WifiStateMachine.java revision 124b44d89bc00b150c9478ccddfa83cac0f1df24
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;
4234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.app.backup.IBackupManager;
4334ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.bluetooth.BluetoothAdapter;
4434ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.BroadcastReceiver;
4534ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.Context;
4634ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.Intent;
4734ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.IntentFilter;
4834ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.ConnectivityManager;
490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.DhcpInfo;
500216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwaltimport android.net.DhcpInfoInternal;
5127d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwaltimport android.net.InterfaceConfiguration;
5234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.LinkAddress;
5334ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.LinkProperties;
5434ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.NetworkInfo;
550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
5627d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwaltimport android.net.NetworkUtils;
57e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriffimport android.net.wifi.WpsResult.Status;
580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Binder;
590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.IBinder;
600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.INetworkManagementService;
6134ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.Message;
620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.PowerManager;
6334ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.Process;
640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.RemoteException;
650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.ServiceManager;
6634ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.SystemProperties;
6703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackbornimport android.os.WorkSource;
680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.provider.Settings;
690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.EventLog;
700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Log;
7134ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.util.LruCache;
72090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.app.IBatteryStats;
744b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Savilleimport com.android.internal.util.AsyncChannel;
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalState;
760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalStateMachine;
770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriffimport java.net.InetAddress;
790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.ArrayList;
800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.List;
810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.concurrent.atomic.AtomicInteger;
820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.regex.Pattern;
830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Track the state of Wifi connectivity. All event handling is done here,
860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and all changes in connectivity state are initiated here.
870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @hide
890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpublic class WifiStateMachine extends HierarchicalStateMachine {
910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String TAG = "WifiStateMachine";
930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String NETWORKTYPE = "WIFI";
940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final boolean DBG = false;
950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* TODO: fetch a configurable interface */
970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String SOFTAP_IFACE = "wl0.1";
980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiMonitor mWifiMonitor;
1000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private INetworkManagementService nwService;
1010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ConnectivityManager mCm;
1020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results handling */
1040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private List<ScanResult> mScanResults;
1050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final Pattern scanResultPattern = Pattern.compile("\t+");
1060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULT_CACHE_SIZE = 80;
10734ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilson    private final LruCache<String, ScanResult> mScanResultCache;
1080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mInterfaceName;
1100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastSignalLevel = -1;
1120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mLastBssid;
1130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastNetworkId;
1140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mEnableRssiPolling = false;
11519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private int mRssiPollToken = 0;
1160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mReconnectCount = 0;
1170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mIsScanMode = false;
1180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    private boolean mBluetoothConnectionActive = false;
12065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff
1210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
12219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Interval in milliseconds between polling for RSSI
12319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * and linkspeed information
12419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
12519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
12619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /**
12896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Delay between supplicant restarts upon failure to establish connection
12996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
13096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;
13196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
13296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /**
13396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Number of times we attempt to restart supplicant
13496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
13596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_TRIES = 5;
13696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
13796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private int mSupplicantRestartCount = 0;
13896071a7031bac06e3f249610b010ad5651efe8aeIrfan 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
1460216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    private DhcpInfoInternal mDhcpInfoInternal;
1470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiInfo mWifiInfo;
1480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkInfo mNetworkInfo;
1490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SupplicantStateTracker mSupplicantStateTracker;
15002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    private WpsStateMachine mWpsStateMachine;
15102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
152090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private AlarmManager mAlarmManager;
153090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private PendingIntent mScanIntent;
15436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Tracks current frequency mode */
15536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
156090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
1574b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    // Channel for sending replies.
1584b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    private AsyncChannel mReplyChannel = new AsyncChannel();
1594b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
1600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Event log tags (must be in sync with event-log-tags)
1610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
1620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
1630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED  = 50023;
1640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Load the driver */
16619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER                      = 1;
1670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unload the driver */
16819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER                    = 2;
1690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load succeeded */
17019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER_SUCCESS              = 3;
1710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load failed */
17219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER_FAILURE              = 4;
1730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload succeeded */
17419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER_SUCCESS            = 5;
1750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload failed */
17619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER_FAILURE            = 6;
1770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the supplicant */
17919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_SUPPLICANT                 = 11;
1800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the supplicant */
18119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_SUPPLICANT                  = 12;
1820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
18319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_DRIVER                     = 13;
1840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
18519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_DRIVER                      = 14;
1860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP succeded */
18719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_IP_CONFIG_SUCCESS                = 15;
1880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP failed */
18919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_IP_CONFIG_FAILURE                = 16;
1900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the soft access point */
19219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_AP                         = 21;
1930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the soft access point */
19419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_AP                          = 22;
1950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = 23;
1970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant events */
1990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant established */
20019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUP_CONNECTION_EVENT                 = 31;
2010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant lost */
20219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUP_DISCONNECTION_EVENT              = 32;
2030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start completed */
20419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int DRIVER_START_EVENT                   = 33;
2050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stop completed */
20619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int DRIVER_STOP_EVENT                    = 34;
2070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network connection completed */
20819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int NETWORK_CONNECTION_EVENT             = 36;
2090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network disconnection completed */
21019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int NETWORK_DISCONNECTION_EVENT          = 37;
2110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results are available */
21219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SCAN_RESULTS_EVENT                   = 38;
2130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicate state changed */
21419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
215b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /* Password failure and EAP authentication failure */
216b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    static final int AUTHENTICATION_FAILURE_EVENT         = 40;
217fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /* WPS overlap detected */
218fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    static final int WPS_OVERLAP_EVENT                    = 41;
219fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
2200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands */
2220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Is supplicant alive ? */
22319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_PING_SUPPLICANT                  = 51;
2240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Add/update a network configuration */
22519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ADD_OR_UPDATE_NETWORK            = 52;
2260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Delete a network */
22719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REMOVE_NETWORK                   = 53;
2280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable a network. The device will attempt a connection to the given network. */
22919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ENABLE_NETWORK                   = 54;
2308e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    /* Enable all networks */
2318e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_ENABLE_ALL_NETWORKS              = 55;
2320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disable a network. The device does not attempt a connection to the given network. */
2338e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_DISABLE_NETWORK                  = 56;
2340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Blacklist network. De-prioritizes the given BSSID for connection. */
2358e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_BLACKLIST_NETWORK                = 57;
2360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear the blacklist network list */
2378e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_CLEAR_BLACKLIST                  = 58;
2380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Save configuration */
2398e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_SAVE_CONFIG                      = 59;
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;
268ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /* Set the country code */
26919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_COUNTRY_CODE                 = 80;
2700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Request connectivity manager wake lock before driver stop */
27119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REQUEST_CM_WAKELOCK              = 81;
2720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enables RSSI poll */
27319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ENABLE_RSSI_POLL                 = 82;
2740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* RSSI poll */
27519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_RSSI_POLL                        = 83;
2760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set up packet filtering */
27719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_PACKET_FILTERING           = 84;
2780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear packet filter */
27919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_PACKET_FILTERING            = 85;
280e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Connect to a specified network (network id
281e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * or WifiConfiguration) This involves increasing
282e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * the priority of the network, enabling the network
283e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * (while disabling others) and issuing a reconnect.
284e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * Note that CMD_RECONNECT just does a reconnect to
285e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an existing network. All the networks get enabled
286e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * upon a successful connection or a failure.
287e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
28819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_CONNECT_NETWORK                  = 86;
289e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Save the specified network. This involves adding
290e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an enabled network (if new) and updating the
291e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * config and issuing a save on supplicant config.
292e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
29319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SAVE_NETWORK                     = 87;
294e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Delete the specified network. This involves
295e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * removing the network and issuing a save on
296e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * supplicant config.
297e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
29819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_FORGET_NETWORK                   = 88;
29902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Start Wi-Fi protected setup */
30002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    static final int CMD_START_WPS                        = 89;
30136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Set the frequency band */
30202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    static final int CMD_SET_FREQUENCY_BAND               = 90;
303ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
304b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Commands from/to the SupplicantStateTracker */
305b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Reset the supplicant state tracker */
3066bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff    static final int CMD_RESET_SUPPLICANT_STATE           = 111;
307b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff
30802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Commands/events reported by WpsStateMachine */
30902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Indicates the completion of WPS activity */
310b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    static final int WPS_COMPLETED_EVENT                  = 121;
311e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    /* Reset the WPS state machine */
312e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    static final int CMD_RESET_WPS_STATE                  = 122;
31302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
3140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CONNECT_MODE   = 1;
3150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ONLY_MODE = 2;
3160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ACTIVE = 1;
3180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_PASSIVE = 2;
3190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3201406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int SUCCESS = 1;
3211406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int FAILURE = -1;
3221406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
3230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * The maximum number of times we will retry a connection to an access point
3250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * for which we have failed in acquiring an IP address from DHCP. A value of
3260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * N means that we will make N+1 connection attempts in all.
3270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * <p>
3280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
3290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * value if a Settings value is not present.
3300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
3320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3335876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private static final int POWER_MODE_ACTIVE = 1;
3345876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private static final int POWER_MODE_AUTO = 0;
3350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
336090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    /**
337090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
338090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     * Settings.Secure value is not present.
339090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     */
340090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
341090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
3420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Default parent state */
3430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDefaultState = new DefaultState();
3440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Temporary initial state */
3450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mInitialState = new InitialState();
3460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unloading the driver */
3470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadingState = new DriverUnloadingState();
3480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Loading the driver */
3490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadedState = new DriverUnloadedState();
3500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver load/unload failed */
3510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverFailedState = new DriverFailedState();
3520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loading */
3530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadingState = new DriverLoadingState();
3540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded */
3550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadedState = new DriverLoadedState();
3560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded, waiting for supplicant to start */
35796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private HierarchicalState mSupplicantStartingState = new SupplicantStartingState();
3580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded and supplicant ready */
35996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private HierarchicalState mSupplicantStartedState = new SupplicantStartedState();
36096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /* Waiting for supplicant to stop and monitor to exit */
36196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private HierarchicalState mSupplicantStoppingState = new SupplicantStoppingState();
3620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start issued, waiting for completed event */
3630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartingState = new DriverStartingState();
3640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver started */
3650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartedState = new DriverStartedState();
3660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopping */
3670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppingState = new DriverStoppingState();
3680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopped */
3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppedState = new DriverStoppedState();
3700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan for networks, no connection will be established */
3710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mScanModeState = new ScanModeState();
3720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connecting to an access point */
3730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectModeState = new ConnectModeState();
3740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Fetching IP after network connection (assoc+auth complete) */
3750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectingState = new ConnectingState();
3760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connected with IP addr */
3770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectedState = new ConnectedState();
3780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* disconnect issued, waiting for network disconnect confirmation */
3790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectingState = new DisconnectingState();
3800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network is not connected, supplicant assoc+auth is not complete */
3810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectedState = new DisconnectedState();
38202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Waiting for WPS to be completed*/
38302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    private HierarchicalState mWaitForWpsCompletionState = new WaitForWpsCompletionState();
3840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Soft Ap is running */
3860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mSoftApStartedState = new SoftApStartedState();
3870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
3910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_DISABLING},
3920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLED},
3930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLING},
3940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
3950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
3960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
3980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
4000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
4010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
4020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
4030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
4040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
4050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
4060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
4070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
4080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastEnableUid = new AtomicInteger(Process.myUid());
4100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastApEnableUid = new AtomicInteger(Process.myUid());
4110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
412090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final int SCAN_REQUEST = 0;
413090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final String ACTION_START_SCAN =
414090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        "com.android.server.WifiManager.action.START_SCAN";
415090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
41603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
41703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether WIFI is running.
41803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
41903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mIsRunning = false;
4205ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
42103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
42203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether we last told the battery stats we had started.
42303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
42403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mReportedRunning = false;
42503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
42603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
42703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Most recently set source of starting WIFI.
42803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
42903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mRunningWifiUids = new WorkSource();
43003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
43103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
43203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * The last reported UIDs that were responsible for starting WIFI.
43303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
43403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mLastRunningWifiUids = new WorkSource();
43503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
4360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final IBatteryStats mBatteryStats;
4370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public WifiStateMachine(Context context) {
4390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        super(TAG);
4400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext = context;
4420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
4440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
4450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
4470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        nwService = INetworkManagementService.Stub.asInterface(b);
4480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiMonitor = new WifiMonitor(this);
4500216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        mDhcpInfoInternal = new DhcpInfoInternal();
4510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo = new WifiInfo();
4520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
45319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
45402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
45537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties = new LinkProperties();
4560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo.setIsAvailable(false);
45837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
4590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid = null;
4600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
4610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastSignalLevel = -1;
4620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
463090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
464090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        Intent scanIntent = new Intent(ACTION_START_SCAN, null);
465090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
466090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
467090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mContext.registerReceiver(
46843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            new BroadcastReceiver() {
46943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                @Override
47043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                public void onReceive(Context context, Intent intent) {
47143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
47243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    ArrayList<String> available = intent.getStringArrayListExtra(
47343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            ConnectivityManager.EXTRA_AVAILABLE_TETHER);
47443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    ArrayList<String> active = intent.getStringArrayListExtra(
47543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            ConnectivityManager.EXTRA_ACTIVE_TETHER);
47643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    updateTetherState(available, active);
47743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
47843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                }
47943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
48043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
48143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        mContext.registerReceiver(
482090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new BroadcastReceiver() {
483090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    @Override
484090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    public void onReceive(Context context, Intent intent) {
485090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        startScan(false);
486090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    }
487090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                },
488090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new IntentFilter(ACTION_START_SCAN));
489090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
49034ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilson        mScanResultCache = new LruCache<String, ScanResult>(SCAN_RESULT_CACHE_SIZE);
4910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
4934f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
4940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
4960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
4970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
4980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
4990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
5000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
5010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
50296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartingState, mDefaultState);
50396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartedState, mDefaultState);
50496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartingState, mSupplicantStartedState);
50596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartedState, mSupplicantStartedState);
5060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
5070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
5080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectingState, mConnectModeState);
5090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectedState, mConnectModeState);
5100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
5110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
51202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                        addState(mWaitForWpsCompletionState, mConnectModeState);
51396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppingState, mSupplicantStartedState);
51496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppedState, mSupplicantStartedState);
51596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStoppingState, mDefaultState);
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
5210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
5230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
5240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
5270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
5280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
5290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5331406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncPingSupplicant(AsyncChannel channel) {
5341406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
5351406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
5361406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
5371406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
5380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
543e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
544e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
545e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
5460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
5520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
5530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
5560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
5570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
5590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
5610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
5690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
5720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
5730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
5750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
5770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
583d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiState() {
5840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
5850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
590d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiStateByName() {
5910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
5920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
5930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
5940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
5950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
5960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
5970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
5980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
5990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
6000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
6010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
6020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
610d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiApState() {
6110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
6120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
617d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiApStateByName() {
6180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
6190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
6200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
6210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
6220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
6230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
6240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
6250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
6260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
6270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
6280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
6290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
6360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
6370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
639d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public WifiInfo syncRequestConnectionInfo() {
6400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
6410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
643d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public DhcpInfo syncGetDhcpInfo() {
6440216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        synchronized (mDhcpInfoInternal) {
6450216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            return mDhcpInfoInternal.makeDhcpInfo();
64631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
6470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setDriverStart(boolean enable) {
6534f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        if (enable) {
6544f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_START_DRIVER);
6554f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        } else {
6564f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_STOP_DRIVER);
6574f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        }
6580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
6640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
6650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
6660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
6680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
6750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
6760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
6770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
6790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
685d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<ScanResult> syncGetScanResultsList() {
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mScanResults;
6870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
692e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
693e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
6980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
699e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
700e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
7050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
706e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
707e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
7080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
7120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
7140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7151406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
7161406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
7171406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        int result = resultMsg.arg1;
7181406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7191406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
722d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<WifiConfiguration> syncGetConfiguredNetworks() {
72304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return WifiConfigStore.getConfiguredNetworks();
7240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
7280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
7300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7314b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
7324b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
7331406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7344b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        resultMsg.recycle();
7354b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        return result;
7364b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    }
7374b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
7384b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    /**
7390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
7400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
7430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7451406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
7461406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
7471406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                disableOthers ? 1 : 0);
7481406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7491406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7501406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
7550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7591406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
7601406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId);
7611406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7621406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7631406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
7680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
7690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
7810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
7820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
784e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(int netId) {
785e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, netId, 0));
786e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
787e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
788e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(WifiConfiguration wifiConfig) {
789a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        /* arg1 is used to indicate netId, force a netId value of -1 when
790a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * we are passing a configuration since the default value of
791a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * 0 is a valid netId
792a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         */
793a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, -1, 0, wifiConfig));
794e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
795e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
796e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void saveNetwork(WifiConfiguration wifiConfig) {
797e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_SAVE_NETWORK, wifiConfig));
798e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
799e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
800e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void forgetNetwork(int netId) {
801e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
802e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
803e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
804e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) {
805e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        WpsResult result;
80602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        switch (config.setup) {
80702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            case PIN_FROM_DEVICE:
808e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            case PBC:
809e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            case PIN_FROM_ACCESS_POINT:
81002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                //TODO: will go away with AsyncChannel use from settings
81102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
812e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                result = (WpsResult) resultMsg.obj;
81302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                resultMsg.recycle();
81402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                break;
815e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            default:
816e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                result = new WpsResult(Status.FAILURE);
81702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                break;
81802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
819f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        return result;
8205ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
8215ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
8220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
8230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
8240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8268e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    public void enableAllNetworks() {
8278e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        sendMessage(CMD_ENABLE_ALL_NETWORKS);
8288e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    }
8298e86b89860114386e6c43f55fc034a26798b73e2Irfan 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    /**
89065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff     * Send a message indicating bluetooth adapter connection state changed
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
89265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    public void sendBluetoothAdapterStateChange(int state) {
89365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff        sendMessage(obtainMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0));
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
9000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
9020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9031406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncSaveConfig(AsyncChannel channel) {
9041406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
9051406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9061406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9071406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9119beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * Request a wakelock with connectivity service to
9129beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * keep the device awake until we hand-off from wifi
9139beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * to an alternate network
9140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void requestCmWakeLock() {
9160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_REQUEST_CM_WAKELOCK);
9170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
91903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    public void updateBatteryWorkSource(WorkSource newSource) {
92003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        synchronized (mRunningWifiUids) {
92103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            try {
92203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (newSource != null) {
92303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    mRunningWifiUids.set(newSource);
92403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
92503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (mIsRunning) {
92603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
92703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // If the work source has changed since last time, need
92803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // to remove old work from battery stats.
92903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
93003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
93103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                                    mRunningWifiUids);
93203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mLastRunningWifiUids.set(mRunningWifiUids);
93303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        }
93403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    } else {
93503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Now being started, report it.
93603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
93703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.set(mRunningWifiUids);
93803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = true;
93903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
94003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                } else {
94103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
94203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Last reported we were running, time to stop.
94303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
94403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.clear();
94503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = false;
94603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
94703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
9484f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                mWakeLock.setWorkSource(newSource);
94903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            } catch (RemoteException ignore) {
95003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            }
95103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        }
95203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    }
95303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
954bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    @Override
955bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    public String toString() {
956bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        StringBuffer sb = new StringBuffer();
957bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        String LS = System.getProperty("line.separator");
958bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
95937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
960bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
9610216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        sb.append("mDhcpInfoInternal ").append(mDhcpInfoInternal).append(LS);
962bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
963bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
964bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastBssid ").append(mLastBssid).append(LS);
965bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
966bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
967bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
968bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("Supplicant status").append(LS)
969bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff                .append(WifiNative.statusCommand()).append(LS).append(LS);
97004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
97104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        sb.append(WifiConfigStore.dump());
972bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        return sb.toString();
973bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    }
974bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff
9750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
9760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
9770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
9780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
97943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff    private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) {
98043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
98143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        boolean wifiTethered = false;
98243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        boolean wifiAvailable = false;
98343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
98443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
98543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
98643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
98743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        if (mCm == null) {
98843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
98943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        }
99043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
99143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
99243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
99343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        for (String intf : available) {
99443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            for (String regex : wifiRegexs) {
99543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                if (intf.matches(regex)) {
99643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
99743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    InterfaceConfiguration ifcg = null;
99843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    try {
99943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        ifcg = service.getInterfaceConfig(intf);
100043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        if (ifcg != null) {
100143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            /* IP/netmask: 192.168.43.1/255.255.255.0 */
1002ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwalt                            ifcg.addr = new LinkAddress(InetAddress.getByName("192.168.43.1"), 24);
100343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            ifcg.interfaceFlags = "[up]";
100443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
100543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            service.setInterfaceConfig(intf, ifcg);
100643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        }
100743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    } catch (Exception e) {
100843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        Log.e(TAG, "Error configuring interface " + intf + ", :" + e);
100943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        setWifiApEnabled(null, false);
101043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        return;
101143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
101243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
101343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
101443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        Log.e(TAG, "Error tethering on " + intf);
101543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        setWifiApEnabled(null, false);
101643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        return;
101743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
101843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    break;
101943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                }
102043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            }
102143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        }
102243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff    }
102343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
1024ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /**
1025ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code from the system setting value, if any.
1026ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     */
1027ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    private void setCountryCode() {
1028ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        String countryCode = Settings.Secure.getString(mContext.getContentResolver(),
1029ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                Settings.Secure.WIFI_COUNTRY_CODE);
1030ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (countryCode != null && !countryCode.isEmpty()) {
1031ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode(countryCode, false);
1032ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        } else {
1033ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            //use driver default
1034ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        }
1035ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    }
1036ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
103736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
103836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the frequency band from the system setting value, if any.
103936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
104036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private void setFrequencyBand() {
104136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        int band = Settings.Secure.getInt(mContext.getContentResolver(),
104236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                Settings.Secure.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
104336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        setFrequencyBand(band, false);
104436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
104536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
10460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
10470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
10480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
105103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
105303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Failed to note battery stats in wifi");
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
10600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1061d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiState: " + syncGetWifiStateByName());
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
10640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
10660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
10670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
10720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
107503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
107703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.d(TAG, "Failed to note battery stats in wifi");
10810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
10840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
10850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1086d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiApState: " + syncGetWifiApStateByName());
10870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
10890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
10910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
10920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Parse the scan result line passed to us by wpa_supplicant (helper).
10970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param line the line to parse
10980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return the {@link ScanResult} object
10990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ScanResult parseScanResult(String line) {
11010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        ScanResult scanResult = null;
11020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (line != null) {
11030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
11040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Cache implementation (LinkedHashMap) is not synchronized, thus,
11050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * must synchronized here!
11060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
11070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized (mScanResultCache) {
11080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String[] result = scanResultPattern.split(line);
11090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (3 <= result.length && result.length <= 5) {
11100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String bssid = result[0];
11110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid | frequency | level | flags | ssid
11120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int frequency;
11130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int level;
11140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
11150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = Integer.parseInt(result[1]);
11160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = Integer.parseInt(result[2]);
11170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
11180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
11190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
11200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
11210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch (NumberFormatException e) {
11220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = 0;
11230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = 0;
11240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
11270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * The formatting of the results returned by
11280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * wpa_supplicant is intended to make the fields
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * line up nicely when printed,
11300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * not to make them easy to parse. So we have to
11310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * apply some heuristics to figure out which field
11320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * is the SSID and which field is the flags.
11330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
11340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String ssid;
11350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String flags;
11360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (result.length == 4) {
11370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (result[3].charAt(0) == '[') {
11380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = result[3];
11390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = "";
11400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
11410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = "";
11420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = result[3];
11430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else if (result.length == 5) {
11450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = result[3];
11460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = result[4];
11470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Here, we must have 3 fields: no flags and ssid
11490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // set
11500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = "";
11510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = "";
11520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid + ssid is the hash key
11550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String key = bssid + ssid;
11560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    scanResult = mScanResultCache.get(key);
11570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.level = level;
11590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.SSID = ssid;
11600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.capabilities = flags;
11610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.frequency = frequency;
11620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Do not add scan results that have no SSID set
11640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (0 < ssid.trim().length()) {
11650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
11660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
11670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    ssid, bssid, flags, level, frequency);
11680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
11690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
11720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.w(TAG, "Misformatted scan result text with " +
11730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          result.length + " fields: " + line);
11740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return scanResult;
11790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
11820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * scanResults input format
11830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ee       2427    166     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net1
11840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ff       2412    165     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net2
11850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setScanResults(String scanResults) {
11870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (scanResults == null) {
11880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<ScanResult> scanList = new ArrayList<ScanResult>();
11920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int lineCount = 0;
11940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int scanResultsLen = scanResults.length();
11960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Parse the result string, keeping in mind that the last line does
11970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // not end with a newline.
11980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
11990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
12000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                ++lineCount;
12010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineCount == 1) {
12030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lineBeg = lineEnd + 1;
12040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    continue;
12050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
12060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineEnd > lineBeg) {
12070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String line = scanResults.substring(lineBeg, lineEnd);
12080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ScanResult scanResult = parseScanResult(line);
12090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
12100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanList.add(scanResult);
12110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
1212090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        //TODO: hidden network handling
12130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
12140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
12150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                lineBeg = lineEnd + 1;
12160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResults = scanList;
12200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1222cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    private String fetchSSID() {
1223cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String status = WifiNative.statusCommand();
1224cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        if (status == null) {
1225cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            return null;
1226cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1227cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        // extract ssid from a series of "name=value"
1228cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String[] lines = status.split("\n");
1229cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        for (String line : lines) {
1230cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String[] prop = line.split(" *= *");
1231cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (prop.length < 2) continue;
1232cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String name = prop[0];
1233cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String value = prop[1];
1234cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (name.equalsIgnoreCase("ssid")) return value;
1235cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1236cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        return null;
1237cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    }
1238cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff
123919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /*
124019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Fetch RSSI and linkspeed on current connection
124119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
124219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private void fetchRssiAndLinkSpeedNative() {
124319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newRssi = WifiNative.getRssiCommand();
124419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
124519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /* some implementations avoid negative values by adding 256
124619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * so we need to adjust for that here.
124719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
124819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newRssi > 0) newRssi -= 256;
124919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(newRssi);
125019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /*
125119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * Rather then sending the raw RSSI out every time it
125219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes, we precalculate the signal level that would
125319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * be displayed in the status bar, and only send the
125419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcast if that much more coarse-grained number
125519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes. This cuts down greatly on the number of
125619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcasts, at the cost of not mWifiInforming others
125719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * interested in RSSI of all the changes in signal
125819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * level.
125919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
126019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // TODO: The second arg to the call below needs to be a symbol somewhere, but
126119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // it's actually the size of an array of icons that's private
126219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // to StatusBar Policy.
126319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
126419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
126519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendRssiChangeBroadcast(newRssi);
126619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
126719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mLastSignalLevel = newSignalLevel;
126819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        } else {
126919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(-200);
127019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
127119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newLinkSpeed = WifiNative.getLinkSpeedCommand();
127219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newLinkSpeed != -1) {
127319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
127419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
127519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
127619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12775876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private void setHighPerfModeEnabledNative(boolean enable) {
12785876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
12795876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            Log.e(TAG, "set suspend optimizations failed!");
12805876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12815876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if (enable) {
12825876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
12835876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode active failed!");
12845876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12855876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        } else {
12865876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
12875876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode auto failed!");
12885876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12895876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12905876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    }
12915876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
129237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private void configureLinkProperties() {
129396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
129496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
129596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
12960216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            synchronized (mDhcpInfoInternal) {
12970216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                mLinkProperties = mDhcpInfoInternal.makeLinkProperties();
129896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
129996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
1300128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
130196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        mLinkProperties.setInterfaceName(mInterfaceName);
130296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        Log.d(TAG, "netId=" + mLastNetworkId  + " Link configured: " + mLinkProperties.toString());
13030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
13060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return Settings.Secure.getInt(mContext.getContentResolver(),
13070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
13080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
13090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
1312be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
1313be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1314be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        mContext.sendBroadcast(intent);
13150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
13180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
1319be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
13210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
13250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
13260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
13270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
132937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
13300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
13310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
13320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
13330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1335fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    private void sendErrorBroadcast(int errorCode) {
1336fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        Intent intent = new Intent(WifiManager.ERROR_ACTION);
1337fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1338fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.putExtra(WifiManager.EXTRA_ERROR_CODE, errorCode);
1339fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        mContext.sendBroadcast(intent);
1340fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1341fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1342be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void sendLinkConfigurationChangedBroadcast() {
1343be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
1344be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
134537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
13460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
13500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
1351be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
13530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
13580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param state the new @{code DetailedState}
13590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1360be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
13610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "setDetailed state, old ="
13620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                + mNetworkInfo.getDetailedState() + " and new state=" + state);
13630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
13640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkInfo.setDetailedState(state, null, null);
13650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1368be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private DetailedState getNetworkDetailedState() {
1369be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return mNetworkInfo.getDetailedState();
1370be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    }
1371be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
13720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
13740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
13750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "Reset connections and stopping DHCP");
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Reset connections & stop DHCP
13810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
13820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.resetConnections(mInterfaceName);
13830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!NetworkUtils.stopDhcp(mInterfaceName)) {
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Could not stop DHCP");
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Disable interface */
13890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.disableInterface(mInterfaceName);
13900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* send event to CM & network change broadcast */
1392be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        setNetworkDetailedState(DetailedState.DISCONNECTED);
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
13940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
1396124b44d89bc00b150c9478ccddfa83cac0f1df24Robert Greenwalt        mWifiInfo.setInetAddress(null);
13970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
13980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
13990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setNetworkId(-1);
14000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
140237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
14030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
14050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
14110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Notifications from WifiMonitor
14120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1415b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff     * Stores supplicant state change information passed from WifiMonitor
14160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
141719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static class StateChangeResult {
1418b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff        StateChangeResult(int networkId, String BSSID, SupplicantState state) {
14190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.state = state;
14200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.BSSID = BSSID;
14210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.networkId = networkId;
14220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int networkId;
14240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String BSSID;
1425b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff        SupplicantState state;
14260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1429b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * Send the tracker a notification that a user provided
1430b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * configuration caused authentication failure - this could
1431b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * be a password failure or a EAP authentication failure
14320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1433b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    void notifyAuthenticationFailure() {
1434b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff        sendMessage(AUTHENTICATION_FAILURE_EVENT);
14350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1438fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     * Send a notification that the supplicant has detected overlapped
1439fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     * WPS sessions
1440fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     */
1441fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    void notifyWpsOverlap() {
1442fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        sendMessage(WPS_OVERLAP_EVENT);
1443fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1444fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1445fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /**
14460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a connection to the supplicant
14470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * daemon has been established.
14480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantConnection() {
14500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_CONNECTION_EVENT);
14510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
145468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * Send the tracker a notification that connection to the supplicant
145568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * daemon is lost
14560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantLost() {
14580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_DISCONNECTION_EVENT);
14590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of Wifi connectivity
14630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new network state
14660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param BSSID when the new state is {@link DetailedState#CONNECTED
14670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * NetworkInfo.DetailedState.CONNECTED},
14680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * this is the MAC address of the access point. Otherwise, it
14690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * is {@code null}.
14700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyNetworkStateChange(DetailedState newState, String BSSID, int networkId) {
14720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newState == NetworkInfo.DetailedState.CONNECTED) {
1473b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff            sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT, networkId, 0, BSSID));
14740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
1475b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff            sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT, networkId, 0, BSSID));
14760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of the supplicant
14810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new {@code SupplicantState}
14840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantStateChange(int networkId, String BSSID, SupplicantState newState) {
14860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
14870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                new StateChangeResult(networkId, BSSID, newState)));
14880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a scan has completed, and results
14920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * are available.
14930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyScanResultsAvailable() {
14950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
14960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Switch scan mode over to passive.
14970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Turning off scan-only mode happens only in "Connect" mode
14980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
14990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setScanType(false);
15000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SCAN_RESULTS_EVENT);
15010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStarted() {
15040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_START_EVENT);
15050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStopped() {
15080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_STOP_EVENT);
15090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverHung() {
15120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(false);
15130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(true);
15140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
15170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
15180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
15190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DefaultState extends HierarchicalState {
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
15240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
152565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
152665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
152765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
1528cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
15290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
15300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
15310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
15320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
15330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
15344b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                case CMD_REMOVE_NETWORK:
15351406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_SAVE_CONFIG:
15361406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, FAILURE);
15374b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                    break;
15380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
15390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
154019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
15410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
15420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
15430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
15440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
15450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
15460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
15470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
15480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
15490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
1550e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
1551e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
1552e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
1553e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
15540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
15550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
15560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
15570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
15580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
15590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
15600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
15610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
1562b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                case AUTHENTICATION_FAILURE_EVENT:
1563fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
15640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
15650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
15660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
15670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
15685876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1569ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
157036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
15710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
1572e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
1573e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1574e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
157519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
15768e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
15770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
157802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
1579e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    /* Return failure when the state machine cannot handle WPS initiation*/
1580e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mReplyChannel.replyToMessage(message, message.what,
1581e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                                new WpsResult(Status.FAILURE));
158202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
15830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
15840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG, "Error! unhandled message" + message);
15850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
15860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
15880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class InitialState extends HierarchicalState {
15920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
15940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
15950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
15960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
15970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
15980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
15990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (WifiNative.isDriverLoaded()) {
16020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
16030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
16050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
16060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadingState extends HierarchicalState {
16110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
16170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
16180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
16190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
16200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
16234f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
16240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
16260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
16290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
16300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
16310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
16320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.loadDriver()) {
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver load successful");
16360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
16370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
16380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to load driver!");
16390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
16400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
16410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
16420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
16440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
16450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
16480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16494f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
16500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
16520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
16580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
16590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
16600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
16620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
16630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
16660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
16690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
16700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
16710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
16720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
16730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
16745876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1675ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
167636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
16770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
16780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
16790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
16800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
16820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
16830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
16850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
16860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadedState extends HierarchicalState {
16900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
16990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
17000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
17010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
17030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.startSupplicant()) {
17040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Supplicant start successful");
17050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
170696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mSupplicantStartingState);
17070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
17080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to start supplicant!");
17090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
17100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.startAccessPoint((WifiConfiguration) message.obj,
17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
17170c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                    } catch (Exception e) {
17180c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        Log.e(TAG, "Exception in softap start " + e);
17190c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        try {
17200c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            nwService.stopAccessPoint();
17210c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            nwService.startAccessPoint((WifiConfiguration) message.obj,
17220c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    mInterfaceName,
17230c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    SOFTAP_IFACE);
17240c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        } catch (Exception ee) {
17250c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            Log.e(TAG, "Exception during softap restart : " + ee);
17260c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
17270c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            break;
17280c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        }
17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Soft AP start successful");
17310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
17320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mSoftApStartedState);
17330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadingState extends HierarchicalState {
17430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
17460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
17490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
17500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17534f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
17540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.unloadDriver()) {
17550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver unload successful");
17560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
17570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
17660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
17690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to unload driver!");
17700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
17710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
17760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
17800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17834f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
17840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
17850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
17860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
17900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
17920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
17930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
17940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
17990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
18000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
18020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
18030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
18040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
18050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
18060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
18070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
18085876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1809ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
181036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
18110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
18120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
18130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
18140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
18160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
18170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
18190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
18200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadedState extends HierarchicalState {
18240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
18330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
18340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadingState);
18350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
18370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
18380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
18400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
18410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverFailedState extends HierarchicalState {
18450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, getName() + "\n");
18480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
18540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
185896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStartingState extends HierarchicalState {
18590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
18680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
18690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Supplicant connection established");
1870b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_ENABLED);
187196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    mSupplicantRestartCount = 0;
1872b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    /* Reset the supplicant state to indicate the supplicant
1873b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                     * state is not known at this time */
1874b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1875e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
18760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
18770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
18780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = -1;
18790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
18800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
18820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
188304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.initialize(mContext);
18849e6222f4c126252c9950d072ab67d8b849d17643Irfan Sheriff
18850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //TODO: initialize and fix multicast filtering
18860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //mWM.initializeMulticastFiltering();
18870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
18894f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartedState);
18900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
189168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case SUP_DISCONNECTION_EVENT:
189296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
189396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        Log.e(TAG, "Failed to setup control channel, restart supplicant");
189496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        WifiNative.killSupplicant();
189596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
189696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
189796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    } else {
189896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        mSupplicantRestartCount = 0;
189996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        Log.e(TAG, "Failed " + mSupplicantRestartCount +
190096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                                " times to start supplicant, unload driver");
190196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
1902b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
190396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
19040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
190568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_LOAD_DRIVER:
190668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_UNLOAD_DRIVER:
190768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_START_SUPPLICANT:
190868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_SUPPLICANT:
19090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
191068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_AP:
19110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
19120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
19130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
19140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
19155876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1916ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
191736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
19180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
19190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
19200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
19210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
19230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
19240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
19270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
193096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStartedState extends HierarchicalState {
19310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
19330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
19340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
19350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
19360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
19376bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            /* Wifi is available as long as we have a connection to supplicant */
19386bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(true);
19390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
19420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
1943e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
19448e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
19450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
19460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
19475d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                    Log.d(TAG, "stopping supplicant");
19485d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                    if (!WifiNative.stopSupplicant()) {
19495d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                        Log.e(TAG, "Failed to stop supplicant, issue kill");
195096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        WifiNative.killSupplicant();
195196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
19526bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
195368825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    handleNetworkDisconnect();
1954b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_DISABLING);
195568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
1956b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1957e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
195896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mSupplicantStoppingState);
195968825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    break;
196096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
196196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.e(TAG, "Connection lost, restart supplicant");
196296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    WifiNative.killSupplicant();
19630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.closeSupplicantConnection();
19646bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
19650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
19660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
1967b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1968e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
197096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
19710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
19738e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
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:
19821406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    config = (WifiConfiguration) message.obj;
19831406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
19841406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                            WifiConfigStore.addOrUpdateNetwork(config));
19850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
19871406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.removeNetwork(message.arg1);
19881406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
19911406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
19921406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19948e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
19958e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    WifiConfigStore.enableAllNetworks();
19968e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    break;
19970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
19981406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.disableNetwork(message.arg1);
19991406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
20000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
20020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.addToBlacklistCommand((String)message.obj);
20030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
20050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.clearBlacklistCommand();
20060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
20081406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.saveConfig();
20091406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
20101406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
20110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
20120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
20130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
20140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
20150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
20160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
20170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
20180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
20190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
20200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
20210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
20230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
20240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
20250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
20260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
20280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
20290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2030e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
2031e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
203204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.saveNetwork(config);
2033e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
2034e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
203504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.forgetNetwork(message.arg1);
2036e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
20370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20408e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
20418e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20428e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
20430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20456bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff
20466bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        @Override
20476bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        public void exit() {
20486bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
20496bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        }
20500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
205296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStoppingState extends HierarchicalState {
205396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
205496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public void enter() {
205596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
205696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
205796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
205896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
205996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public boolean processMessage(Message message) {
206096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
206196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            switch(message.what) {
206296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_CONNECTION_EVENT:
206396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.e(TAG, "Supplicant connection received while stopping");
206496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
206596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
206696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.d(TAG, "Supplicant connection lost");
206796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    WifiNative.closeSupplicantConnection();
206896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mDriverLoadedState);
206996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
207096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_LOAD_DRIVER:
207196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_UNLOAD_DRIVER:
207296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_SUPPLICANT:
207396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_SUPPLICANT:
207496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_AP:
207596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_AP:
207696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_DRIVER:
207796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_DRIVER:
207896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_MODE:
207996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_TYPE:
208096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
208196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
208296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
208396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_PACKET_FILTERING:
208496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
208596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    deferMessage(message);
208696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
208796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                default:
208896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    return NOT_HANDLED;
208996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            }
209096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
209196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            return HANDLED;
209296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
209396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    }
209496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
20950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartingState extends HierarchicalState {
20960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
21060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStartedState);
21070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
21090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
21100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
21120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
2114b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                case AUTHENTICATION_FAILURE_EVENT:
2115fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21175876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2118ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
211936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
21200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
21210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
21220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
21240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
21250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2126e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
21270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
21320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartedState extends HierarchicalState {
21370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
21400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
214203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = true;
214303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
21440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
214565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            /**
214665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
214765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * When this mode is on, some of the low-level scan parameters used by the
214865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * driver are changed to reduce interference with bluetooth
214965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             */
215065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive);
2151ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            /* set country code */
2152ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode();
215336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            /* set frequency band of operation */
215436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            setFrequencyBand();
21553a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            /* initialize network state */
21563a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            setNetworkDetailedState(DetailedState.DISCONNECTED);
21570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
21590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
21600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.disconnectCommand();
21610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
21620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
21630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
21640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.reconnectCommand();
2165090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                transitionTo(mDisconnectedState);
21660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21718e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
21720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ACTIVE) {
21750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(true);
21760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(false);
21780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
218019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
21818e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
218219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
218319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
21845876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
21855876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    setHighPerfModeEnabledNative(message.arg1 == 1);
21860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2187ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
2188ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    String country = (String) message.obj;
2189ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Log.d(TAG, "set country code " + country);
2190ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) {
2191ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                        Log.e(TAG, "Failed to set country code " + country);
2192ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    }
21930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
219436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
219536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    int band =  message.arg1;
219636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Log.d(TAG, "set frequency band " + band);
219736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    if (WifiNative.setBandCommand(band)) {
219836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        mFrequencyBand.set(band);
2199cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        //Fetch the latest scan results when frequency band is set
2200cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        startScan(true);
220136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    } else {
220236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        Log.e(TAG, "Failed to set frequency band " + band);
220336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    }
220436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    break;
220565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
220665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
220765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
220865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive);
220965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    break;
22100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22114f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
22120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopDriverCommand();
22130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppingState);
22144f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
22150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.startPacketFiltering();
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopPacketFiltering();
22210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22258e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
22268e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22278e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
22280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
22320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
223303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = false;
223403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
2235f99819e47cbef2ec066a21b426c7e6fe95e3de48Irfan Sheriff            mScanResults = null;
22360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppingState extends HierarchicalState {
22400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
22500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppedState);
22510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
22530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
22540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
22565876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2257ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
225836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2265e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppedState extends HierarchicalState {
22760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22844f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            switch (message.what) {
22854f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                case CMD_START_DRIVER:
22864f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
22874f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    WifiNative.startDriverCommand();
22884f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartingState);
22894f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
22904f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    break;
22914f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                default:
22924f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    return NOT_HANDLED;
22934f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            }
22944f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22954f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            return HANDLED;
22960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ScanModeState extends HierarchicalState {
23000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
23030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
23080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
23090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
23100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
23110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
23120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
23130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
23140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
23150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.reconnectCommand();
23160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
23170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
23180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
23190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
23210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
23220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
23230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
23240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
23250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
23260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
23270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
23290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
23310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
23320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
23330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectModeState extends HierarchicalState {
23370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
23400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
23450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
23460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
2347b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                case AUTHENTICATION_FAILURE_EVENT:
2348b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                    mSupplicantStateTracker.sendMessage(AUTHENTICATION_FAILURE_EVENT);
23490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2350fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
2351fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    /* We just need to broadcast the error */
2352fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
2353fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    break;
23540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
23550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
2356b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    SupplicantState state = stateChangeResult.state;
235719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // Supplicant state change
235819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [31-13] Reserved for future use
235919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [8 - 0] Supplicant state (as defined in SupplicantState.java)
236019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // 50023 supplicant_state_changed (custom|1|5)
236119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
236219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setSupplicantState(state);
236319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
236419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (state == SupplicantState.ASSOCIATING) {
236519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        /* BSSID is valid only in ASSOCIATING state */
236619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mWifiInfo.setBSSID(stateChangeResult.BSSID);
236719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
236819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
236902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mSupplicantStateTracker.sendMessage(Message.obtain(message));
237002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
23710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
23730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2374e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
23750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2377e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reconnectCommand();
23780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
2380e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reassociateCommand();
23810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2382e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2383e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
2384e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
238504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
238604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* We connect to a specific network by issuing a select
238704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * to the WifiConfigStore. This enables the network,
238804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * while disabling all other networks in the supplicant.
238904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * Disabling a connected network will cause a disconnection
239004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * from the network. A reconnectCommand() will then initiate
239104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * a connection to the enabled network.
239204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     */
2393e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
239404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(config);
239504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    } else {
239604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(netId);
2397e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2398e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
23998e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    /* The state tracker handles enabling networks upon completion/failure */
24008e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_CONNECT_NETWORK);
240104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
2402a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    WifiNative.reconnectCommand();
240304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
240404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* Expect a disconnection from the old connection */
2405a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    transitionTo(mDisconnectingState);
2406e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
240702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
240802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
240902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mWaitForWpsCompletionState);
2410f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    break;
24110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
24120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
24130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
24140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
24150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
24160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
24170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection established");
2418b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastNetworkId = message.arg1;
2419b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastBssid = (String) message.obj;
24200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2421cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    //TODO: make supplicant modification to push this in events
2422cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    mWifiInfo.setSSID(fetchSSID());
2423b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid);
2424b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setNetworkId(mLastNetworkId);
24250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
2426be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
24270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
24280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
24290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
24310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection lost");
24320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
24330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
24340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
24360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
24370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
24380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
24390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
24400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
24420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectingState extends HierarchicalState {
244431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mModifiedBluetoothCoexistenceMode;
244531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        int mPowerMode;
244631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mUseStaticIp;
24470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Thread mDhcpThread;
24480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
24520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
245331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
24540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!mUseStaticIp) {
24550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = null;
245631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mModifiedBluetoothCoexistenceMode = false;
24575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                mPowerMode = POWER_MODE_AUTO;
24580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
245965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                if (!mBluetoothConnectionActive) {
24600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
24610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * There are problems setting the Wi-Fi driver's power
24620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode to active when bluetooth coexistence mode is
24630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * enabled or sense.
24640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * We set Wi-Fi to active mode when
24660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address because we've found
24670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * compatibility issues with some routers with low power
24680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode.
24690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * In order for this active power mode to properly be set,
24710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * we disable coexistence mode until we're done with
24720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address.  One exception is if we
24730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * are currently connected to a headset, since disabling
24740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * coexistence would interrupt that connection.
24750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
247631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    mModifiedBluetoothCoexistenceMode = true;
24770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Disable the coexistence mode
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
24810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
248331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mPowerMode =  WifiNative.getPowerModeCommand();
248431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (mPowerMode < 0) {
24850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Handle the case where supplicant driver does not support
24860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // getPowerModeCommand.
24875876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    mPowerMode = POWER_MODE_AUTO;
24880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24895876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                if (mPowerMode != POWER_MODE_ACTIVE) {
24905876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
24910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "DHCP request started");
24940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = new Thread(new Runnable() {
24950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    public void run() {
24960216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                        DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
24970216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                        if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal)) {
24980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request succeeded");
24990216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                            synchronized (mDhcpInfoInternal) {
25000216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                                mDhcpInfoInternal = dhcpInfoInternal;
250131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            }
25020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_SUCCESS);
25030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
25040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request failed: " +
25050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    NetworkUtils.getDhcpError());
25060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_FAILURE);
25070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
25080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
25090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                });
25100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread.start();
25110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
25120216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
25130216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                        mLastNetworkId);
251427d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
251527d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                INetworkManagementService netd = INetworkManagementService.Stub.asInterface(b);
251627d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                InterfaceConfiguration ifcg = new InterfaceConfiguration();
2517ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwalt                ifcg.addr = dhcpInfoInternal.makeLinkAddress();
251827d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                ifcg.interfaceFlags = "[up]";
251927d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                try {
252027d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                    netd.setInterfaceConfig(mInterfaceName, ifcg);
25210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration succeeded");
25220216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                    synchronized (mDhcpInfoInternal) {
25230216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                        mDhcpInfoInternal = dhcpInfoInternal;
252431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    }
25250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_SUCCESS);
252627d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                } catch (RemoteException re) {
252727d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                    Log.v(TAG, "Static IP configuration failed: " + re);
252827d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                    sendMessage(CMD_IP_CONFIG_FAILURE);
252927d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                } catch (IllegalStateException e) {
253027d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                    Log.v(TAG, "Static IP configuration failed: " + e);
25310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_FAILURE);
25320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
25330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
25340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         }
25350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
25360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public boolean processMessage(Message message) {
25370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
25380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          switch(message.what) {
25400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_SUCCESS:
25410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mLastSignalLevel = -1; // force update of signal strength
25420216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                  InetAddress addr;
25430216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                  synchronized (mDhcpInfoInternal) {
25440216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                      addr = NetworkUtils.numericToInetAddress(mDhcpInfoInternal.ipAddress);
254531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  }
2546124b44d89bc00b150c9478ccddfa83cac0f1df24Robert Greenwalt                  mWifiInfo.setInetAddress(addr);
254737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                  configureLinkProperties();
2548be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  if (getNetworkDetailedState() == DetailedState.CONNECTED) {
2549be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendLinkConfigurationChangedBroadcast();
2550be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  } else {
2551be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      setNetworkDetailedState(DetailedState.CONNECTED);
2552be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendNetworkStateChangeBroadcast(mLastBssid);
2553be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  }
255431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //TODO: The framework is not detecting a DHCP renewal and a possible
255531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //IP change. we should detect this and send out a config change broadcast
25560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mConnectedState);
25570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_FAILURE:
2559124b44d89bc00b150c9478ccddfa83cac0f1df24Robert Greenwalt                  mWifiInfo.setInetAddress(null);
25600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  Log.e(TAG, "IP configuration failed");
25620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /**
25630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * If we've exceeded the maximum number of retries for DHCP
25640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * to a given network, disable the network
25650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (++mReconnectCount > getMaxDhcpRetries()) {
256768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      Log.e(TAG, "Failed " +
256868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                              mReconnectCount + " times, Disabling " + mLastNetworkId);
256904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                      WifiConfigStore.disableNetwork(mLastNetworkId);
257068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      mReconnectCount = 0;
25710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* DHCP times out after about 30 seconds, we do a
25740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * disconnect and an immediate reconnect to try again
25750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.disconnectCommand();
25770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.reconnectCommand();
25780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_DISCONNECT:
2581e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                  WifiNative.disconnectCommand();
25820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
2584a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  /* Ignore connection to same network */
2585a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff              case CMD_CONNECT_NETWORK:
2586a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  int netId = message.arg1;
2587a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  if (mWifiInfo.getNetworkId() == netId) {
2588a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                      break;
2589a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  }
2590a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  return NOT_HANDLED;
2591be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff              case CMD_SAVE_NETWORK:
2592be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  deferMessage(message);
2593be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  break;
25940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* Ignore */
25950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case NETWORK_CONNECTION_EVENT:
25960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_STOP_DRIVER:
25980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  sendMessage(CMD_DISCONNECT);
25990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  deferMessage(message);
26000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
26010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_SET_SCAN_MODE:
26020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (message.arg1 == SCAN_ONLY_MODE) {
26030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendMessage(CMD_DISCONNECT);
26040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      deferMessage(message);
26050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
26060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
260719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  /* Defer scan when IP is being fetched */
260819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff              case CMD_START_SCAN:
260919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  deferMessage(message);
261019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  break;
26115876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  /* Defer any power mode changes since we must keep active power mode at DHCP */
26125876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              case CMD_SET_HIGH_PERF_MODE:
26135876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  deferMessage(message);
26145876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  break;
26150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              default:
26160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return NOT_HANDLED;
26170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
26180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
26190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          return HANDLED;
26200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
26210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
26230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public void exit() {
26240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          /* reset power state & bluetooth coexistence if on DHCP */
26250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (!mUseStaticIp) {
26265876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              if (mPowerMode != POWER_MODE_ACTIVE) {
262731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  WifiNative.setPowerModeCommand(mPowerMode);
26280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
26290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
263031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff              if (mModifiedBluetoothCoexistenceMode) {
26310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Set the coexistence mode back to its default value
26320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.setBluetoothCoexistenceModeCommand(
26330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
26340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
26350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
26360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
26380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectedState extends HierarchicalState {
26410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
26440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
264519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mRssiPollToken++;
264619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (mEnableRssiPolling) {
264719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendMessage(obtainMessage(WifiStateMachine.CMD_RSSI_POLL, mRssiPollToken, 0));
264819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
26490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
26538e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
26540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
26550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2656e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
26570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
26580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
26600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_DISCONNECT);
26610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
26620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26639beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
26649beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    if (mCm == null) {
26659beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                        mCm = (ConnectivityManager)mContext.getSystemService(
26669beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                                Context.CONNECTIVITY_SERVICE);
26679beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    }
26689beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    mCm.requestNetworkTransitionWakelock(TAG);
26699beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    break;
26700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
26710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
26720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
26730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
26740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
26750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
267619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
26778e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
267819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* When the network is connected, re-scanning can trigger
267919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * a reconnection. Put it in scan-only mode during scan.
268019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * When scan results are received, the mode is switched
268119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * back to CONNECT_MODE.
268219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     */
268319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
268419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
268519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
2686a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Ignore connection to same network */
2687a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                case CMD_CONNECT_NETWORK:
2688a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    int netId = message.arg1;
2689a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    if (mWifiInfo.getNetworkId() == netId) {
2690a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                        break;
2691a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    }
2692a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    return NOT_HANDLED;
2693be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                case CMD_SAVE_NETWORK:
2694be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
2695be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
2696be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
2697be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasIpChanged()) {
2698be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring IP on connection");
2699be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            NetworkUtils.resetConnections(mInterfaceName);
2700be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            transitionTo(mConnectingState);
2701be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2702be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasProxyChanged()) {
2703be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring proxy on connection");
2704be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            configureLinkProperties();
2705be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            sendLinkConfigurationChangedBroadcast();
2706be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2707be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    }
2708be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    break;
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
27110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
271219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
27138e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
271419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (message.arg1 == mRssiPollToken) {
271519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Get Info and continue polling
271619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
271719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
271819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
271919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    } else {
272019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Polling has completed
272119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
272219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
272319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_ENABLE_RSSI_POLL:
272419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
272519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mRssiPollToken++;
272619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (mEnableRssiPolling) {
272719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // first poll
272819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
272919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
273019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
273119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
273219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
27330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27368e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
27378e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27388e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
27390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectingState extends HierarchicalState {
27440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
27530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
27540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
27550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
27590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
276119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* Handle in  DisconnectedState */
276219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
276319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    deferMessage(message);
276419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
27650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectedState extends HierarchicalState {
27740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
2778090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2779090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            /**
2780090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * In a disconnected state, an infrequent scan that wakes
2781090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * up the device is needed to ensure a user connects to
2782090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * an access point on the move
2783090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             */
2784090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
2785090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
2786090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2787090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
2788090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
27890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
27940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
27970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
27980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.disconnectCommand();
27990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
28000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
28010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
28040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
28050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
280619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
280719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
2808b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
280919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* DriverStartedState does the rest of the handling */
281019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    return NOT_HANDLED;
28110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
2817090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2818090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        @Override
2819090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        public void exit() {
2820090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.cancel(mScanIntent);
2821090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        }
28220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
282402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    class WaitForWpsCompletionState extends HierarchicalState {
282502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
282602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public void enter() {
282702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
282802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
282902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
283002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
283102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public boolean processMessage(Message message) {
283202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
283302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            switch (message.what) {
283402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                /* Defer all commands that can cause connections to a different network
283502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 * or put the state machine out of connect mode
283602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 */
283702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_STOP_DRIVER:
283802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_SET_SCAN_MODE:
283902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_CONNECT_NETWORK:
284002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_ENABLE_NETWORK:
284102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_RECONNECT:
284202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_REASSOCIATE:
284302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case NETWORK_CONNECTION_EVENT: /* Handled after IP & proxy update */
284402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    deferMessage(message);
284502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
284602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
284702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    Log.d(TAG,"Network connection lost");
284802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    handleNetworkDisconnect();
284902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
285002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case WPS_COMPLETED_EVENT:
285102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    /* we are still disconnected until we see a network connection
285202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                     * notification */
285302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mDisconnectedState);
285402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
285502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                default:
285602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    return NOT_HANDLED;
285702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            }
285802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
285902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            return HANDLED;
286002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
286102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    }
286202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
28630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SoftApStartedState extends HierarchicalState {
28640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
28730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
28740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Stopping Soft AP");
28750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
287643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
287743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    if (mCm == null) {
287843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        mCm = (ConnectivityManager) mContext.getSystemService(
287943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                                Context.CONNECTIVITY_SERVICE);
288043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
288143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    if (mCm.untether(SOFTAP_IFACE) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
288243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        Log.e(TAG, "Untether initiate failed!");
288343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
28840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.stopAccessPoint();
28860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in stopAccessPoint()");
28880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
28900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
28920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"SoftAP set on a running access point");
28930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.setAccessPoint((WifiConfiguration) message.obj,
28950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
28960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
28970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28980c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        Log.e(TAG, "Exception in softap set " + e);
28990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
29000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            nwService.stopAccessPoint();
29010c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            nwService.startAccessPoint((WifiConfiguration) message.obj,
29020c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    mInterfaceName,
29030c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    SOFTAP_IFACE);
29040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception ee) {
29050c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            Log.e(TAG, "Could not restart softap after set failed " + ee);
29060c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
29070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
29080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
29090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* Fail client mode operation when soft AP is enabled */
29110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
29120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG,"Cannot start supplicant with a running soft AP");
29130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
29140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
29160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
29170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
29180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
29190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
29200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
29210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
29220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
2923