WifiStateMachine.java revision 9beea36441ef805a8a3c343553e281f1966c047e
10d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/*
20d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Copyright (C) 2010 The Android Open Source Project
30d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
40d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License");
50d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * you may not use this file except in compliance with the License.
60d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * You may obtain a copy of the License at
70d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
80d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *      http://www.apache.org/licenses/LICENSE-2.0
90d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Unless required by applicable law or agreed to in writing, software
110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS,
120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * See the License for the specific language governing permissions and
140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * limitations under the License.
150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpackage android.net.wifi;
180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * TODO: Add soft AP states as part of WIFI_STATE_XXX
270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Retain WIFI_STATE_ENABLING that indicates driver is loading
280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Add WIFI_STATE_AP_ENABLED to indicate soft AP has started
290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and WIFI_STATE_FAILED for failure
300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Deprecate WIFI_STATE_UNKNOWN
310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Doing this will simplify the logic for sending broadcasts
330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
40090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.AlarmManager;
41090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.PendingIntent;
42ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.net.LinkAddress;
430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo;
440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.DhcpInfo;
450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkUtils;
460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.ConnectivityManager;
470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
4837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltimport android.net.LinkProperties;
49be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriffimport android.net.wifi.NetworkUpdateResult;
500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Binder;
510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Message;
520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.IBinder;
530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.INetworkManagementService;
540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.PowerManager;
550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.SystemProperties;
560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.RemoteException;
570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.ServiceManager;
580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Process;
5903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackbornimport android.os.WorkSource;
600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.provider.Settings;
610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.EventLog;
620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Log;
630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Slog;
640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.backup.IBackupManager;
657440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganeshimport android.bluetooth.BluetoothA2dp;
667440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.bluetooth.BluetoothDevice;
680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.bluetooth.BluetoothHeadset;
697440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganeshimport android.bluetooth.BluetoothProfile;
70090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.content.BroadcastReceiver;
710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Intent;
720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Context;
73090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.content.IntentFilter;
74090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.app.IBatteryStats;
764b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Savilleimport com.android.internal.util.AsyncChannel;
770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalState;
780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalStateMachine;
790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff
810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.ArrayList;
820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.LinkedHashMap;
830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.List;
840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.Map;
850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.concurrent.atomic.AtomicInteger;
860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.regex.Pattern;
870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Track the state of Wifi connectivity. All event handling is done here,
900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and all changes in connectivity state are initiated here.
910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @hide
930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpublic class WifiStateMachine extends HierarchicalStateMachine {
950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String TAG = "WifiStateMachine";
970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String NETWORKTYPE = "WIFI";
980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final boolean DBG = false;
990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* TODO: fetch a configurable interface */
1010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String SOFTAP_IFACE = "wl0.1";
1020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiMonitor mWifiMonitor;
1040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private INetworkManagementService nwService;
1050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ConnectivityManager mCm;
1060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results handling */
1080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private List<ScanResult> mScanResults;
1090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final Pattern scanResultPattern = Pattern.compile("\t+");
1100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULT_CACHE_SIZE = 80;
1110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final LinkedHashMap<String, ScanResult> mScanResultCache;
1120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mInterfaceName;
1140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastSignalLevel = -1;
1160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mLastBssid;
1170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastNetworkId;
1180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mEnableRssiPolling = false;
11919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private int mRssiPollToken = 0;
1200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mReconnectCount = 0;
1210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mIsScanMode = false;
1220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
12419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Interval in milliseconds between polling for RSSI
12519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * and linkspeed information
12619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
12719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
12819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /**
1300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Instance of the bluetooth headset helper. This needs to be created
1310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * early because there is a delay before it actually 'connects', as
1320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * noted by its javadoc. If we check before it is connected, it will be
1330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * in an error state and we will not disable coexistence.
1340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private BluetoothHeadset mBluetoothHeadset;
1360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private BluetoothA2dp mBluetoothA2dp;
1380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private LinkProperties mLinkProperties;
1400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1414f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    // Wakelock held during wifi start/stop and driver load/unload
1424f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    private PowerManager.WakeLock mWakeLock;
1430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private Context mContext;
1450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private DhcpInfo mDhcpInfo;
1470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiInfo mWifiInfo;
1480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkInfo mNetworkInfo;
1490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SupplicantStateTracker mSupplicantStateTracker;
15004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /* Connection to a specific network involves disabling all networks,
15104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * this flag tracks if networks need to be re-enabled */
152e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private boolean mEnableAllNetworks = false;
15304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
154090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private AlarmManager mAlarmManager;
155090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private PendingIntent mScanIntent;
15636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Tracks current frequency mode */
15736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
158090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
1594b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    // Channel for sending replies.
1604b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    private AsyncChannel mReplyChannel = new AsyncChannel();
1614b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
1620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Event log tags (must be in sync with event-log-tags)
1630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
1640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
1650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED  = 50023;
1660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Load the driver */
16819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER                      = 1;
1690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unload the driver */
17019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER                    = 2;
1710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load succeeded */
17219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER_SUCCESS              = 3;
1730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load failed */
17419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER_FAILURE              = 4;
1750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload succeeded */
17619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER_SUCCESS            = 5;
1770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload failed */
17819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER_FAILURE            = 6;
179cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff    /* Set bluetooth headset proxy */
18019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_BLUETOOTH_HEADSET_PROXY      = 7;
181cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff    /* Set bluetooth A2dp proxy */
18219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_BLUETOOTH_A2DP_PROXY         = 8;
1830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the supplicant */
18519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_SUPPLICANT                 = 11;
1860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the supplicant */
18719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_SUPPLICANT                  = 12;
1880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
18919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_DRIVER                     = 13;
1900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
19119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_DRIVER                      = 14;
1920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP succeded */
19319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_IP_CONFIG_SUCCESS                = 15;
1940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP failed */
19519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_IP_CONFIG_FAILURE                = 16;
1960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the soft access point */
19819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_AP                         = 21;
1990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the soft access point */
20019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_AP                          = 22;
2010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant events */
2040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant established */
20519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUP_CONNECTION_EVENT                 = 31;
2060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant lost */
20719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUP_DISCONNECTION_EVENT              = 32;
2080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start completed */
20919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int DRIVER_START_EVENT                   = 33;
2100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stop completed */
21119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int DRIVER_STOP_EVENT                    = 34;
2120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network connection completed */
21319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int NETWORK_CONNECTION_EVENT             = 36;
2140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network disconnection completed */
21519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int NETWORK_DISCONNECTION_EVENT          = 37;
2160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results are available */
21719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SCAN_RESULTS_EVENT                   = 38;
2180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicate state changed */
21919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
2200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Password may be incorrect */
22119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
2220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands */
2240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Is supplicant alive ? */
22519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_PING_SUPPLICANT                  = 51;
2260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Add/update a network configuration */
22719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ADD_OR_UPDATE_NETWORK            = 52;
2280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Delete a network */
22919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REMOVE_NETWORK                   = 53;
2300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable a network. The device will attempt a connection to the given network. */
23119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ENABLE_NETWORK                   = 54;
2320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disable a network. The device does not attempt a connection to the given network. */
23319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_DISABLE_NETWORK                  = 55;
2340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Blacklist network. De-prioritizes the given BSSID for connection. */
23519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_BLACKLIST_NETWORK                = 56;
2360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear the blacklist network list */
23719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_CLEAR_BLACKLIST                  = 57;
2380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Save configuration */
23919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SAVE_CONFIG                      = 58;
2400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands after driver start*/
2420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Initiate a scan */
24319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_SCAN                       = 71;
2440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
24519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_SCAN_MODE                    = 72;
2460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
24719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_SCAN_TYPE                    = 73;
2480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disconnect from a network */
24919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_DISCONNECT                       = 74;
2500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reconnect to a network */
25119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_RECONNECT                        = 75;
2520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reassociate to a network */
25319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REASSOCIATE                      = 76;
2545876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    /* Controls power mode and suspend mode optimizations
2555876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
2565876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * When high perf mode is enabled, power mode is set to
2575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * POWER_MODE_ACTIVE and suspend mode optimizations are disabled
2585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
2595876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * When high perf mode is disabled, power mode is set to
2605876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * POWER_MODE_AUTO and suspend mode optimizations are enabled
2615876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
2625876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Suspend mode optimizations include:
2635876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - packet filtering
2645876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - turn off roaming
2655876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - DTIM wake up settings
2660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
26719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_HIGH_PERF_MODE               = 77;
2680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set bluetooth co-existence
2690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * BLUETOOTH_COEXISTENCE_MODE_ENABLED
2700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * BLUETOOTH_COEXISTENCE_MODE_DISABLED
2710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * BLUETOOTH_COEXISTENCE_MODE_SENSE
2720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
27319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_BLUETOOTH_COEXISTENCE        = 78;
2740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable/disable bluetooth scan mode
2750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * true(1)
2760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * false(0)
2770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
27819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_BLUETOOTH_SCAN_MODE          = 79;
279ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /* Set the country code */
28019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_COUNTRY_CODE                 = 80;
2810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Request connectivity manager wake lock before driver stop */
28219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REQUEST_CM_WAKELOCK              = 81;
2830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enables RSSI poll */
28419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ENABLE_RSSI_POLL                 = 82;
2850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* RSSI poll */
28619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_RSSI_POLL                        = 83;
2870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set up packet filtering */
28819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_PACKET_FILTERING           = 84;
2890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear packet filter */
29019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_PACKET_FILTERING            = 85;
291e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Connect to a specified network (network id
292e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * or WifiConfiguration) This involves increasing
293e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * the priority of the network, enabling the network
294e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * (while disabling others) and issuing a reconnect.
295e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * Note that CMD_RECONNECT just does a reconnect to
296e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an existing network. All the networks get enabled
297e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * upon a successful connection or a failure.
298e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
29919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_CONNECT_NETWORK                  = 86;
300e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Save the specified network. This involves adding
301e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an enabled network (if new) and updating the
302e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * config and issuing a save on supplicant config.
303e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
30419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SAVE_NETWORK                     = 87;
305e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Delete the specified network. This involves
306e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * removing the network and issuing a save on
307e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * supplicant config.
308e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
30919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_FORGET_NETWORK                   = 88;
310f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff    /* Start Wi-Fi protected setup push button configuration */
31119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_WPS_PBC                    = 89;
3121406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    /* Start Wi-Fi protected setup pin method configuration with pin obtained from AP */
31319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_WPS_PIN_FROM_AP            = 90;
3141406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    /* Start Wi-Fi protected setup pin method configuration with pin obtained from device */
31519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_WPS_PIN_FROM_DEVICE        = 91;
31636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Set the frequency band */
31719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_FREQUENCY_BAND               = 92;
318ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
31919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /* Commands from the SupplicantStateTracker */
32019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /* Indicates whether a wifi network is available for connection */
32119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_NETWORK_AVAILABLE             = 111;
3220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CONNECT_MODE   = 1;
3240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ONLY_MODE = 2;
3250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ACTIVE = 1;
3270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_PASSIVE = 2;
3280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3291406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int SUCCESS = 1;
3301406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int FAILURE = -1;
3311406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
3320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * The maximum number of times we will retry a connection to an access point
3340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * for which we have failed in acquiring an IP address from DHCP. A value of
3350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * N means that we will make N+1 connection attempts in all.
3360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * <p>
3370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
3380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * value if a Settings value is not present.
3390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
3410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3425876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private static final int POWER_MODE_ACTIVE = 1;
3435876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private static final int POWER_MODE_AUTO = 0;
3440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
345090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    /**
346090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
347090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     * Settings.Secure value is not present.
348090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     */
349090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
350090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
3510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Default parent state */
3520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDefaultState = new DefaultState();
3530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Temporary initial state */
3540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mInitialState = new InitialState();
3550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unloading the driver */
3560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadingState = new DriverUnloadingState();
3570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Loading the driver */
3580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadedState = new DriverUnloadedState();
3590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver load/unload failed */
3600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverFailedState = new DriverFailedState();
3610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loading */
3620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadingState = new DriverLoadingState();
3630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded */
3640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadedState = new DriverLoadedState();
3650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded, waiting for supplicant to start */
3660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mWaitForSupState = new WaitForSupState();
3670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded and supplicant ready */
3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverSupReadyState = new DriverSupReadyState();
3700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start issued, waiting for completed event */
3710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartingState = new DriverStartingState();
3720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver started */
3730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartedState = new DriverStartedState();
3740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopping */
3750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppingState = new DriverStoppingState();
3760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopped */
3770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppedState = new DriverStoppedState();
3780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan for networks, no connection will be established */
3790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mScanModeState = new ScanModeState();
3800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connecting to an access point */
3810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectModeState = new ConnectModeState();
3820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Fetching IP after network connection (assoc+auth complete) */
3830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectingState = new ConnectingState();
3840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connected with IP addr */
3850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectedState = new ConnectedState();
3860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* disconnect issued, waiting for network disconnect confirmation */
3870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectingState = new DisconnectingState();
3880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network is not connected, supplicant assoc+auth is not complete */
3890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectedState = new DisconnectedState();
3900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Soft Ap is running */
3920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mSoftApStartedState = new SoftApStartedState();
3930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
3970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_DISABLING},
3980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLED},
3990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLING},
4000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
4010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
4020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
4030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
4040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
4060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
4070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
4080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
4090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
4100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
4110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
4120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
4130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
4140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastEnableUid = new AtomicInteger(Process.myUid());
4160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastApEnableUid = new AtomicInteger(Process.myUid());
4170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
418090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final int SCAN_REQUEST = 0;
419090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final String ACTION_START_SCAN =
420090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        "com.android.server.WifiManager.action.START_SCAN";
421090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
42203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
42303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether WIFI is running.
42403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
42503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mIsRunning = false;
4265ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
42703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
42803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether we last told the battery stats we had started.
42903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
43003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mReportedRunning = false;
43103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
43203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
43303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Most recently set source of starting WIFI.
43403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
43503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mRunningWifiUids = new WorkSource();
43603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
43703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
43803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * The last reported UIDs that were responsible for starting WIFI.
43903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
44003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mLastRunningWifiUids = new WorkSource();
44103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
4420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final IBatteryStats mBatteryStats;
4430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public WifiStateMachine(Context context) {
4450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        super(TAG);
4460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext = context;
4480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
4500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
4510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
4530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        nwService = INetworkManagementService.Stub.asInterface(b);
4540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiMonitor = new WifiMonitor(this);
4560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mDhcpInfo = new DhcpInfo();
4570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo = new WifiInfo();
4580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
45919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
4600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
46137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties = new LinkProperties();
4627440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
4637440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        if (adapter != null) {
4647440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh            adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
4657440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                                    BluetoothProfile.A2DP);
4667440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh            adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
4677440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                                    BluetoothProfile.HEADSET);
4687440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        }
4690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo.setIsAvailable(false);
47137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
4720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid = null;
4730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
4740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastSignalLevel = -1;
4750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
476090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
477090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        Intent scanIntent = new Intent(ACTION_START_SCAN, null);
478090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
479090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
480090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mContext.registerReceiver(
481090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new BroadcastReceiver() {
482090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    @Override
483090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    public void onReceive(Context context, Intent intent) {
484090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        startScan(false);
485090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    }
486090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                },
487090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new IntentFilter(ACTION_START_SCAN));
488090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
4890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResultCache = new LinkedHashMap<String, ScanResult>(
4900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SCAN_RESULT_CACHE_SIZE, 0.75f, true) {
4910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /*
4920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * Limit the cache size by SCAN_RESULT_CACHE_SIZE
4930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * elements
4940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 */
4950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                @Override
4960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public boolean removeEldestEntry(Map.Entry eldest) {
4970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return SCAN_RESULT_CACHE_SIZE < this.size();
4980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
4990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        };
5000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
5024f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
5030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
5050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
5060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
5070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
5080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
5090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
5100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
5110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mWaitForSupState, mDriverLoadedState);
5120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverSupReadyState, mDefaultState);
5130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStartingState, mDriverSupReadyState);
5140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStartedState, mDriverSupReadyState);
5150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectingState, mConnectModeState);
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectedState, mConnectModeState);
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
5210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStoppingState, mDriverSupReadyState);
5220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStoppedState, mDriverSupReadyState);
5230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
5240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
5260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
5280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
5300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
5310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
5340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
5350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
5360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5401406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncPingSupplicant(AsyncChannel channel) {
5411406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
5421406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
5431406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
5441406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
5450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
550e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
551e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
552e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
5530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
5590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
5600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
5630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
5640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
5660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
5750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
5790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
5800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
5820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
5840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
590d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiState() {
5910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
5920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
597d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiStateByName() {
5980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
5990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
6000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
6010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
6020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
6030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
6040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
6050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
6060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
6070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
6080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
6090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
617d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiApState() {
6180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
6190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
624d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiApStateByName() {
6250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
6260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
6270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
6280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
6290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
6310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
6320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
6330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
6340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
6350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
6360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
6430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
6440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
646d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public WifiInfo syncRequestConnectionInfo() {
6470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
6480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
650d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public DhcpInfo syncGetDhcpInfo() {
65131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        synchronized (mDhcpInfo) {
65231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            return new DhcpInfo(mDhcpInfo);
65331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
6540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setDriverStart(boolean enable) {
6604f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        if (enable) {
6614f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_START_DRIVER);
6624f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        } else {
6634f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_STOP_DRIVER);
6644f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        }
6650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
6710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
6720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
6730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
6750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
6820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
692d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<ScanResult> syncGetScanResultsList() {
6930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mScanResults;
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
6980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
699e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
700e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
7050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
706e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
707e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
7080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
7120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
713e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
714e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
7150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
7190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7221406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
7231406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
7241406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        int result = resultMsg.arg1;
7251406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7261406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
729d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<WifiConfiguration> syncGetConfiguredNetworks() {
73004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return WifiConfigStore.getConfiguredNetworks();
7310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
7350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
7370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7384b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
7394b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
7401406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7414b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        resultMsg.recycle();
7424b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        return result;
7434b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    }
7444b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
7454b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    /**
7460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
7470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
7500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7521406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
7531406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
7541406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                disableOthers ? 1 : 0);
7551406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7561406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7571406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
7620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7661406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
7671406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId);
7681406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7691406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7701406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
7760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
7800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
7810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
7850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
7880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
7890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
791e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(int netId) {
792e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, netId, 0));
793e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
794e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
795e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(WifiConfiguration wifiConfig) {
796a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        /* arg1 is used to indicate netId, force a netId value of -1 when
797a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * we are passing a configuration since the default value of
798a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * 0 is a valid netId
799a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         */
800a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, -1, 0, wifiConfig));
801e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
802e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
803e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void saveNetwork(WifiConfiguration wifiConfig) {
804e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_SAVE_NETWORK, wifiConfig));
805e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
806e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
807e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void forgetNetwork(int netId) {
808e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
809e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
810e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
8115ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    public void startWpsPbc(String bssid) {
812f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        sendMessage(obtainMessage(CMD_START_WPS_PBC, bssid));
813f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff    }
814f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff
815f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
8161406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        sendMessage(obtainMessage(CMD_START_WPS_PIN_FROM_AP, apPin, 0, bssid));
8175ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
8185ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
819f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff    public int syncStartWpsWithPinFromDevice(AsyncChannel channel, String bssid) {
8201406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN_FROM_DEVICE, bssid);
821f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        int result = resultMsg.arg1;
822f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        resultMsg.recycle();
823f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        return result;
8245ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
8255ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
8260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
8270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
8280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Start packet filtering
8320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void startPacketFiltering() {
8340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_START_PACKET_FILTERING);
8350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Stop packet filtering
8390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void stopPacketFiltering() {
8410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_STOP_PACKET_FILTERING);
8420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8455876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Set high performance mode of operation.
8465876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Enabling would set active power mode and disable suspend optimizations;
8475876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * disabling would set auto power mode and enable suspend optimizations
8485876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * @param enable true if enable, false otherwise
8490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8505876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    public void setHighPerfModeEnabled(boolean enable) {
8515876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
8520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
855ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code
856ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param countryCode following ISO 3166 format
857ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
8580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
859ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    public void setCountryCode(String countryCode, boolean persist) {
860ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (persist) {
861ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            Settings.Secure.putString(mContext.getContentResolver(),
862ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Settings.Secure.WIFI_COUNTRY_CODE,
863ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    countryCode);
8640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
865ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_COUNTRY_CODE, countryCode));
8660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
86936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the operational frequency band
87036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param band
87136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
87236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
87336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public void setFrequencyBand(int band, boolean persist) {
87436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        if (persist) {
87536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            Settings.Secure.putInt(mContext.getContentResolver(),
87636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Settings.Secure.WIFI_FREQUENCY_BAND,
87736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    band);
87836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        }
87936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_FREQUENCY_BAND, band, 0));
88036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
88136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
88236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
88336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Returns the operational frequency band
88436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
88536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public int getFrequencyBand() {
88636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        return mFrequencyBand.get();
88736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
88836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
88936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
8900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Set bluetooth coex mode:
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param mode
8930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  BLUETOOTH_COEXISTENCE_MODE_ENABLED
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  BLUETOOTH_COEXISTENCE_MODE_DISABLED
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  BLUETOOTH_COEXISTENCE_MODE_SENSE
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setBluetoothCoexistenceMode(int mode) {
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_BLUETOOTH_COEXISTENCE, mode, 0));
8990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
9030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * some of the low-level scan parameters used by the driver are changed to
9040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * reduce interference with A2DP streaming.
9050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param isBluetoothPlaying whether to enable or disable this mode
9070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setBluetoothScanMode(boolean isBluetoothPlaying) {
9090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_BLUETOOTH_SCAN_MODE, isBluetoothPlaying ? 1 : 0, 0));
9100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
9140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
9160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
9180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9191406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncSaveConfig(AsyncChannel channel) {
9201406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
9211406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9221406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9231406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9279beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * Request a wakelock with connectivity service to
9289beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * keep the device awake until we hand-off from wifi
9299beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * to an alternate network
9300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void requestCmWakeLock() {
9320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_REQUEST_CM_WAKELOCK);
9330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
93503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    public void updateBatteryWorkSource(WorkSource newSource) {
93603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        synchronized (mRunningWifiUids) {
93703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            try {
93803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (newSource != null) {
93903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    mRunningWifiUids.set(newSource);
94003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
94103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (mIsRunning) {
94203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
94303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // If the work source has changed since last time, need
94403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // to remove old work from battery stats.
94503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
94603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
94703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                                    mRunningWifiUids);
94803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mLastRunningWifiUids.set(mRunningWifiUids);
94903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        }
95003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    } else {
95103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Now being started, report it.
95203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
95303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.set(mRunningWifiUids);
95403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = true;
95503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
95603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                } else {
95703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
95803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Last reported we were running, time to stop.
95903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
96003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.clear();
96103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = false;
96203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
96303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
9644f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                mWakeLock.setWorkSource(newSource);
96503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            } catch (RemoteException ignore) {
96603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            }
96703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        }
96803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    }
96903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
970bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    @Override
971bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    public String toString() {
972bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        StringBuffer sb = new StringBuffer();
973bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        String LS = System.getProperty("line.separator");
974bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
97537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
976bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
977bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mDhcpInfo ").append(mDhcpInfo).append(LS);
978bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
979bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
980bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastBssid ").append(mLastBssid).append(LS);
981bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
982bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mEnableAllNetworks ").append(mEnableAllNetworks).append(LS);
983bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
984bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
985bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("Supplicant status").append(LS)
986bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff                .append(WifiNative.statusCommand()).append(LS).append(LS);
98704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
98804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        sb.append(WifiConfigStore.dump());
989bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        return sb.toString();
990bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    }
991bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff
9920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
9930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
9940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
9950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
996ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /**
997ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code from the system setting value, if any.
998ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     */
999ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    private void setCountryCode() {
1000ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        String countryCode = Settings.Secure.getString(mContext.getContentResolver(),
1001ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                Settings.Secure.WIFI_COUNTRY_CODE);
1002ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (countryCode != null && !countryCode.isEmpty()) {
1003ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode(countryCode, false);
1004ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        } else {
1005ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            //use driver default
1006ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        }
1007ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    }
1008ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
100936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
101036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the frequency band from the system setting value, if any.
101136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
101236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private void setFrequencyBand() {
101336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        int band = Settings.Secure.getInt(mContext.getContentResolver(),
101436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                Settings.Secure.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
101536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        setFrequencyBand(band, false);
101636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
101736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
10180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
10190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
10200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
102303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
102503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Failed to note battery stats in wifi");
10290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
10320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1033d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiState: " + syncGetWifiStateByName());
10340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
10360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
10380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
10390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
10430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
10440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
104703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
104903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.d(TAG, "Failed to note battery stats in wifi");
10530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
10560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1058d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiApState: " + syncGetWifiApStateByName());
10590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
10610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
10630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
10640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Parse the scan result line passed to us by wpa_supplicant (helper).
10690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param line the line to parse
10700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return the {@link ScanResult} object
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ScanResult parseScanResult(String line) {
10730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        ScanResult scanResult = null;
10740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (line != null) {
10750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
10760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Cache implementation (LinkedHashMap) is not synchronized, thus,
10770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * must synchronized here!
10780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
10790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized (mScanResultCache) {
10800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String[] result = scanResultPattern.split(line);
10810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (3 <= result.length && result.length <= 5) {
10820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String bssid = result[0];
10830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid | frequency | level | flags | ssid
10840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int frequency;
10850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int level;
10860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
10870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = Integer.parseInt(result[1]);
10880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = Integer.parseInt(result[2]);
10890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
10900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
10910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
10920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
10930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch (NumberFormatException e) {
10940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = 0;
10950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = 0;
10960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
10970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
10990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * The formatting of the results returned by
11000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * wpa_supplicant is intended to make the fields
11010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * line up nicely when printed,
11020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * not to make them easy to parse. So we have to
11030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * apply some heuristics to figure out which field
11040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * is the SSID and which field is the flags.
11050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
11060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String ssid;
11070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String flags;
11080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (result.length == 4) {
11090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (result[3].charAt(0) == '[') {
11100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = result[3];
11110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = "";
11120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
11130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = "";
11140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = result[3];
11150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else if (result.length == 5) {
11170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = result[3];
11180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = result[4];
11190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Here, we must have 3 fields: no flags and ssid
11210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // set
11220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = "";
11230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = "";
11240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid + ssid is the hash key
11270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String key = bssid + ssid;
11280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    scanResult = mScanResultCache.get(key);
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.level = level;
11310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.SSID = ssid;
11320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.capabilities = flags;
11330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.frequency = frequency;
11340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Do not add scan results that have no SSID set
11360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (0 < ssid.trim().length()) {
11370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
11380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
11390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    ssid, bssid, flags, level, frequency);
11400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
11410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
11440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.w(TAG, "Misformatted scan result text with " +
11450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          result.length + " fields: " + line);
11460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return scanResult;
11510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
11540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * scanResults input format
11550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ee       2427    166     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net1
11560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ff       2412    165     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net2
11570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setScanResults(String scanResults) {
11590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (scanResults == null) {
11600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<ScanResult> scanList = new ArrayList<ScanResult>();
11640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int lineCount = 0;
11660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int scanResultsLen = scanResults.length();
11680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Parse the result string, keeping in mind that the last line does
11690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // not end with a newline.
11700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
11710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
11720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                ++lineCount;
11730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineCount == 1) {
11750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lineBeg = lineEnd + 1;
11760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    continue;
11770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineEnd > lineBeg) {
11790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String line = scanResults.substring(lineBeg, lineEnd);
11800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ScanResult scanResult = parseScanResult(line);
11810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanList.add(scanResult);
11830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
1184090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        //TODO: hidden network handling
11850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                lineBeg = lineEnd + 1;
11880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResults = scanList;
11920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1194cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    private String fetchSSID() {
1195cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String status = WifiNative.statusCommand();
1196cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        if (status == null) {
1197cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            return null;
1198cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1199cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        // extract ssid from a series of "name=value"
1200cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String[] lines = status.split("\n");
1201cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        for (String line : lines) {
1202cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String[] prop = line.split(" *= *");
1203cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (prop.length < 2) continue;
1204cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String name = prop[0];
1205cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String value = prop[1];
1206cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (name.equalsIgnoreCase("ssid")) return value;
1207cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1208cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        return null;
1209cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    }
1210cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff
121119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /*
121219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Fetch RSSI and linkspeed on current connection
121319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
121419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private void fetchRssiAndLinkSpeedNative() {
121519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newRssi = WifiNative.getRssiCommand();
121619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
121719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /* some implementations avoid negative values by adding 256
121819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * so we need to adjust for that here.
121919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
122019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newRssi > 0) newRssi -= 256;
122119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(newRssi);
122219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /*
122319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * Rather then sending the raw RSSI out every time it
122419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes, we precalculate the signal level that would
122519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * be displayed in the status bar, and only send the
122619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcast if that much more coarse-grained number
122719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes. This cuts down greatly on the number of
122819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcasts, at the cost of not mWifiInforming others
122919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * interested in RSSI of all the changes in signal
123019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * level.
123119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
123219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // TODO: The second arg to the call below needs to be a symbol somewhere, but
123319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // it's actually the size of an array of icons that's private
123419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // to StatusBar Policy.
123519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
123619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
123719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendRssiChangeBroadcast(newRssi);
123819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
123919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mLastSignalLevel = newSignalLevel;
124019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        } else {
124119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(-200);
124219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
124319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newLinkSpeed = WifiNative.getLinkSpeedCommand();
124419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newLinkSpeed != -1) {
124519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
124619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
124719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
124819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12495876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private void setHighPerfModeEnabledNative(boolean enable) {
12505876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
12515876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            Log.e(TAG, "set suspend optimizations failed!");
12525876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12535876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if (enable) {
12545876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
12555876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode active failed!");
12565876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        } else {
12585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
12595876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode auto failed!");
12605876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12615876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12625876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    }
12635876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
126437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private void configureLinkProperties() {
126596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
126696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
126796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
126896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            // TODO - fix this for v6
126996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            synchronized (mDhcpInfo) {
127096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addLinkAddress(new LinkAddress(
127196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress),
127296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        NetworkUtils.intToInetAddress(mDhcpInfo.netmask)));
127396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
127496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
127596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
127696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
127796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
1278128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
127996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        mLinkProperties.setInterfaceName(mInterfaceName);
128096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        Log.d(TAG, "netId=" + mLastNetworkId  + " Link configured: " + mLinkProperties.toString());
12810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
12840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return Settings.Secure.getInt(mContext.getContentResolver(),
12850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
12860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
12870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1290cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff     * Whether to disable coexistence mode while obtaining IP address. We
1291cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff     * disable coexistence if the headset indicates that there are no
1292cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff     * connected devices. If we have not got an indication of the service
1293cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff     * connection yet, we go ahead with disabling coexistence mode.
12940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
12950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return Whether to disable coexistence mode.
12960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1297cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff    private boolean shouldDisableCoexistenceMode() {
1298cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff        if (mBluetoothHeadset == null) return true;
12995a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh        List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
1300cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff        return (devices.size() != 0 ? false : true);
13010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1303cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff    private void checkIsBluetoothPlaying() {
13040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        boolean isBluetoothPlaying = false;
13057440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        if (mBluetoothA2dp != null) {
13065a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh            List<BluetoothDevice> connected = mBluetoothA2dp.getConnectedDevices();
13070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13087440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh            for (BluetoothDevice device : connected) {
13097440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                if (mBluetoothA2dp.isA2dpPlaying(device)) {
13107440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                    isBluetoothPlaying = true;
13117440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                    break;
13127440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                }
13130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setBluetoothScanMode(isBluetoothPlaying);
13160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13187440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
13197440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        new BluetoothProfile.ServiceListener() {
13207440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        public void onServiceConnected(int profile, BluetoothProfile proxy) {
13217440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                if (profile == BluetoothProfile.HEADSET) {
1322cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    sendMessage(CMD_SET_BLUETOOTH_HEADSET_PROXY, proxy);
13237440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                } else if (profile == BluetoothProfile.A2DP) {
1324cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    sendMessage(CMD_SET_BLUETOOTH_A2DP_PROXY, proxy);
13257440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                }
13267440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        }
13277440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh
13287440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        public void onServiceDisconnected(int profile) {
13297440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                if (profile == BluetoothProfile.HEADSET) {
1330cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    sendMessage(CMD_SET_BLUETOOTH_HEADSET_PROXY, null);
13317440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                } else if (profile == BluetoothProfile.A2DP) {
1332cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    sendMessage(CMD_SET_BLUETOOTH_A2DP_PROXY, null);
13337440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh                }
13347440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh        }
13357440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh    };
13367440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh
13370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
1338be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
1339be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1340be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        mContext.sendBroadcast(intent);
13410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
13440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
1345be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
13470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
13510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
13520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
13530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
135537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
13560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
13570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
13580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
13590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1361be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void sendLinkConfigurationChangedBroadcast() {
1362be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
1363be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
136437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
13650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
13690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
1370be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
13720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param state the new @{code DetailedState}
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1379be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "setDetailed state, old ="
13810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                + mNetworkInfo.getDetailedState() + " and new state=" + state);
13820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
13830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkInfo.setDetailedState(state, null, null);
13840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1387be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private DetailedState getNetworkDetailedState() {
1388be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return mNetworkInfo.getDetailedState();
1389be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    }
1390be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
13940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
13960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "Reset connections and stopping DHCP");
13970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
13990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Reset connections & stop DHCP
14000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
14010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.resetConnections(mInterfaceName);
14020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!NetworkUtils.stopDhcp(mInterfaceName)) {
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Could not stop DHCP");
14050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Disable interface */
14080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.disableInterface(mInterfaceName);
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* send event to CM & network change broadcast */
1411be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        setNetworkDetailedState(DetailedState.DISCONNECTED);
14120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
14150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setIpAddress(0);
14160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
14170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
14180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setNetworkId(-1);
14190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
142137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
14220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
14240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
14250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
14300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Notifications from WifiMonitor
14310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
14320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * A structure for supplying information about a supplicant state
14350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * change in the STATE_CHANGE event message that comes from the
14360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * WifiMonitor
14370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * thread.
14380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
143919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static class StateChangeResult {
14400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        StateChangeResult(int networkId, String BSSID, Object state) {
14410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.state = state;
14420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.BSSID = BSSID;
14430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.networkId = networkId;
14440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int networkId;
14460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String BSSID;
14470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Object state;
14480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a user-entered password key
14520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * may be incorrect (i.e., caused authentication to fail).
14530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyPasswordKeyMayBeIncorrect() {
14550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
14560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a connection to the supplicant
14600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * daemon has been established.
14610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantConnection() {
14630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_CONNECTION_EVENT);
14640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
146768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * Send the tracker a notification that connection to the supplicant
146868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * daemon is lost
14690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantLost() {
14710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_DISCONNECTION_EVENT);
14720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of Wifi connectivity
14760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new network state
14790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param BSSID when the new state is {@link DetailedState#CONNECTED
14800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * NetworkInfo.DetailedState.CONNECTED},
14810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * this is the MAC address of the access point. Otherwise, it
14820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * is {@code null}.
14830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyNetworkStateChange(DetailedState newState, String BSSID, int networkId) {
14850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newState == NetworkInfo.DetailedState.CONNECTED) {
14860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT,
14870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    new StateChangeResult(networkId, BSSID, newState)));
14880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
14890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT,
14900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    new StateChangeResult(networkId, BSSID, newState)));
14910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of the supplicant
14960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new {@code SupplicantState}
14990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
15000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantStateChange(int networkId, String BSSID, SupplicantState newState) {
15010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
15020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                new StateChangeResult(networkId, BSSID, newState)));
15030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
15060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a scan has completed, and results
15070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * are available.
15080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
15090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyScanResultsAvailable() {
15100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
15110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Switch scan mode over to passive.
15120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Turning off scan-only mode happens only in "Connect" mode
15130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
15140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setScanType(false);
15150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SCAN_RESULTS_EVENT);
15160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStarted() {
15190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_START_EVENT);
15200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStopped() {
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_STOP_EVENT);
15240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverHung() {
15270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(false);
15280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(true);
15290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
153119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    void setNetworkAvailable(boolean available) {
15323c661bde458b7c69f494673c7d6728a7a871b586Robert Greenwalt        sendMessage(obtainMessage(CMD_SET_NETWORK_AVAILABLE, available ? 1 : 0, 0));
153319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
15340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
15360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
15370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
15380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DefaultState extends HierarchicalState {
15400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
15420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
15430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
1544cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                case CMD_SET_BLUETOOTH_HEADSET_PROXY:
1545cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    mBluetoothHeadset = (BluetoothHeadset) message.obj;
1546cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
1547cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                case CMD_SET_BLUETOOTH_A2DP_PROXY:
1548cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    mBluetoothA2dp = (BluetoothA2dp) message.obj;
1549cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
15500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
15510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
15520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
15530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
15540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
15554b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                case CMD_REMOVE_NETWORK:
15561406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_SAVE_CONFIG:
15571406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_START_WPS_PIN_FROM_DEVICE:
15581406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, FAILURE);
15594b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                    break;
15600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
15610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
156219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
156319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_SET_NETWORK_AVAILABLE:
156419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mNetworkInfo.setIsAvailable(message.arg1 == 1);
15650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
15660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
15670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
15680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
15690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
15700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
15710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
15720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
15730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
15740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
1575e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
1576e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
1577e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
1578e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
15790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
15800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
15810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
15820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
15830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
15840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
15850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
15860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
15870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
15880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
15890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
15900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
15910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
15925876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
15930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
15940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
1595ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
159636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
15970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
1598e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
1599e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1600e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
1601f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                case CMD_START_WPS_PBC:
16021406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_START_WPS_PIN_FROM_AP:
160319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
16040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
16060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG, "Error! unhandled message" + message);
16070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
16100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class InitialState extends HierarchicalState {
16140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
16160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
16190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
16200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (WifiNative.isDriverLoaded()) {
16240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadingState extends HierarchicalState {
16330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
16390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
16400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
16410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
16420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
16430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
16440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
16454f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
16480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
16490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
16500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
16510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
16520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
16530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
16540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.loadDriver()) {
16570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver load successful");
16580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
16590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
16600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to load driver!");
16610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
16620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
16630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
16640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
16660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
16690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
16700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16714f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
16720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
16740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
16800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
16810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
16820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
16840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
16850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
16870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
16880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
16890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
16900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
16910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
16920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
16930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
16940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
16950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
16965876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
16970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
16980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
1699ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
170036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
17010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
17020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
17030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
17040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadedState extends HierarchicalState {
17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
17170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
17210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
17230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
17240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
17250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
17270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.startSupplicant()) {
17280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Supplicant start successful");
17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
17300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        setWifiState(WIFI_STATE_ENABLED);
17310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mWaitForSupState);
17320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
17330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to start supplicant!");
17340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
17350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
17380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
17390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.startAccessPoint((WifiConfiguration) message.obj,
17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
17410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
17420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
17430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in startAccessPoint()");
17440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
17450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
17460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Soft AP start successful");
17480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
17490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mSoftApStartedState);
17500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadingState extends HierarchicalState {
17600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
17630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
17660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
17670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
17680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
17690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17704f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
17710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.unloadDriver()) {
17720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver unload successful");
17730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
17740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
17790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
17830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
17860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to unload driver!");
17870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
17880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
17930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
18004f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
18020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
18030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
18090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
18100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
18110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
18130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
18140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
18160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
18170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
18180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
18190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
18200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
18210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
18220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
18230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
18240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
18255876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
18260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
18270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
1828ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
182936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
18300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
18310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
18320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
18330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
18350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
18360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
18380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
18390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadedState extends HierarchicalState {
18430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
18520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
18530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadingState);
18540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
18560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
18570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
18590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
18600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverFailedState extends HierarchicalState {
18640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, getName() + "\n");
18670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
18730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class WaitForSupState extends HierarchicalState {
18780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
18870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
18880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Supplicant connection established");
18890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.resetSupplicantState();
18900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
18910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
18920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = -1;
18930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
18940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
18960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
189704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.initialize(mContext);
18989e6222f4c126252c9950d072ab67d8b849d17643Irfan Sheriff
18990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //TODO: initialize and fix multicast filtering
19000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //mWM.initializeMulticastFiltering();
19010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    checkIsBluetoothPlaying();
19030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
19054f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartedState);
19060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
190768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case SUP_DISCONNECTION_EVENT:
190868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    Log.e(TAG, "Failed to setup control channel, restart supplicant");
19090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopSupplicant();
19100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
191168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    sendMessageAtFrontOfQueue(CMD_START_SUPPLICANT);
19120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
191368825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_LOAD_DRIVER:
191468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_UNLOAD_DRIVER:
191568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_START_SUPPLICANT:
191668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_SUPPLICANT:
19170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
191868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_AP:
19190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
19200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
19210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
19220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
19235876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
19240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
19250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
1926ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
192736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
19280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
19290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
19300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
19310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
19330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
19340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
19370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverSupReadyState extends HierarchicalState {
19410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
19430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
19440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
19450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
19460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
19470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
19500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
1951e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
19520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
19530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
195468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Stop supplicant received");
195668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    WifiNative.closeSupplicantConnection();
19570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopSupplicant();
195868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    handleNetworkDisconnect();
195968825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
196068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    mSupplicantStateTracker.resetSupplicantState();
196168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    transitionTo(mDriverLoadedState);
196268825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    break;
19630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:  /* Supplicant died */
19640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
196568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    Log.e(TAG, "Supplicant died, restarting");
19660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.closeSupplicantConnection();
19670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
19680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.resetSupplicantState();
19700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
197168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    sendMessageAtFrontOfQueue(CMD_START_SUPPLICANT); /* restart */
19720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
19740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setScanResults(WifiNative.scanResultsCommand());
19750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendScanResultsAvailableBroadcast();
19760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
19781406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    boolean ok = WifiNative.pingCommand();
19791406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
19820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19831406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    config = (WifiConfiguration) message.obj;
19841406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
19851406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                            WifiConfigStore.addOrUpdateNetwork(config));
19860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
19880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19891406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.removeNetwork(message.arg1);
19901406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
19930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19941406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
19951406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
19980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19991406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.disableNetwork(message.arg1);
20001406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
20010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
20030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.addToBlacklistCommand((String)message.obj);
20050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
20070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.clearBlacklistCommand();
20080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
20101406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.saveConfig();
20111406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
20121406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
20130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
20140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
20150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
20160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
20170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
20180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
20190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
20200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
20210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
20220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
20230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
20250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
20260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
20270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
20290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
20310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
20320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2033e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
2034e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
203504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.saveNetwork(config);
2036e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
2037e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
203804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.forgetNetwork(message.arg1);
2039e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
20400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartingState extends HierarchicalState {
20480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
20550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
20560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
20570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
20580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStartedState);
20590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
20610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
20620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
20630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
20640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
20650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
20660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
20670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
20685876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
20690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
20700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
2071ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
207236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
20730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
20740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
20750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
20760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
20770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
20780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2079e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
20800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartedState extends HierarchicalState {
20900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
209503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = true;
209603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
20970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2098ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            /* set country code */
2099ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode();
210036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            /* set frequency band of operation */
210136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            setFrequencyBand();
21020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
21040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
21050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.disconnectCommand();
21060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
21070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
21080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
21090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.reconnectCommand();
2110090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                transitionTo(mDisconnectedState);
21110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ACTIVE) {
21190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(true);
21200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(false);
21220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
212419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
212519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
212619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
21275876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
21285876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    setHighPerfModeEnabledNative(message.arg1 == 1);
21290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
21310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(message.arg1);
21320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
21340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceScanModeCommand(message.arg1 == 1);
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2136ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
2137ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    String country = (String) message.obj;
2138ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Log.d(TAG, "set country code " + country);
2139ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) {
2140ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                        Log.e(TAG, "Failed to set country code " + country);
2141ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    }
21420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
214336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
214436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    int band =  message.arg1;
214536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Log.d(TAG, "set frequency band " + band);
214636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    if (WifiNative.setBandCommand(band)) {
214736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        mFrequencyBand.set(band);
214836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    } else {
214936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        Log.e(TAG, "Failed to set frequency band " + band);
215036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    }
215136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    break;
21520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21534f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
21540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopDriverCommand();
21550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppingState);
21564f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
21570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
21590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.startPacketFiltering();
21600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
21620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopPacketFiltering();
21630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
21680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
21720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
217303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = false;
217403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
2175f99819e47cbef2ec066a21b426c7e6fe95e3de48Irfan Sheriff            mScanResults = null;
21760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppingState extends HierarchicalState {
21800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
21830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
21900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppedState);
21910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
21930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
21940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21965876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
21970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
21980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
2199ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
220036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
22010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
22040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2207e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
22080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppedState extends HierarchicalState {
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22264f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            switch (message.what) {
22274f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                case CMD_START_DRIVER:
22284f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
22294f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    WifiNative.startDriverCommand();
22304f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartingState);
22314f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
22324f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    break;
22334f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                default:
22344f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    return NOT_HANDLED;
22354f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            }
22364f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22374f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            return HANDLED;
22380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ScanModeState extends HierarchicalState {
22420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
22530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
22540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
22550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
22560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
22570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.reconnectCommand();
22580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
22600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
22650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
22670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
22680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectModeState extends HierarchicalState {
22790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
22880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
229019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
22910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
22930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
229419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    SupplicantState state = (SupplicantState) stateChangeResult.state;
229519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // Supplicant state change
229619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [31-13] Reserved for future use
229719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [8 - 0] Supplicant state (as defined in SupplicantState.java)
229819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // 50023 supplicant_state_changed (custom|1|5)
229919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
230019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setSupplicantState(state);
230119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
230219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (state == SupplicantState.ASSOCIATING) {
230319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        /* BSSID is valid only in ASSOCIATING state */
230419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mWifiInfo.setBSSID(stateChangeResult.BSSID);
230519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
230619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
23070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Message newMsg = obtainMessage();
23080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    newMsg.copyFrom(message);
23090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.sendMessage(newMsg);
23100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
23120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2313e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
23140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2316e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reconnectCommand();
23170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
2319e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reassociateCommand();
23200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2321e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2322e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
2323e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
232404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
232504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* We connect to a specific network by issuing a select
232604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * to the WifiConfigStore. This enables the network,
232704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * while disabling all other networks in the supplicant.
232804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * Disabling a connected network will cause a disconnection
232904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * from the network. A reconnectCommand() will then initiate
233004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * a connection to the enabled network.
233104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     */
2332e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
233304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(config);
233404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    } else {
233504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(netId);
2336e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2337e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
2338a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Save a flag to indicate that we need to enable all
2339a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                     * networks after supplicant indicates a network
2340a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                     * state change event
2341a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                     */
2342e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    mEnableAllNetworks = true;
234304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
2344a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    WifiNative.reconnectCommand();
234504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
234604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* Expect a disconnection from the old connection */
2347a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    transitionTo(mDisconnectingState);
2348e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
2349f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                case CMD_START_WPS_PBC:
23505ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                    String bssid = (String) message.obj;
2351f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    /* WPS push button configuration */
2352f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    boolean success = WifiConfigStore.startWpsPbc(bssid);
2353f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff
23545ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                    /* During WPS setup, all other networks are disabled. After
23555ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     * a successful connect a new config is created in the supplicant.
23565ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     *
23575ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     * We need to enable all networks after a successful connection
23585ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     * or when supplicant goes inactive due to failure. Enabling all
23595ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     * networks after a disconnect is observed as done with connectNetwork
23605ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     * does not lead to a successful WPS setup.
23615ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     *
23625ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     * Upon success, the configuration list needs to be reloaded
23635ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                     */
23645ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                    if (success) {
236519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mSupplicantStateTracker.sendMessage(message.what);
23665ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                        /* Expect a disconnection from the old connection */
23675ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                        transitionTo(mDisconnectingState);
23685ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                    }
23695ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                    break;
23701406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_START_WPS_PIN_FROM_AP:
2371f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    bssid = (String) message.obj;
2372f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    int apPin = message.arg1;
23731406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
23741406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    /* WPS pin from access point */
23751406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
23761406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
23771406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    if (success) {
237819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mSupplicantStateTracker.sendMessage(message.what);
23791406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                        /* Expect a disconnection from the old connection */
23801406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                        transitionTo(mDisconnectingState);
2381f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    }
23821406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    break;
23831406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_START_WPS_PIN_FROM_DEVICE:
23841406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    bssid = (String) message.obj;
23851406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    int pin = WifiConfigStore.startWpsWithPinFromDevice(bssid);
23861406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    success = (pin != FAILURE);
23871406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN_FROM_DEVICE, pin);
23881406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
2389f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    if (success) {
239019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mSupplicantStateTracker.sendMessage(message.what);
2391f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                        /* Expect a disconnection from the old connection */
2392f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                        transitionTo(mDisconnectingState);
2393f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    }
2394f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    break;
23950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
23960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
23970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
23980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
23990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
24000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
24010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection established");
24020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
24030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2404cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    //TODO: make supplicant modification to push this in events
2405cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    mWifiInfo.setSSID(fetchSSID());
24060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid = stateChangeResult.BSSID);
24070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
24080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = stateChangeResult.networkId;
24090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
2410be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
24110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
24120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
24130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
24150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection lost");
24160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
24170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
24180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
24200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
24210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
24220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
24230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
24240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
24260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectingState extends HierarchicalState {
242831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mModifiedBluetoothCoexistenceMode;
242931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        int mPowerMode;
243031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mUseStaticIp;
24310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Thread mDhcpThread;
24320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
24360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
24370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
243831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
24390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!mUseStaticIp) {
24400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = null;
244131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mModifiedBluetoothCoexistenceMode = false;
24425876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                mPowerMode = POWER_MODE_AUTO;
24430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2444cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                if (shouldDisableCoexistenceMode()) {
24450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
24460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * There are problems setting the Wi-Fi driver's power
24470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode to active when bluetooth coexistence mode is
24480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * enabled or sense.
24490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * We set Wi-Fi to active mode when
24510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address because we've found
24520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * compatibility issues with some routers with low power
24530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode.
24540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * In order for this active power mode to properly be set,
24560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * we disable coexistence mode until we're done with
24570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address.  One exception is if we
24580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * are currently connected to a headset, since disabling
24590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * coexistence would interrupt that connection.
24600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
246131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    mModifiedBluetoothCoexistenceMode = true;
24620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Disable the coexistence mode
24640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(
24650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
24660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
246831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mPowerMode =  WifiNative.getPowerModeCommand();
246931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (mPowerMode < 0) {
24700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Handle the case where supplicant driver does not support
24710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // getPowerModeCommand.
24725876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    mPowerMode = POWER_MODE_AUTO;
24730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24745876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                if (mPowerMode != POWER_MODE_ACTIVE) {
24755876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
24760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "DHCP request started");
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = new Thread(new Runnable() {
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    public void run() {
248131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        DhcpInfo dhcpInfo = new DhcpInfo();
248231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfo)) {
24830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request succeeded");
248431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            synchronized (mDhcpInfo) {
248531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                                mDhcpInfo = dhcpInfo;
248631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            }
24870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_SUCCESS);
24880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
24890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request failed: " +
24900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    NetworkUtils.getDhcpError());
24910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_FAILURE);
24920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
24930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
24940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                });
24950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread.start();
24960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
249731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                DhcpInfo dhcpInfo = WifiConfigStore.getIpConfiguration(mLastNetworkId);
249831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (NetworkUtils.configureInterface(mInterfaceName, dhcpInfo)) {
24990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration succeeded");
250031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    synchronized (mDhcpInfo) {
250131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        mDhcpInfo = dhcpInfo;
250231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    }
25030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_SUCCESS);
25040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
25050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration failed");
25060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_FAILURE);
25070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
25080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
25090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         }
25100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
25110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public boolean processMessage(Message message) {
25120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
25130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          switch(message.what) {
25150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_SUCCESS:
25160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mLastSignalLevel = -1; // force update of signal strength
251731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  synchronized (mDhcpInfo) {
251831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                      mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
251931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  }
252037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                  configureLinkProperties();
2521be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  if (getNetworkDetailedState() == DetailedState.CONNECTED) {
2522be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendLinkConfigurationChangedBroadcast();
2523be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  } else {
2524be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      setNetworkDetailedState(DetailedState.CONNECTED);
2525be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendNetworkStateChangeBroadcast(mLastBssid);
2526be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  }
252731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //TODO: The framework is not detecting a DHCP renewal and a possible
252831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //IP change. we should detect this and send out a config change broadcast
25290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mConnectedState);
25300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_FAILURE:
25320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mWifiInfo.setIpAddress(0);
25330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  Log.e(TAG, "IP configuration failed");
25350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /**
25360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * If we've exceeded the maximum number of retries for DHCP
25370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * to a given network, disable the network
25380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (++mReconnectCount > getMaxDhcpRetries()) {
254068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      Log.e(TAG, "Failed " +
254168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                              mReconnectCount + " times, Disabling " + mLastNetworkId);
254204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                      WifiConfigStore.disableNetwork(mLastNetworkId);
254368825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      mReconnectCount = 0;
25440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* DHCP times out after about 30 seconds, we do a
25470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * disconnect and an immediate reconnect to try again
25480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.disconnectCommand();
25500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.reconnectCommand();
25510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_DISCONNECT:
2554e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                  WifiNative.disconnectCommand();
25550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
2557a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  /* Ignore connection to same network */
2558a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff              case CMD_CONNECT_NETWORK:
2559a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  int netId = message.arg1;
2560a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  if (mWifiInfo.getNetworkId() == netId) {
2561a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                      break;
2562a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  }
2563a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  return NOT_HANDLED;
2564be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff              case CMD_SAVE_NETWORK:
2565be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  deferMessage(message);
2566be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  break;
25670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* Ignore */
25680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case NETWORK_CONNECTION_EVENT:
25690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_STOP_DRIVER:
25710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  sendMessage(CMD_DISCONNECT);
25720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  deferMessage(message);
25730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_SET_SCAN_MODE:
25750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (message.arg1 == SCAN_ONLY_MODE) {
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendMessage(CMD_DISCONNECT);
25770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      deferMessage(message);
25780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
258019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  /* Defer scan when IP is being fetched */
258119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff              case CMD_START_SCAN:
258219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  deferMessage(message);
258319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  break;
25845876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  /* Defer any power mode changes since we must keep active power mode at DHCP */
25855876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              case CMD_SET_HIGH_PERF_MODE:
25865876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  deferMessage(message);
25875876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  break;
25880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              default:
25890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return NOT_HANDLED;
25900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
25910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          return HANDLED;
25930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
25940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
25960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public void exit() {
25970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          /* reset power state & bluetooth coexistence if on DHCP */
25980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (!mUseStaticIp) {
25995876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              if (mPowerMode != POWER_MODE_ACTIVE) {
260031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  WifiNative.setPowerModeCommand(mPowerMode);
26010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
26020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
260331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff              if (mModifiedBluetoothCoexistenceMode) {
26040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Set the coexistence mode back to its default value
26050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.setBluetoothCoexistenceModeCommand(
26060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
26070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
26080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
26090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
26110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectedState extends HierarchicalState {
26140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
26170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
261819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mRssiPollToken++;
261919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (mEnableRssiPolling) {
262019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendMessage(obtainMessage(WifiStateMachine.CMD_RSSI_POLL, mRssiPollToken, 0));
262119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
26220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
26260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
26270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2628e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
26290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
26300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
26320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_DISCONNECT);
26330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
26340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26359beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
26369beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    if (mCm == null) {
26379beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                        mCm = (ConnectivityManager)mContext.getSystemService(
26389beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                                Context.CONNECTIVITY_SERVICE);
26399beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    }
26409beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    mCm.requestNetworkTransitionWakelock(TAG);
26419beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    break;
26420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
26430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
26440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
26450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
26460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
26470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
264819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
264919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* When the network is connected, re-scanning can trigger
265019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * a reconnection. Put it in scan-only mode during scan.
265119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * When scan results are received, the mode is switched
265219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * back to CONNECT_MODE.
265319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     */
265419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
265519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
265619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
2657a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Ignore connection to same network */
2658a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                case CMD_CONNECT_NETWORK:
2659a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    int netId = message.arg1;
2660a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    if (mWifiInfo.getNetworkId() == netId) {
2661a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                        break;
2662a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    }
2663a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    return NOT_HANDLED;
2664be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                case CMD_SAVE_NETWORK:
2665be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
2666be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
2667be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
2668be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasIpChanged()) {
2669be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring IP on connection");
2670be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            NetworkUtils.resetConnections(mInterfaceName);
2671be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            transitionTo(mConnectingState);
2672be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2673be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasProxyChanged()) {
2674be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring proxy on connection");
2675be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            configureLinkProperties();
2676be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            sendLinkConfigurationChangedBroadcast();
2677be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2678be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    }
2679be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    break;
26800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
26810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
26820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
268319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
268419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (message.arg1 == mRssiPollToken) {
268519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Get Info and continue polling
268619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
268719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
268819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
268919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    } else {
269019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Polling has completed
269119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
269219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
269319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_ENABLE_RSSI_POLL:
269419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
269519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mRssiPollToken++;
269619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (mEnableRssiPolling) {
269719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // first poll
269819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
269919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
270019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
270119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
270219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
27030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectingState extends HierarchicalState {
27120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
27210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
27220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
27230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
27270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
272919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* Handle in  DisconnectedState */
273019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
273119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    deferMessage(message);
273219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
27330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
2739a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        @Override
2740a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        public void exit() {
2741a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff            if (mEnableAllNetworks) {
2742a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                mEnableAllNetworks = false;
274304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                WifiConfigStore.enableAllNetworks();
2744a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff            }
2745a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        }
27460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectedState extends HierarchicalState {
27490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
2753090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2754090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            /**
2755090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * In a disconnected state, an infrequent scan that wakes
2756090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * up the device is needed to ensure a user connects to
2757090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * an access point on the move
2758090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             */
2759090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
2760090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
2761090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2762090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
2763090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
27640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
27690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
27720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
27730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.disconnectCommand();
27740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
27750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
27760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
27790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
27800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
278119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
278219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
278319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    SupplicantState state = (SupplicantState) stateChangeResult.state;
2784be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(state));
278519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* DriverStartedState does the rest of the handling */
278619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    return NOT_HANDLED;
27870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
2793090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2794090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        @Override
2795090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        public void exit() {
2796090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.cancel(mScanIntent);
2797090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        }
27980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
28000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SoftApStartedState extends HierarchicalState {
28010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
28100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
28110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Stopping Soft AP");
28120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
28130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.stopAccessPoint();
28150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in stopAccessPoint()");
28170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
28190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
28210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"SoftAP set on a running access point");
28220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.setAccessPoint((WifiConfiguration) message.obj,
28240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
28250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
28260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in nwService during soft AP set");
28280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
28290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            nwService.stopAccessPoint();
28300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception ee) {
28310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Slog.e(TAG, "Could not stop AP, :" + ee);
28320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
28330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
28340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* Fail client mode operation when soft AP is enabled */
28370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
28380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG,"Cannot start supplicant with a running soft AP");
28390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
28400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
2849