WifiStateMachine.java revision 0c7e16450c9060551bd0bea6e08bc9fb2ba411b4
10d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/*
20d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Copyright (C) 2010 The Android Open Source Project
30d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
40d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License");
50d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * you may not use this file except in compliance with the License.
60d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * You may obtain a copy of the License at
70d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
80d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *      http://www.apache.org/licenses/LICENSE-2.0
90d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Unless required by applicable law or agreed to in writing, software
110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS,
120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * See the License for the specific language governing permissions and
140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * limitations under the License.
150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpackage android.net.wifi;
180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * TODO: Add soft AP states as part of WIFI_STATE_XXX
270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Retain WIFI_STATE_ENABLING that indicates driver is loading
280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Add WIFI_STATE_AP_ENABLED to indicate soft AP has started
290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and WIFI_STATE_FAILED for failure
300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Deprecate WIFI_STATE_UNKNOWN
310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Doing this will simplify the logic for sending broadcasts
330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
40090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.AlarmManager;
41090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.PendingIntent;
42ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.net.LinkAddress;
430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo;
440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.DhcpInfo;
450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkUtils;
460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.ConnectivityManager;
470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
4837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltimport android.net.LinkProperties;
49be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriffimport android.net.wifi.NetworkUpdateResult;
50e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriffimport android.net.wifi.WpsResult.Status;
510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Binder;
520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Message;
530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.IBinder;
540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.INetworkManagementService;
550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.PowerManager;
560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.SystemProperties;
570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.RemoteException;
580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.ServiceManager;
590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Process;
6003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackbornimport android.os.WorkSource;
610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.provider.Settings;
620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.EventLog;
630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Log;
640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.backup.IBackupManager;
657440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
66090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.content.BroadcastReceiver;
670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Intent;
680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Context;
69090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.content.IntentFilter;
70090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.app.IBatteryStats;
724b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Savilleimport com.android.internal.util.AsyncChannel;
730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalState;
740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalStateMachine;
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff
770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.ArrayList;
780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.LinkedHashMap;
790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.List;
800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.Map;
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;
1070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final LinkedHashMap<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
1460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private DhcpInfo mDhcpInfo;
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;
2150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Password may be incorrect */
21619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int PASSWORD_MAY_BE_INCORRECT_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);
4500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mDhcpInfo = new DhcpInfo();
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(
468090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new BroadcastReceiver() {
469090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    @Override
470090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    public void onReceive(Context context, Intent intent) {
471090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        startScan(false);
472090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    }
473090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                },
474090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new IntentFilter(ACTION_START_SCAN));
475090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
4760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResultCache = new LinkedHashMap<String, ScanResult>(
4770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SCAN_RESULT_CACHE_SIZE, 0.75f, true) {
4780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /*
4790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * Limit the cache size by SCAN_RESULT_CACHE_SIZE
4800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * elements
4810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 */
4820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                @Override
4830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public boolean removeEldestEntry(Map.Entry eldest) {
4840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return SCAN_RESULT_CACHE_SIZE < this.size();
4850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
4860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        };
4870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
4894f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
4900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
4920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
4930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
4940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
4950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
4960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
4970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
49896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartingState, mDefaultState);
49996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartedState, mDefaultState);
50096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartingState, mSupplicantStartedState);
50196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartedState, mSupplicantStartedState);
5020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
5030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
5040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectingState, mConnectModeState);
5050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectedState, mConnectModeState);
5060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
5070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
50802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                        addState(mWaitForWpsCompletionState, mConnectModeState);
50996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppingState, mSupplicantStartedState);
51096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppedState, mSupplicantStartedState);
51196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStoppingState, mDefaultState);
5120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
5130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
5150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
5230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
5240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
5250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5291406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncPingSupplicant(AsyncChannel channel) {
5301406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
5311406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
5321406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
5331406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
5340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
539e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
540e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
541e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
5420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
5480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
5490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
5520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
5530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
5550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
5570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
5640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
5650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
5690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
5710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
5730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
579d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiState() {
5800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
5810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
586d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiStateByName() {
5870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
5880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
5890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
5900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
5910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
5920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
5930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
5940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
5950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
5960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
5970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
5980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
5990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
606d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiApState() {
6070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
6080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
613d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiApStateByName() {
6140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
6150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
6160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
6170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
6180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
6190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
6200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
6210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
6220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
6230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
6240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
6250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
6320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
6330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
635d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public WifiInfo syncRequestConnectionInfo() {
6360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
6370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
639d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public DhcpInfo syncGetDhcpInfo() {
64031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        synchronized (mDhcpInfo) {
64131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            return new DhcpInfo(mDhcpInfo);
64231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
6430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setDriverStart(boolean enable) {
6494f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        if (enable) {
6504f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_START_DRIVER);
6514f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        } else {
6524f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_STOP_DRIVER);
6534f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        }
6540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
6600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
6610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
6620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
6640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
6710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
6720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
6730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
6750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
681d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<ScanResult> syncGetScanResultsList() {
6820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mScanResults;
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
6870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
688e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
689e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
6900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
695e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
696e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
6970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
702e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
703e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
7040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
7080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
7100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7111406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
7121406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
7131406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        int result = resultMsg.arg1;
7141406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7151406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
718d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<WifiConfiguration> syncGetConfiguredNetworks() {
71904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return WifiConfigStore.getConfiguredNetworks();
7200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
7240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
7260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7274b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
7284b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
7291406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7304b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        resultMsg.recycle();
7314b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        return result;
7324b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    }
7334b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
7344b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    /**
7350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
7360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
7390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7411406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
7421406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
7431406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                disableOthers ? 1 : 0);
7441406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7451406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7461406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
7510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7551406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
7561406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId);
7571406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7581406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7591406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
7670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
7690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
7700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
780e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(int netId) {
781e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, netId, 0));
782e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
783e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
784e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(WifiConfiguration wifiConfig) {
785a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        /* arg1 is used to indicate netId, force a netId value of -1 when
786a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * we are passing a configuration since the default value of
787a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * 0 is a valid netId
788a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         */
789a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, -1, 0, wifiConfig));
790e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
791e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
792e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void saveNetwork(WifiConfiguration wifiConfig) {
793e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_SAVE_NETWORK, wifiConfig));
794e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
795e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
796e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void forgetNetwork(int netId) {
797e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
798e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
799e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
800e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) {
801e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        WpsResult result;
80202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        switch (config.setup) {
80302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            case PIN_FROM_DEVICE:
804e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            case PBC:
805e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            case PIN_FROM_ACCESS_POINT:
80602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                //TODO: will go away with AsyncChannel use from settings
80702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
808e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                result = (WpsResult) resultMsg.obj;
80902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                resultMsg.recycle();
81002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                break;
811e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            default:
812e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                result = new WpsResult(Status.FAILURE);
81302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                break;
81402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
815f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        return result;
8165ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
8175ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
8180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
8190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
8200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8228e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    public void enableAllNetworks() {
8238e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        sendMessage(CMD_ENABLE_ALL_NETWORKS);
8248e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    }
8258e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff
8260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Start packet filtering
8280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void startPacketFiltering() {
8300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_START_PACKET_FILTERING);
8310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Stop packet filtering
8350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void stopPacketFiltering() {
8370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_STOP_PACKET_FILTERING);
8380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8415876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Set high performance mode of operation.
8425876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Enabling would set active power mode and disable suspend optimizations;
8435876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * disabling would set auto power mode and enable suspend optimizations
8445876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * @param enable true if enable, false otherwise
8450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8465876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    public void setHighPerfModeEnabled(boolean enable) {
8475876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
8480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
851ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code
852ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param countryCode following ISO 3166 format
853ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
8540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
855ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    public void setCountryCode(String countryCode, boolean persist) {
856ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (persist) {
857ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            Settings.Secure.putString(mContext.getContentResolver(),
858ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Settings.Secure.WIFI_COUNTRY_CODE,
859ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    countryCode);
8600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
861ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_COUNTRY_CODE, countryCode));
8620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
86536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the operational frequency band
86636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param band
86736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
86836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
86936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public void setFrequencyBand(int band, boolean persist) {
87036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        if (persist) {
87136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            Settings.Secure.putInt(mContext.getContentResolver(),
87236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Settings.Secure.WIFI_FREQUENCY_BAND,
87336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    band);
87436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        }
87536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_FREQUENCY_BAND, band, 0));
87636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
87736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
87836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
87936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Returns the operational frequency band
88036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
88136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public int getFrequencyBand() {
88236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        return mFrequencyBand.get();
88336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
88436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
88536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
88665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff     * Send a message indicating bluetooth adapter connection state changed
8870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
88865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    public void sendBluetoothAdapterStateChange(int state) {
88965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff        sendMessage(obtainMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0));
8900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8991406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncSaveConfig(AsyncChannel channel) {
9001406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
9011406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9021406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9031406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9079beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * Request a wakelock with connectivity service to
9089beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * keep the device awake until we hand-off from wifi
9099beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * to an alternate network
9100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void requestCmWakeLock() {
9120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_REQUEST_CM_WAKELOCK);
9130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
91503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    public void updateBatteryWorkSource(WorkSource newSource) {
91603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        synchronized (mRunningWifiUids) {
91703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            try {
91803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (newSource != null) {
91903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    mRunningWifiUids.set(newSource);
92003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
92103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (mIsRunning) {
92203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
92303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // If the work source has changed since last time, need
92403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // to remove old work from battery stats.
92503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
92603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
92703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                                    mRunningWifiUids);
92803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mLastRunningWifiUids.set(mRunningWifiUids);
92903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        }
93003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    } else {
93103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Now being started, report it.
93203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
93303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.set(mRunningWifiUids);
93403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = true;
93503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
93603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                } else {
93703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
93803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Last reported we were running, time to stop.
93903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
94003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.clear();
94103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = false;
94203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
94303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
9444f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                mWakeLock.setWorkSource(newSource);
94503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            } catch (RemoteException ignore) {
94603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            }
94703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        }
94803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    }
94903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
950bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    @Override
951bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    public String toString() {
952bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        StringBuffer sb = new StringBuffer();
953bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        String LS = System.getProperty("line.separator");
954bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
95537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
956bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
957bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mDhcpInfo ").append(mDhcpInfo).append(LS);
958bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
959bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
960bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastBssid ").append(mLastBssid).append(LS);
961bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
962bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
963bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
964bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("Supplicant status").append(LS)
965bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff                .append(WifiNative.statusCommand()).append(LS).append(LS);
96604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
96704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        sb.append(WifiConfigStore.dump());
968bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        return sb.toString();
969bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    }
970bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff
9710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
9720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
9730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
9740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
975ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /**
976ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code from the system setting value, if any.
977ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     */
978ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    private void setCountryCode() {
979ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        String countryCode = Settings.Secure.getString(mContext.getContentResolver(),
980ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                Settings.Secure.WIFI_COUNTRY_CODE);
981ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (countryCode != null && !countryCode.isEmpty()) {
982ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode(countryCode, false);
983ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        } else {
984ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            //use driver default
985ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        }
986ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    }
987ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
98836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
98936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the frequency band from the system setting value, if any.
99036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
99136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private void setFrequencyBand() {
99236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        int band = Settings.Secure.getInt(mContext.getContentResolver(),
99336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                Settings.Secure.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
99436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        setFrequencyBand(band, false);
99536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
99636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
9970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
9980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
9990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
100203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
100403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Failed to note battery stats in wifi");
10080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
10110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1012d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiState: " + syncGetWifiStateByName());
10130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
10150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
10170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
10180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
10220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
10230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
102603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
102803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.d(TAG, "Failed to note battery stats in wifi");
10320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
10350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
10360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1037d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiApState: " + syncGetWifiApStateByName());
10380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
10400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
10420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
10430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Parse the scan result line passed to us by wpa_supplicant (helper).
10480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param line the line to parse
10490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return the {@link ScanResult} object
10500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ScanResult parseScanResult(String line) {
10520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        ScanResult scanResult = null;
10530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (line != null) {
10540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
10550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Cache implementation (LinkedHashMap) is not synchronized, thus,
10560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * must synchronized here!
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
10580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized (mScanResultCache) {
10590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String[] result = scanResultPattern.split(line);
10600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (3 <= result.length && result.length <= 5) {
10610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String bssid = result[0];
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid | frequency | level | flags | ssid
10630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int frequency;
10640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int level;
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
10660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = Integer.parseInt(result[1]);
10670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = Integer.parseInt(result[2]);
10680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
10690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
10700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
10720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch (NumberFormatException e) {
10730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = 0;
10740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = 0;
10750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
10760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
10780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * The formatting of the results returned by
10790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * wpa_supplicant is intended to make the fields
10800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * line up nicely when printed,
10810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * not to make them easy to parse. So we have to
10820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * apply some heuristics to figure out which field
10830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * is the SSID and which field is the flags.
10840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
10850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String ssid;
10860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String flags;
10870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (result.length == 4) {
10880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (result[3].charAt(0) == '[') {
10890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = result[3];
10900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = "";
10910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
10920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = "";
10930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = result[3];
10940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
10950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else if (result.length == 5) {
10960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = result[3];
10970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = result[4];
10980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
10990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Here, we must have 3 fields: no flags and ssid
11000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // set
11010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = "";
11020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = "";
11030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid + ssid is the hash key
11060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String key = bssid + ssid;
11070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    scanResult = mScanResultCache.get(key);
11080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.level = level;
11100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.SSID = ssid;
11110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.capabilities = flags;
11120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.frequency = frequency;
11130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Do not add scan results that have no SSID set
11150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (0 < ssid.trim().length()) {
11160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
11170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
11180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    ssid, bssid, flags, level, frequency);
11190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
11200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
11230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.w(TAG, "Misformatted scan result text with " +
11240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          result.length + " fields: " + line);
11250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return scanResult;
11300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
11330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * scanResults input format
11340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ee       2427    166     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net1
11350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ff       2412    165     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net2
11360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setScanResults(String scanResults) {
11380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (scanResults == null) {
11390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<ScanResult> scanList = new ArrayList<ScanResult>();
11430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int lineCount = 0;
11450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int scanResultsLen = scanResults.length();
11470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Parse the result string, keeping in mind that the last line does
11480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // not end with a newline.
11490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
11500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
11510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                ++lineCount;
11520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineCount == 1) {
11540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lineBeg = lineEnd + 1;
11550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    continue;
11560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineEnd > lineBeg) {
11580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String line = scanResults.substring(lineBeg, lineEnd);
11590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ScanResult scanResult = parseScanResult(line);
11600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanList.add(scanResult);
11620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
1163090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        //TODO: hidden network handling
11640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                lineBeg = lineEnd + 1;
11670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResults = scanList;
11710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1173cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    private String fetchSSID() {
1174cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String status = WifiNative.statusCommand();
1175cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        if (status == null) {
1176cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            return null;
1177cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1178cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        // extract ssid from a series of "name=value"
1179cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String[] lines = status.split("\n");
1180cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        for (String line : lines) {
1181cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String[] prop = line.split(" *= *");
1182cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (prop.length < 2) continue;
1183cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String name = prop[0];
1184cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String value = prop[1];
1185cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (name.equalsIgnoreCase("ssid")) return value;
1186cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1187cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        return null;
1188cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    }
1189cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff
119019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /*
119119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Fetch RSSI and linkspeed on current connection
119219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
119319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private void fetchRssiAndLinkSpeedNative() {
119419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newRssi = WifiNative.getRssiCommand();
119519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
119619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /* some implementations avoid negative values by adding 256
119719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * so we need to adjust for that here.
119819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
119919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newRssi > 0) newRssi -= 256;
120019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(newRssi);
120119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /*
120219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * Rather then sending the raw RSSI out every time it
120319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes, we precalculate the signal level that would
120419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * be displayed in the status bar, and only send the
120519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcast if that much more coarse-grained number
120619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes. This cuts down greatly on the number of
120719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcasts, at the cost of not mWifiInforming others
120819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * interested in RSSI of all the changes in signal
120919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * level.
121019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
121119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // TODO: The second arg to the call below needs to be a symbol somewhere, but
121219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // it's actually the size of an array of icons that's private
121319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // to StatusBar Policy.
121419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
121519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
121619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendRssiChangeBroadcast(newRssi);
121719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
121819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mLastSignalLevel = newSignalLevel;
121919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        } else {
122019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(-200);
122119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
122219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newLinkSpeed = WifiNative.getLinkSpeedCommand();
122319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newLinkSpeed != -1) {
122419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
122519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
122619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
122719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12285876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private void setHighPerfModeEnabledNative(boolean enable) {
12295876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
12305876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            Log.e(TAG, "set suspend optimizations failed!");
12315876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12325876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if (enable) {
12335876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
12345876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode active failed!");
12355876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12365876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        } else {
12375876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
12385876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode auto failed!");
12395876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12405876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12415876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    }
12425876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
124337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private void configureLinkProperties() {
124496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
124596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
124696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
124796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            // TODO - fix this for v6
124896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            synchronized (mDhcpInfo) {
124996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addLinkAddress(new LinkAddress(
125096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress),
125196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        NetworkUtils.intToInetAddress(mDhcpInfo.netmask)));
125296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
125396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
125496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
125596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
125696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
1257128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
125896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        mLinkProperties.setInterfaceName(mInterfaceName);
125996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        Log.d(TAG, "netId=" + mLastNetworkId  + " Link configured: " + mLinkProperties.toString());
12600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
12630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return Settings.Secure.getInt(mContext.getContentResolver(),
12640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
12650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
12660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
1269be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
1270be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1271be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        mContext.sendBroadcast(intent);
12720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
12750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
1276be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
12770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
12780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
12790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
12820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
12830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
12840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
128637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
12870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
12880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
12890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
12900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1292fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    private void sendErrorBroadcast(int errorCode) {
1293fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        Intent intent = new Intent(WifiManager.ERROR_ACTION);
1294fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1295fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.putExtra(WifiManager.EXTRA_ERROR_CODE, errorCode);
1296fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        mContext.sendBroadcast(intent);
1297fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1298fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1299be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void sendLinkConfigurationChangedBroadcast() {
1300be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
1301be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
130237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
13030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
13070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
1308be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
13100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
13150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param state the new @{code DetailedState}
13160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1317be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
13180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "setDetailed state, old ="
13190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                + mNetworkInfo.getDetailedState() + " and new state=" + state);
13200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
13210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkInfo.setDetailedState(state, null, null);
13220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1325be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private DetailedState getNetworkDetailedState() {
1326be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return mNetworkInfo.getDetailedState();
1327be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    }
1328be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
13290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
13310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
13320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
13340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "Reset connections and stopping DHCP");
13350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
13370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Reset connections & stop DHCP
13380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
13390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.resetConnections(mInterfaceName);
13400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!NetworkUtils.stopDhcp(mInterfaceName)) {
13420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Could not stop DHCP");
13430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Disable interface */
13460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.disableInterface(mInterfaceName);
13470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* send event to CM & network change broadcast */
1349be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        setNetworkDetailedState(DetailedState.DISCONNECTED);
13500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
13510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
13530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setIpAddress(0);
13540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
13550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
13560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setNetworkId(-1);
13570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
135937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
13600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
13620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
13630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
13680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Notifications from WifiMonitor
13690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
13700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1372b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff     * Stores supplicant state change information passed from WifiMonitor
13730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
137419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static class StateChangeResult {
1375b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff        StateChangeResult(int networkId, String BSSID, SupplicantState state) {
13760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.state = state;
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.BSSID = BSSID;
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.networkId = networkId;
13790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int networkId;
13810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String BSSID;
1382b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff        SupplicantState state;
13830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a user-entered password key
13870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * may be incorrect (i.e., caused authentication to fail).
13880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyPasswordKeyMayBeIncorrect() {
13900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1394fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     * Send a notification that the supplicant has detected overlapped
1395fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     * WPS sessions
1396fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     */
1397fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    void notifyWpsOverlap() {
1398fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        sendMessage(WPS_OVERLAP_EVENT);
1399fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1400fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1401fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /**
14020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a connection to the supplicant
14030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * daemon has been established.
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantConnection() {
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_CONNECTION_EVENT);
14070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
141068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * Send the tracker a notification that connection to the supplicant
141168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * daemon is lost
14120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantLost() {
14140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_DISCONNECTION_EVENT);
14150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of Wifi connectivity
14190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new network state
14220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param BSSID when the new state is {@link DetailedState#CONNECTED
14230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * NetworkInfo.DetailedState.CONNECTED},
14240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * this is the MAC address of the access point. Otherwise, it
14250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * is {@code null}.
14260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyNetworkStateChange(DetailedState newState, String BSSID, int networkId) {
14280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newState == NetworkInfo.DetailedState.CONNECTED) {
1429b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff            sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT, networkId, 0, BSSID));
14300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
1431b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff            sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT, networkId, 0, BSSID));
14320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of the supplicant
14370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new {@code SupplicantState}
14400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantStateChange(int networkId, String BSSID, SupplicantState newState) {
14420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
14430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                new StateChangeResult(networkId, BSSID, newState)));
14440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a scan has completed, and results
14480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * are available.
14490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyScanResultsAvailable() {
14510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
14520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Switch scan mode over to passive.
14530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Turning off scan-only mode happens only in "Connect" mode
14540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
14550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setScanType(false);
14560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SCAN_RESULTS_EVENT);
14570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStarted() {
14600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_START_EVENT);
14610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStopped() {
14640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_STOP_EVENT);
14650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverHung() {
14680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(false);
14690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(true);
14700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
14730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
14740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
14750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DefaultState extends HierarchicalState {
14770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
14780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
14790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
14800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
148165eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
148265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
148365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
1484cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
14850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
14860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
14870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
14880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
14890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
14904b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                case CMD_REMOVE_NETWORK:
14911406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_SAVE_CONFIG:
14921406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, FAILURE);
14934b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                    break;
14940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
14950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
149619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
14970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
14980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
14990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
15000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
15010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
15020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
15030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
15040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
15050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
1506e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
1507e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
1508e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
1509e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
15100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
15110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
15120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
15130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
15140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
15150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
15160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
15170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
15180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
1519fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
15200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
15245876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1525ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
152636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
15270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
1528e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
1529e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1530e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
153119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
15328e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
15330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
153402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
1535e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    /* Return failure when the state machine cannot handle WPS initiation*/
1536e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mReplyChannel.replyToMessage(message, message.what,
1537e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                                new WpsResult(Status.FAILURE));
153802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
15390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
15400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG, "Error! unhandled message" + message);
15410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
15420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
15440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class InitialState extends HierarchicalState {
15480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
15500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
15510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
15520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
15530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
15540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
15550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
15560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (WifiNative.isDriverLoaded()) {
15580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
15590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
15610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
15620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadingState extends HierarchicalState {
15670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
15690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
15700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
15710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
15730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
15740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
15750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
15760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
15770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
15780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
15794f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
15800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
15810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
15820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
15830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
15840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
15850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
15860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
15870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
15880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
15890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.loadDriver()) {
15910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver load successful");
15920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
15930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
15940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to load driver!");
15950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
15960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
15970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
15980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
15990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
16000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
16010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
16030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
16040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16054f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
16060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
16080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
16140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
16150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
16160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
16180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
16190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
16230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
16240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
16260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
16290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
16305876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1631ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
163236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
16330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
16340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
16360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
16380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
16390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
16410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
16420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadedState extends HierarchicalState {
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
16550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
16560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
16570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
16590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.startSupplicant()) {
16600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Supplicant start successful");
16610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
166296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mSupplicantStartingState);
16630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
16640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to start supplicant!");
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
16660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
16690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
16700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.startAccessPoint((WifiConfiguration) message.obj,
16710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
16720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
16730c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                    } catch (Exception e) {
16740c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        Log.e(TAG, "Exception in softap start " + e);
16750c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        try {
16760c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            nwService.stopAccessPoint();
16770c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            nwService.startAccessPoint((WifiConfiguration) message.obj,
16780c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    mInterfaceName,
16790c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    SOFTAP_IFACE);
16800c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        } catch (Exception ee) {
16810c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            Log.e(TAG, "Exception during softap restart : " + ee);
16820c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
16830c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            break;
16840c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        }
16850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Soft AP start successful");
16870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
16880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mSoftApStartedState);
16890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
16910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
16920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
16940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
16950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadingState extends HierarchicalState {
16990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
17020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
17050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
17060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
17070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
17080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17094f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
17100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.unloadDriver()) {
17110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver unload successful");
17120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
17180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
17220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
17250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to unload driver!");
17260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
17270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
17320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
17360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17394f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
17410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
17420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
17460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
17480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
17490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
17500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
17530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
17550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
17560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
17570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
17580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
17590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
17600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
17630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
17645876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1765ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
176636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
17670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
17680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
17690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
17700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadedState extends HierarchicalState {
17800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
17830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
17870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
17890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
17900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadingState);
17910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverFailedState extends HierarchicalState {
18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, getName() + "\n");
18040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
18100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
181496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStartingState extends HierarchicalState {
18150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
18240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
18250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Supplicant connection established");
1826b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_ENABLED);
182796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    mSupplicantRestartCount = 0;
1828b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    /* Reset the supplicant state to indicate the supplicant
1829b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                     * state is not known at this time */
1830b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1831e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
18320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
18330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
18340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = -1;
18350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
18360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
18380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
183904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.initialize(mContext);
18409e6222f4c126252c9950d072ab67d8b849d17643Irfan Sheriff
18410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //TODO: initialize and fix multicast filtering
18420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //mWM.initializeMulticastFiltering();
18430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
18454f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartedState);
18460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
184768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case SUP_DISCONNECTION_EVENT:
184896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
184996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        Log.e(TAG, "Failed to setup control channel, restart supplicant");
185096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        WifiNative.killSupplicant();
185196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
185296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
185396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    } else {
185496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        mSupplicantRestartCount = 0;
185596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        Log.e(TAG, "Failed " + mSupplicantRestartCount +
185696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                                " times to start supplicant, unload driver");
185796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
1858b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
185996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
18600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
186168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_LOAD_DRIVER:
186268825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_UNLOAD_DRIVER:
186368825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_START_SUPPLICANT:
186468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_SUPPLICANT:
18650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
186668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_AP:
18670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
18680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
18690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
18700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
18715876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1872ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
187336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
18740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
18750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
18760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
18770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
18790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
18800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
18820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
18830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
188696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStartedState extends HierarchicalState {
18870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
18920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
18936bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            /* Wifi is available as long as we have a connection to supplicant */
18946bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(true);
18950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
1899e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
19008e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
19010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
19020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
19035d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                    Log.d(TAG, "stopping supplicant");
19045d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                    if (!WifiNative.stopSupplicant()) {
19055d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                        Log.e(TAG, "Failed to stop supplicant, issue kill");
190696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        WifiNative.killSupplicant();
190796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
19086bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
190968825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    handleNetworkDisconnect();
1910b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_DISABLING);
191168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
1912b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1913e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
191496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mSupplicantStoppingState);
191568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    break;
191696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
191796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.e(TAG, "Connection lost, restart supplicant");
191896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    WifiNative.killSupplicant();
19190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.closeSupplicantConnection();
19206bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
19210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
19220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
1923b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1924e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
19250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
192696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
19270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
19298e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
19300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setScanResults(WifiNative.scanResultsCommand());
19310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendScanResultsAvailableBroadcast();
19320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
19341406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    boolean ok = WifiNative.pingCommand();
19351406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
19381406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    config = (WifiConfiguration) message.obj;
19391406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
19401406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                            WifiConfigStore.addOrUpdateNetwork(config));
19410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
19431406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.removeNetwork(message.arg1);
19441406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
19471406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
19481406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19508e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
19518e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    WifiConfigStore.enableAllNetworks();
19528e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    break;
19530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
19541406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.disableNetwork(message.arg1);
19551406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
19580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.addToBlacklistCommand((String)message.obj);
19590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
19610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.clearBlacklistCommand();
19620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
19641406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.saveConfig();
19651406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
19661406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
19670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
19680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
19700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
19710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
19720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
19730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
19740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
19750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
19760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
19770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
19790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
19800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
19810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
19820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
19840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
19850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
1986e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1987e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
198804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.saveNetwork(config);
1989e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
1990e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
199104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.forgetNetwork(message.arg1);
1992e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
19930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
19940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
19950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19968e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
19978e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19988e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
19990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20016bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff
20026bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        @Override
20036bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        public void exit() {
20046bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
20056bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        }
20060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
200896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStoppingState extends HierarchicalState {
200996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
201096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public void enter() {
201196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
201296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
201396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
201496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
201596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public boolean processMessage(Message message) {
201696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
201796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            switch(message.what) {
201896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_CONNECTION_EVENT:
201996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.e(TAG, "Supplicant connection received while stopping");
202096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
202196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
202296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.d(TAG, "Supplicant connection lost");
202396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    WifiNative.closeSupplicantConnection();
202496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mDriverLoadedState);
202596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
202696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_LOAD_DRIVER:
202796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_UNLOAD_DRIVER:
202896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_SUPPLICANT:
202996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_SUPPLICANT:
203096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_AP:
203196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_AP:
203296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_DRIVER:
203396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_DRIVER:
203496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_MODE:
203596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_TYPE:
203696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
203796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
203896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
203996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_PACKET_FILTERING:
204096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
204196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    deferMessage(message);
204296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
204396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                default:
204496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    return NOT_HANDLED;
204596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            }
204696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
204796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            return HANDLED;
204896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
204996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    }
205096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
20510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartingState extends HierarchicalState {
20520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
20590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
20600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
20610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
20620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStartedState);
20630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
20650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
20660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
20670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
20680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
20690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
20700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
2071fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
20720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
20735876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2074ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
207536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
20760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
20770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
20780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
20790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
20800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
20810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2082e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
20830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartedState extends HierarchicalState {
20930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
209803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = true;
209903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
21000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
210165eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            /**
210265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
210365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * When this mode is on, some of the low-level scan parameters used by the
210465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * driver are changed to reduce interference with bluetooth
210565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             */
210665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive);
2107ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            /* set country code */
2108ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode();
210936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            /* set frequency band of operation */
211036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            setFrequencyBand();
21113a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            /* initialize network state */
21123a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            setNetworkDetailedState(DetailedState.DISCONNECTED);
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
21150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.disconnectCommand();
21170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
21180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
21190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
21200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.reconnectCommand();
2121090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                transitionTo(mDisconnectedState);
21220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21278e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
21280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ACTIVE) {
21310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(true);
21320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(false);
21340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
213619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
21378e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
213819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
213919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
21405876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
21415876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    setHighPerfModeEnabledNative(message.arg1 == 1);
21420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2143ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
2144ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    String country = (String) message.obj;
2145ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Log.d(TAG, "set country code " + country);
2146ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) {
2147ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                        Log.e(TAG, "Failed to set country code " + country);
2148ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    }
21490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
215036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
215136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    int band =  message.arg1;
215236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Log.d(TAG, "set frequency band " + band);
215336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    if (WifiNative.setBandCommand(band)) {
215436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        mFrequencyBand.set(band);
2155cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        //Fetch the latest scan results when frequency band is set
2156cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        startScan(true);
215736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    } else {
215836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        Log.e(TAG, "Failed to set frequency band " + band);
215936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    }
216036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    break;
216165eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
216265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
216365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
216465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive);
216565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    break;
21660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21674f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
21680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopDriverCommand();
21690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppingState);
21704f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
21710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
21730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.startPacketFiltering();
21740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
21760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopPacketFiltering();
21770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21818e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
21828e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
21838e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
21840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
21880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
218903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = false;
219003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
2191f99819e47cbef2ec066a21b426c7e6fe95e3de48Irfan Sheriff            mScanResults = null;
21920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppingState extends HierarchicalState {
21960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
21990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
22060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppedState);
22070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
22090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
22100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
22125876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2213ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
221436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
22150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2221e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
22220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppedState extends HierarchicalState {
22320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22404f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            switch (message.what) {
22414f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                case CMD_START_DRIVER:
22424f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
22434f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    WifiNative.startDriverCommand();
22444f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartingState);
22454f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
22464f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    break;
22474f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                default:
22484f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    return NOT_HANDLED;
22494f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            }
22504f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22514f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            return HANDLED;
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ScanModeState extends HierarchicalState {
22560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
22670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
22680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
22710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.reconnectCommand();
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
22770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
22790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
22810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectModeState extends HierarchicalState {
22930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
23010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
23020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
23030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
230419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
23050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2306fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
2307fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    /* We just need to broadcast the error */
2308fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
2309fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    break;
23100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
23110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
2312b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    SupplicantState state = stateChangeResult.state;
231319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // Supplicant state change
231419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [31-13] Reserved for future use
231519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [8 - 0] Supplicant state (as defined in SupplicantState.java)
231619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // 50023 supplicant_state_changed (custom|1|5)
231719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
231819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setSupplicantState(state);
231919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
232019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (state == SupplicantState.ASSOCIATING) {
232119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        /* BSSID is valid only in ASSOCIATING state */
232219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mWifiInfo.setBSSID(stateChangeResult.BSSID);
232319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
232419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
232502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mSupplicantStateTracker.sendMessage(Message.obtain(message));
232602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
23270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
23290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2330e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
23310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2333e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reconnectCommand();
23340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
2336e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reassociateCommand();
23370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2338e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2339e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
2340e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
234104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
234204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* We connect to a specific network by issuing a select
234304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * to the WifiConfigStore. This enables the network,
234404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * while disabling all other networks in the supplicant.
234504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * Disabling a connected network will cause a disconnection
234604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * from the network. A reconnectCommand() will then initiate
234704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * a connection to the enabled network.
234804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     */
2349e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
235004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(config);
235104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    } else {
235204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(netId);
2353e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2354e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
23558e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    /* The state tracker handles enabling networks upon completion/failure */
23568e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_CONNECT_NETWORK);
235704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
2358a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    WifiNative.reconnectCommand();
235904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
236004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* Expect a disconnection from the old connection */
2361a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    transitionTo(mDisconnectingState);
2362e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
236302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
236402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
236502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mWaitForWpsCompletionState);
2366f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    break;
23670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
23680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
23690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
23700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
23710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
23730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection established");
2374b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastNetworkId = message.arg1;
2375b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastBssid = (String) message.obj;
23760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2377cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    //TODO: make supplicant modification to push this in events
2378cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    mWifiInfo.setSSID(fetchSSID());
2379b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid);
2380b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setNetworkId(mLastNetworkId);
23810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
2382be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
23830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
23840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
23850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
23870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection lost");
23880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
23890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
23900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
23920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
23940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
23950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
23960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectingState extends HierarchicalState {
240031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mModifiedBluetoothCoexistenceMode;
240131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        int mPowerMode;
240231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mUseStaticIp;
24030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Thread mDhcpThread;
24040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
24080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
240931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
24100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!mUseStaticIp) {
24110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = null;
241231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mModifiedBluetoothCoexistenceMode = false;
24135876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                mPowerMode = POWER_MODE_AUTO;
24140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
241565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                if (!mBluetoothConnectionActive) {
24160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
24170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * There are problems setting the Wi-Fi driver's power
24180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode to active when bluetooth coexistence mode is
24190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * enabled or sense.
24200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * We set Wi-Fi to active mode when
24220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address because we've found
24230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * compatibility issues with some routers with low power
24240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode.
24250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * In order for this active power mode to properly be set,
24270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * we disable coexistence mode until we're done with
24280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address.  One exception is if we
24290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * are currently connected to a headset, since disabling
24300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * coexistence would interrupt that connection.
24310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
243231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    mModifiedBluetoothCoexistenceMode = true;
24330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Disable the coexistence mode
24350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(
24360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
24370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
243931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mPowerMode =  WifiNative.getPowerModeCommand();
244031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (mPowerMode < 0) {
24410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Handle the case where supplicant driver does not support
24420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // getPowerModeCommand.
24435876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    mPowerMode = POWER_MODE_AUTO;
24440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24455876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                if (mPowerMode != POWER_MODE_ACTIVE) {
24465876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
24470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "DHCP request started");
24500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = new Thread(new Runnable() {
24510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    public void run() {
245231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        DhcpInfo dhcpInfo = new DhcpInfo();
245331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfo)) {
24540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request succeeded");
245531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            synchronized (mDhcpInfo) {
245631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                                mDhcpInfo = dhcpInfo;
245731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            }
24580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_SUCCESS);
24590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
24600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request failed: " +
24610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    NetworkUtils.getDhcpError());
24620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_FAILURE);
24630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
24640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
24650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                });
24660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread.start();
24670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
246831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                DhcpInfo dhcpInfo = WifiConfigStore.getIpConfiguration(mLastNetworkId);
246931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (NetworkUtils.configureInterface(mInterfaceName, dhcpInfo)) {
24700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration succeeded");
247131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    synchronized (mDhcpInfo) {
247231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        mDhcpInfo = dhcpInfo;
247331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    }
24740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_SUCCESS);
24750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
24760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration failed");
24770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_FAILURE);
24780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         }
24810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
24820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public boolean processMessage(Message message) {
24830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
24840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          switch(message.what) {
24860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_SUCCESS:
24870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mLastSignalLevel = -1; // force update of signal strength
248831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  synchronized (mDhcpInfo) {
248931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                      mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
249031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  }
249137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                  configureLinkProperties();
2492be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  if (getNetworkDetailedState() == DetailedState.CONNECTED) {
2493be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendLinkConfigurationChangedBroadcast();
2494be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  } else {
2495be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      setNetworkDetailedState(DetailedState.CONNECTED);
2496be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendNetworkStateChangeBroadcast(mLastBssid);
2497be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  }
249831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //TODO: The framework is not detecting a DHCP renewal and a possible
249931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //IP change. we should detect this and send out a config change broadcast
25000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mConnectedState);
25010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_FAILURE:
25030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mWifiInfo.setIpAddress(0);
25040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  Log.e(TAG, "IP configuration failed");
25060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /**
25070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * If we've exceeded the maximum number of retries for DHCP
25080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * to a given network, disable the network
25090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (++mReconnectCount > getMaxDhcpRetries()) {
251168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      Log.e(TAG, "Failed " +
251268825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                              mReconnectCount + " times, Disabling " + mLastNetworkId);
251304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                      WifiConfigStore.disableNetwork(mLastNetworkId);
251468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      mReconnectCount = 0;
25150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* DHCP times out after about 30 seconds, we do a
25180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * disconnect and an immediate reconnect to try again
25190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.disconnectCommand();
25210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.reconnectCommand();
25220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_DISCONNECT:
2525e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                  WifiNative.disconnectCommand();
25260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
2528a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  /* Ignore connection to same network */
2529a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff              case CMD_CONNECT_NETWORK:
2530a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  int netId = message.arg1;
2531a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  if (mWifiInfo.getNetworkId() == netId) {
2532a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                      break;
2533a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  }
2534a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  return NOT_HANDLED;
2535be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff              case CMD_SAVE_NETWORK:
2536be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  deferMessage(message);
2537be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  break;
25380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* Ignore */
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case NETWORK_CONNECTION_EVENT:
25400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_STOP_DRIVER:
25420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  sendMessage(CMD_DISCONNECT);
25430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  deferMessage(message);
25440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_SET_SCAN_MODE:
25460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (message.arg1 == SCAN_ONLY_MODE) {
25470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendMessage(CMD_DISCONNECT);
25480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      deferMessage(message);
25490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
255119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  /* Defer scan when IP is being fetched */
255219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff              case CMD_START_SCAN:
255319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  deferMessage(message);
255419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  break;
25555876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  /* Defer any power mode changes since we must keep active power mode at DHCP */
25565876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              case CMD_SET_HIGH_PERF_MODE:
25575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  deferMessage(message);
25585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  break;
25590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              default:
25600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return NOT_HANDLED;
25610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
25620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          return HANDLED;
25640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
25650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
25670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public void exit() {
25680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          /* reset power state & bluetooth coexistence if on DHCP */
25690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (!mUseStaticIp) {
25705876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              if (mPowerMode != POWER_MODE_ACTIVE) {
257131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  WifiNative.setPowerModeCommand(mPowerMode);
25720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
25730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
257431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff              if (mModifiedBluetoothCoexistenceMode) {
25750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Set the coexistence mode back to its default value
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.setBluetoothCoexistenceModeCommand(
25770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
25780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
25790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
25800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
25820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
25830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectedState extends HierarchicalState {
25850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
25860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
25870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
25880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
258919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mRssiPollToken++;
259019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (mEnableRssiPolling) {
259119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendMessage(obtainMessage(WifiStateMachine.CMD_RSSI_POLL, mRssiPollToken, 0));
259219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
25930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
25940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
25950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
25960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
25978e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
25980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
25990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2600e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
26010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
26020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
26040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_DISCONNECT);
26050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
26060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26079beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
26089beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    if (mCm == null) {
26099beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                        mCm = (ConnectivityManager)mContext.getSystemService(
26109beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                                Context.CONNECTIVITY_SERVICE);
26119beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    }
26129beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    mCm.requestNetworkTransitionWakelock(TAG);
26139beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    break;
26140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
26150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
26160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
26170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
26180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
26190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
262019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
26218e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
262219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* When the network is connected, re-scanning can trigger
262319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * a reconnection. Put it in scan-only mode during scan.
262419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * When scan results are received, the mode is switched
262519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * back to CONNECT_MODE.
262619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     */
262719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
262819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
262919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
2630a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Ignore connection to same network */
2631a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                case CMD_CONNECT_NETWORK:
2632a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    int netId = message.arg1;
2633a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    if (mWifiInfo.getNetworkId() == netId) {
2634a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                        break;
2635a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    }
2636a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    return NOT_HANDLED;
2637be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                case CMD_SAVE_NETWORK:
2638be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
2639be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
2640be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
2641be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasIpChanged()) {
2642be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring IP on connection");
2643be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            NetworkUtils.resetConnections(mInterfaceName);
2644be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            transitionTo(mConnectingState);
2645be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2646be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasProxyChanged()) {
2647be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring proxy on connection");
2648be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            configureLinkProperties();
2649be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            sendLinkConfigurationChangedBroadcast();
2650be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2651be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    }
2652be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    break;
26530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
26540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
26550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
265619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
26578e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
265819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (message.arg1 == mRssiPollToken) {
265919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Get Info and continue polling
266019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
266119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
266219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
266319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    } else {
266419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Polling has completed
266519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
266619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
266719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_ENABLE_RSSI_POLL:
266819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
266919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mRssiPollToken++;
267019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (mEnableRssiPolling) {
267119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // first poll
267219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
267319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
267419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
267519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
267619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
26770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
26780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
26790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
26808e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
26818e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
26828e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
26830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
26840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectingState extends HierarchicalState {
26880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
26910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
26920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
26960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
26970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
26980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
26990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
27030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
270519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* Handle in  DisconnectedState */
270619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
270719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    deferMessage(message);
270819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectedState extends HierarchicalState {
27180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
2722090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2723090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            /**
2724090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * In a disconnected state, an infrequent scan that wakes
2725090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * up the device is needed to ensure a user connects to
2726090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * an access point on the move
2727090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             */
2728090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
2729090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
2730090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2731090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
2732090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
27330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
27380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
27410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
27420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.disconnectCommand();
27430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
27440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
27450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
27480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
27490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
275019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
275119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
2752b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
275319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* DriverStartedState does the rest of the handling */
275419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    return NOT_HANDLED;
27550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
2761090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2762090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        @Override
2763090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        public void exit() {
2764090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.cancel(mScanIntent);
2765090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        }
27660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
276802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    class WaitForWpsCompletionState extends HierarchicalState {
276902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
277002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public void enter() {
277102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
277202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
277302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
277402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
277502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public boolean processMessage(Message message) {
277602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
277702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            switch (message.what) {
277802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                /* Defer all commands that can cause connections to a different network
277902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 * or put the state machine out of connect mode
278002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 */
278102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_STOP_DRIVER:
278202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_SET_SCAN_MODE:
278302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_CONNECT_NETWORK:
278402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_ENABLE_NETWORK:
278502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_RECONNECT:
278602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_REASSOCIATE:
278702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case NETWORK_CONNECTION_EVENT: /* Handled after IP & proxy update */
278802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    deferMessage(message);
278902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
279002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
279102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    Log.d(TAG,"Network connection lost");
279202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    handleNetworkDisconnect();
279302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
279402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case WPS_COMPLETED_EVENT:
279502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    /* we are still disconnected until we see a network connection
279602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                     * notification */
279702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mDisconnectedState);
279802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
279902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                default:
280002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    return NOT_HANDLED;
280102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            }
280202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
280302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            return HANDLED;
280402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
280502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    }
280602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
28070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SoftApStartedState extends HierarchicalState {
28080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
28170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
28180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Stopping Soft AP");
28190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
28200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.stopAccessPoint();
28220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in stopAccessPoint()");
28240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
28260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
28280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"SoftAP set on a running access point");
28290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.setAccessPoint((WifiConfiguration) message.obj,
28310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
28320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
28330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28340c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                        Log.e(TAG, "Exception in softap set " + e);
28350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
28360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            nwService.stopAccessPoint();
28370c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            nwService.startAccessPoint((WifiConfiguration) message.obj,
28380c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    mInterfaceName,
28390c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                                    SOFTAP_IFACE);
28400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception ee) {
28410c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            Log.e(TAG, "Could not restart softap after set failed " + ee);
28420c7e16450c9060551bd0bea6e08bc9fb2ba411b4Irfan Sheriff                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
28430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
28440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* Fail client mode operation when soft AP is enabled */
28470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
28480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG,"Cannot start supplicant with a running soft AP");
28490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
28500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
2859