WifiStateMachine.java revision fcb659b66756ac02bd1491ae1365b27e8509a890
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.util.Slog;
650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.backup.IBackupManager;
667440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
67090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.content.BroadcastReceiver;
680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Intent;
690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Context;
70090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.content.IntentFilter;
71090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.app.IBatteryStats;
734b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Savilleimport com.android.internal.util.AsyncChannel;
740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalState;
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalStateMachine;
760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff
780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.ArrayList;
790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.LinkedHashMap;
800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.List;
810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.Map;
820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.concurrent.atomic.AtomicInteger;
830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.regex.Pattern;
840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Track the state of Wifi connectivity. All event handling is done here,
870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and all changes in connectivity state are initiated here.
880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @hide
900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpublic class WifiStateMachine extends HierarchicalStateMachine {
920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String TAG = "WifiStateMachine";
940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String NETWORKTYPE = "WIFI";
950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final boolean DBG = false;
960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* TODO: fetch a configurable interface */
980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String SOFTAP_IFACE = "wl0.1";
990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiMonitor mWifiMonitor;
1010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private INetworkManagementService nwService;
1020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ConnectivityManager mCm;
1030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results handling */
1050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private List<ScanResult> mScanResults;
1060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final Pattern scanResultPattern = Pattern.compile("\t+");
1070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULT_CACHE_SIZE = 80;
1080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final LinkedHashMap<String, ScanResult> mScanResultCache;
1090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mInterfaceName;
1110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastSignalLevel = -1;
1130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mLastBssid;
1140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastNetworkId;
1150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mEnableRssiPolling = false;
11619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private int mRssiPollToken = 0;
1170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mReconnectCount = 0;
1180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mIsScanMode = false;
1190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    private boolean mBluetoothConnectionActive = false;
12165eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff
1220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
12319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Interval in milliseconds between polling for RSSI
12419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * and linkspeed information
12519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
12619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
12719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /**
12996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Delay between supplicant restarts upon failure to establish connection
13096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
13196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;
13296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
13396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /**
13496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Number of times we attempt to restart supplicant
13596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
13696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_TRIES = 5;
13796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
13896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private int mSupplicantRestartCount = 0;
13996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
14037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private LinkProperties mLinkProperties;
1410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1424f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    // Wakelock held during wifi start/stop and driver load/unload
1434f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    private PowerManager.WakeLock mWakeLock;
1440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private Context mContext;
1460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private DhcpInfo mDhcpInfo;
1480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiInfo mWifiInfo;
1490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkInfo mNetworkInfo;
1500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SupplicantStateTracker mSupplicantStateTracker;
15102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    private WpsStateMachine mWpsStateMachine;
15202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
153090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private AlarmManager mAlarmManager;
154090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private PendingIntent mScanIntent;
15536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Tracks current frequency mode */
15636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
157090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
1584b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    // Channel for sending replies.
1594b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    private AsyncChannel mReplyChannel = new AsyncChannel();
1604b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
1610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Event log tags (must be in sync with event-log-tags)
1620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
1630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
1640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED  = 50023;
1650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Load the driver */
16719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER                      = 1;
1680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unload the driver */
16919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER                    = 2;
1700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load succeeded */
17119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER_SUCCESS              = 3;
1720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load failed */
17319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_LOAD_DRIVER_FAILURE              = 4;
1740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload succeeded */
17519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER_SUCCESS            = 5;
1760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload failed */
17719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_UNLOAD_DRIVER_FAILURE            = 6;
1780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the supplicant */
18019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_SUPPLICANT                 = 11;
1810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the supplicant */
18219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_SUPPLICANT                  = 12;
1830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
18419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_DRIVER                     = 13;
1850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
18619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_DRIVER                      = 14;
1870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP succeded */
18819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_IP_CONFIG_SUCCESS                = 15;
1890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP failed */
19019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_IP_CONFIG_FAILURE                = 16;
1910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the soft access point */
19319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_AP                         = 21;
1940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the soft access point */
19519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_AP                          = 22;
1960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = 23;
1980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant events */
2000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant established */
20119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUP_CONNECTION_EVENT                 = 31;
2020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant lost */
20319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUP_DISCONNECTION_EVENT              = 32;
2040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start completed */
20519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int DRIVER_START_EVENT                   = 33;
2060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stop completed */
20719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int DRIVER_STOP_EVENT                    = 34;
2080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network connection completed */
20919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int NETWORK_CONNECTION_EVENT             = 36;
2100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network disconnection completed */
21119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int NETWORK_DISCONNECTION_EVENT          = 37;
2120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results are available */
21319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SCAN_RESULTS_EVENT                   = 38;
2140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicate state changed */
21519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
2160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Password may be incorrect */
21719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
218fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /* WPS overlap detected */
219fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    static final int WPS_OVERLAP_EVENT                    = 41;
220fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
2210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands */
2230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Is supplicant alive ? */
22419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_PING_SUPPLICANT                  = 51;
2250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Add/update a network configuration */
22619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ADD_OR_UPDATE_NETWORK            = 52;
2270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Delete a network */
22819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REMOVE_NETWORK                   = 53;
2290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable a network. The device will attempt a connection to the given network. */
23019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ENABLE_NETWORK                   = 54;
2318e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    /* Enable all networks */
2328e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_ENABLE_ALL_NETWORKS              = 55;
2330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disable a network. The device does not attempt a connection to the given network. */
2348e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_DISABLE_NETWORK                  = 56;
2350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Blacklist network. De-prioritizes the given BSSID for connection. */
2368e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_BLACKLIST_NETWORK                = 57;
2370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear the blacklist network list */
2388e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_CLEAR_BLACKLIST                  = 58;
2390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Save configuration */
2408e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    static final int CMD_SAVE_CONFIG                      = 59;
2410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands after driver start*/
2430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Initiate a scan */
24419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_SCAN                       = 71;
2450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
24619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_SCAN_MODE                    = 72;
2470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
24819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_SCAN_TYPE                    = 73;
2490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disconnect from a network */
25019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_DISCONNECT                       = 74;
2510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reconnect to a network */
25219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_RECONNECT                        = 75;
2530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reassociate to a network */
25419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REASSOCIATE                      = 76;
2555876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    /* Controls power mode and suspend mode optimizations
2565876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
2575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * When high perf mode is enabled, power mode is set to
2585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * POWER_MODE_ACTIVE and suspend mode optimizations are disabled
2595876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
2605876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * When high perf mode is disabled, power mode is set to
2615876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * POWER_MODE_AUTO and suspend mode optimizations are enabled
2625876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
2635876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Suspend mode optimizations include:
2645876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - packet filtering
2655876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - turn off roaming
2665876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - DTIM wake up settings
2670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
26819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_HIGH_PERF_MODE               = 77;
269ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /* Set the country code */
27019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SET_COUNTRY_CODE                 = 80;
2710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Request connectivity manager wake lock before driver stop */
27219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_REQUEST_CM_WAKELOCK              = 81;
2730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enables RSSI poll */
27419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_ENABLE_RSSI_POLL                 = 82;
2750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* RSSI poll */
27619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_RSSI_POLL                        = 83;
2770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set up packet filtering */
27819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_START_PACKET_FILTERING           = 84;
2790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear packet filter */
28019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_STOP_PACKET_FILTERING            = 85;
281e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Connect to a specified network (network id
282e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * or WifiConfiguration) This involves increasing
283e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * the priority of the network, enabling the network
284e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * (while disabling others) and issuing a reconnect.
285e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * Note that CMD_RECONNECT just does a reconnect to
286e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an existing network. All the networks get enabled
287e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * upon a successful connection or a failure.
288e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
28919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_CONNECT_NETWORK                  = 86;
290e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Save the specified network. This involves adding
291e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an enabled network (if new) and updating the
292e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * config and issuing a save on supplicant config.
293e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
29419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_SAVE_NETWORK                     = 87;
295e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Delete the specified network. This involves
296e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * removing the network and issuing a save on
297e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * supplicant config.
298e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
29919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static final int CMD_FORGET_NETWORK                   = 88;
30002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Start Wi-Fi protected setup */
30102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    static final int CMD_START_WPS                        = 89;
30236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Set the frequency band */
30302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    static final int CMD_SET_FREQUENCY_BAND               = 90;
304ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
305b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Commands from/to the SupplicantStateTracker */
306b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Reset the supplicant state tracker */
3076bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff    static final int CMD_RESET_SUPPLICANT_STATE           = 111;
308b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff
30902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Commands/events reported by WpsStateMachine */
31002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Indicates the completion of WPS activity */
311b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    static final int WPS_COMPLETED_EVENT                  = 121;
312e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    /* Reset the WPS state machine */
313e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    static final int CMD_RESET_WPS_STATE                  = 122;
31402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
3150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CONNECT_MODE   = 1;
3160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ONLY_MODE = 2;
3170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ACTIVE = 1;
3190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_PASSIVE = 2;
3200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3211406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int SUCCESS = 1;
3221406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int FAILURE = -1;
3231406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
3240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * The maximum number of times we will retry a connection to an access point
3260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * for which we have failed in acquiring an IP address from DHCP. A value of
3270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * N means that we will make N+1 connection attempts in all.
3280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * <p>
3290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
3300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * value if a Settings value is not present.
3310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
3330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3345876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private static final int POWER_MODE_ACTIVE = 1;
3355876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private static final int POWER_MODE_AUTO = 0;
3360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
337090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    /**
338090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
339090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     * Settings.Secure value is not present.
340090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     */
341090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
342090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
3430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Default parent state */
3440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDefaultState = new DefaultState();
3450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Temporary initial state */
3460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mInitialState = new InitialState();
3470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unloading the driver */
3480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadingState = new DriverUnloadingState();
3490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Loading the driver */
3500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadedState = new DriverUnloadedState();
3510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver load/unload failed */
3520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverFailedState = new DriverFailedState();
3530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loading */
3540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadingState = new DriverLoadingState();
3550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded */
3560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadedState = new DriverLoadedState();
3570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded, waiting for supplicant to start */
35896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private HierarchicalState mSupplicantStartingState = new SupplicantStartingState();
3590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded and supplicant ready */
36096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private HierarchicalState mSupplicantStartedState = new SupplicantStartedState();
36196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /* Waiting for supplicant to stop and monitor to exit */
36296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private HierarchicalState mSupplicantStoppingState = new SupplicantStoppingState();
3630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start issued, waiting for completed event */
3640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartingState = new DriverStartingState();
3650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver started */
3660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartedState = new DriverStartedState();
3670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopping */
3680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppingState = new DriverStoppingState();
3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopped */
3700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppedState = new DriverStoppedState();
3710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan for networks, no connection will be established */
3720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mScanModeState = new ScanModeState();
3730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connecting to an access point */
3740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectModeState = new ConnectModeState();
3750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Fetching IP after network connection (assoc+auth complete) */
3760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectingState = new ConnectingState();
3770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connected with IP addr */
3780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectedState = new ConnectedState();
3790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* disconnect issued, waiting for network disconnect confirmation */
3800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectingState = new DisconnectingState();
3810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network is not connected, supplicant assoc+auth is not complete */
3820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectedState = new DisconnectedState();
38302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Waiting for WPS to be completed*/
38402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    private HierarchicalState mWaitForWpsCompletionState = new WaitForWpsCompletionState();
3850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Soft Ap is running */
3870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mSoftApStartedState = new SoftApStartedState();
3880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
3920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_DISABLING},
3930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLED},
3940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLING},
3950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
3960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
3970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
3990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
4010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
4020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
4030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
4040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
4050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
4060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
4070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
4080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
4090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastEnableUid = new AtomicInteger(Process.myUid());
4110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastApEnableUid = new AtomicInteger(Process.myUid());
4120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
413090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final int SCAN_REQUEST = 0;
414090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final String ACTION_START_SCAN =
415090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        "com.android.server.WifiManager.action.START_SCAN";
416090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
41703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
41803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether WIFI is running.
41903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
42003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mIsRunning = false;
4215ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
42203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
42303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether we last told the battery stats we had started.
42403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
42503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mReportedRunning = false;
42603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
42703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
42803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Most recently set source of starting WIFI.
42903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
43003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mRunningWifiUids = new WorkSource();
43103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
43203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
43303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * The last reported UIDs that were responsible for starting WIFI.
43403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
43503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mLastRunningWifiUids = new WorkSource();
43603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
4370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final IBatteryStats mBatteryStats;
4380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public WifiStateMachine(Context context) {
4400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        super(TAG);
4410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext = context;
4430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
4450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
4460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
4480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        nwService = INetworkManagementService.Stub.asInterface(b);
4490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiMonitor = new WifiMonitor(this);
4510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mDhcpInfo = new DhcpInfo();
4520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo = new WifiInfo();
4530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
45419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
45502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
45637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties = new LinkProperties();
4570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo.setIsAvailable(false);
45937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
4600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid = null;
4610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
4620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastSignalLevel = -1;
4630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
464090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
465090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        Intent scanIntent = new Intent(ACTION_START_SCAN, null);
466090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
467090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
468090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mContext.registerReceiver(
469090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new BroadcastReceiver() {
470090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    @Override
471090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    public void onReceive(Context context, Intent intent) {
472090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        startScan(false);
473090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    }
474090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                },
475090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new IntentFilter(ACTION_START_SCAN));
476090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
4770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResultCache = new LinkedHashMap<String, ScanResult>(
4780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SCAN_RESULT_CACHE_SIZE, 0.75f, true) {
4790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /*
4800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * Limit the cache size by SCAN_RESULT_CACHE_SIZE
4810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * elements
4820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 */
4830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                @Override
4840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public boolean removeEldestEntry(Map.Entry eldest) {
4850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return SCAN_RESULT_CACHE_SIZE < this.size();
4860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
4870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        };
4880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
4904f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
4910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
4930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
4940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
4950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
4960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
4970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
4980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
49996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartingState, mDefaultState);
50096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartedState, mDefaultState);
50196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartingState, mSupplicantStartedState);
50296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartedState, mSupplicantStartedState);
5030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
5040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
5050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectingState, mConnectModeState);
5060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectedState, mConnectModeState);
5070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
5080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
50902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                        addState(mWaitForWpsCompletionState, mConnectModeState);
51096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppingState, mSupplicantStartedState);
51196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppedState, mSupplicantStartedState);
51296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStoppingState, mDefaultState);
5130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
5140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
5210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
5240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
5250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
5260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5301406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncPingSupplicant(AsyncChannel channel) {
5311406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
5321406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
5331406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
5341406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
5350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
540e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
541e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
542e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
5430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
5490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
5500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
5530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
5540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
5560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
5580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
5650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
5660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
5690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
5700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
5720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
5740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
580d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiState() {
5810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
5820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
587d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiStateByName() {
5880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
5890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
5900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
5910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
5920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
5930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
5940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
5950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
5960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
5970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
5980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
5990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
607d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiApState() {
6080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
6090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
614d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiApStateByName() {
6150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
6160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
6170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
6180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
6190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
6200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
6210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
6220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
6230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
6240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
6250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
6260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
6270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
6280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
6330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
6340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
636d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public WifiInfo syncRequestConnectionInfo() {
6370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
6380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
640d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public DhcpInfo syncGetDhcpInfo() {
64131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        synchronized (mDhcpInfo) {
64231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            return new DhcpInfo(mDhcpInfo);
64331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
6440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setDriverStart(boolean enable) {
6504f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        if (enable) {
6514f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_START_DRIVER);
6524f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        } else {
6534f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_STOP_DRIVER);
6544f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        }
6550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
6610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
6620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
6630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
6650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
6720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
6730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
6740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
6760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
682d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<ScanResult> syncGetScanResultsList() {
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mScanResults;
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
6880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
689e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
690e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
6950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
696e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
697e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
6980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
7020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
703e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
704e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
7050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
7090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
7110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7121406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
7131406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
7141406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        int result = resultMsg.arg1;
7151406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7161406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
719d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<WifiConfiguration> syncGetConfiguredNetworks() {
72004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return WifiConfigStore.getConfiguredNetworks();
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
7250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
7270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7284b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
7294b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
7301406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7314b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        resultMsg.recycle();
7324b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        return result;
7334b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    }
7344b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
7354b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    /**
7360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
7370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
7400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7421406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
7431406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
7441406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                disableOthers ? 1 : 0);
7451406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7461406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7471406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
7520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7561406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
7571406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId);
7581406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7591406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7601406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
7660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
7680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
7700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
781e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(int netId) {
782e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, netId, 0));
783e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
784e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
785e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(WifiConfiguration wifiConfig) {
786a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        /* arg1 is used to indicate netId, force a netId value of -1 when
787a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * we are passing a configuration since the default value of
788a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         * 0 is a valid netId
789a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         */
790a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, -1, 0, wifiConfig));
791e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
792e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
793e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void saveNetwork(WifiConfiguration wifiConfig) {
794e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_SAVE_NETWORK, wifiConfig));
795e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
796e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
797e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void forgetNetwork(int netId) {
798e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
799e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
800e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
801e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) {
802e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        WpsResult result;
80302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        switch (config.setup) {
80402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            case PIN_FROM_DEVICE:
805e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            case PBC:
806e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            case PIN_FROM_ACCESS_POINT:
80702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                //TODO: will go away with AsyncChannel use from settings
80802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
809e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                result = (WpsResult) resultMsg.obj;
81002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                resultMsg.recycle();
81102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                break;
812e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            default:
813e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                result = new WpsResult(Status.FAILURE);
81402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                break;
81502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
816f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        return result;
8175ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
8185ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
8190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
8200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
8210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8238e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    public void enableAllNetworks() {
8248e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        sendMessage(CMD_ENABLE_ALL_NETWORKS);
8258e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    }
8268e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff
8270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Start packet filtering
8290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void startPacketFiltering() {
8310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_START_PACKET_FILTERING);
8320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Stop packet filtering
8360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void stopPacketFiltering() {
8380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_STOP_PACKET_FILTERING);
8390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8425876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Set high performance mode of operation.
8435876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Enabling would set active power mode and disable suspend optimizations;
8445876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * disabling would set auto power mode and enable suspend optimizations
8455876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * @param enable true if enable, false otherwise
8460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8475876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    public void setHighPerfModeEnabled(boolean enable) {
8485876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
8490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
852ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code
853ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param countryCode following ISO 3166 format
854ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
8550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
856ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    public void setCountryCode(String countryCode, boolean persist) {
857ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (persist) {
858ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            Settings.Secure.putString(mContext.getContentResolver(),
859ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Settings.Secure.WIFI_COUNTRY_CODE,
860ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    countryCode);
8610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
862ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_COUNTRY_CODE, countryCode));
8630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
86636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the operational frequency band
86736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param band
86836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
86936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
87036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public void setFrequencyBand(int band, boolean persist) {
87136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        if (persist) {
87236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            Settings.Secure.putInt(mContext.getContentResolver(),
87336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Settings.Secure.WIFI_FREQUENCY_BAND,
87436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    band);
87536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        }
87636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_FREQUENCY_BAND, band, 0));
87736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
87836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
87936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
88036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Returns the operational frequency band
88136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
88236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public int getFrequencyBand() {
88336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        return mFrequencyBand.get();
88436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
88536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
88636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
88765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff     * Send a message indicating bluetooth adapter connection state changed
8880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
88965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    public void sendBluetoothAdapterStateChange(int state) {
89065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff        sendMessage(obtainMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0));
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
8990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9001406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncSaveConfig(AsyncChannel channel) {
9011406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
9021406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9031406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9041406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9089beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * Request a wakelock with connectivity service to
9099beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * keep the device awake until we hand-off from wifi
9109beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff     * to an alternate network
9110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void requestCmWakeLock() {
9130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_REQUEST_CM_WAKELOCK);
9140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
91603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    public void updateBatteryWorkSource(WorkSource newSource) {
91703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        synchronized (mRunningWifiUids) {
91803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            try {
91903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (newSource != null) {
92003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    mRunningWifiUids.set(newSource);
92103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
92203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (mIsRunning) {
92303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
92403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // If the work source has changed since last time, need
92503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // to remove old work from battery stats.
92603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
92703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
92803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                                    mRunningWifiUids);
92903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mLastRunningWifiUids.set(mRunningWifiUids);
93003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        }
93103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    } else {
93203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Now being started, report it.
93303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
93403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.set(mRunningWifiUids);
93503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = true;
93603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
93703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                } else {
93803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
93903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Last reported we were running, time to stop.
94003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
94103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.clear();
94203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = false;
94303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
94403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
9454f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                mWakeLock.setWorkSource(newSource);
94603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            } catch (RemoteException ignore) {
94703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            }
94803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        }
94903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    }
95003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
951bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    @Override
952bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    public String toString() {
953bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        StringBuffer sb = new StringBuffer();
954bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        String LS = System.getProperty("line.separator");
955bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
95637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
957bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
958bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mDhcpInfo ").append(mDhcpInfo).append(LS);
959bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
960bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
961bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastBssid ").append(mLastBssid).append(LS);
962bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
963bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
964bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
965bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("Supplicant status").append(LS)
966bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff                .append(WifiNative.statusCommand()).append(LS).append(LS);
96704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
96804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        sb.append(WifiConfigStore.dump());
969bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        return sb.toString();
970bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    }
971bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff
9720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
9730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
9740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
9750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
976ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /**
977ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code from the system setting value, if any.
978ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     */
979ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    private void setCountryCode() {
980ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        String countryCode = Settings.Secure.getString(mContext.getContentResolver(),
981ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                Settings.Secure.WIFI_COUNTRY_CODE);
982ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (countryCode != null && !countryCode.isEmpty()) {
983ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode(countryCode, false);
984ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        } else {
985ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            //use driver default
986ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        }
987ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    }
988ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
98936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
99036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the frequency band from the system setting value, if any.
99136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
99236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private void setFrequencyBand() {
99336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        int band = Settings.Secure.getInt(mContext.getContentResolver(),
99436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                Settings.Secure.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
99536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        setFrequencyBand(band, false);
99636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
99736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
9980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
9990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
10000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
100303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
100503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Failed to note battery stats in wifi");
10090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
10120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1013d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiState: " + syncGetWifiStateByName());
10140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
10160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
10180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
10190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
10230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
10240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
102703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
10280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
102903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
10300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.d(TAG, "Failed to note battery stats in wifi");
10330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
10360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
10370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1038d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff        if (DBG) Log.d(TAG, "setWifiApState: " + syncGetWifiApStateByName());
10390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
10410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
10430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
10440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Parse the scan result line passed to us by wpa_supplicant (helper).
10490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param line the line to parse
10500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return the {@link ScanResult} object
10510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ScanResult parseScanResult(String line) {
10530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        ScanResult scanResult = null;
10540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (line != null) {
10550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
10560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Cache implementation (LinkedHashMap) is not synchronized, thus,
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * must synchronized here!
10580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
10590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized (mScanResultCache) {
10600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String[] result = scanResultPattern.split(line);
10610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (3 <= result.length && result.length <= 5) {
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String bssid = result[0];
10630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid | frequency | level | flags | ssid
10640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int frequency;
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int level;
10660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
10670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = Integer.parseInt(result[1]);
10680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = Integer.parseInt(result[2]);
10690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
10700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
10720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
10730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch (NumberFormatException e) {
10740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = 0;
10750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = 0;
10760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
10770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
10790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * The formatting of the results returned by
10800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * wpa_supplicant is intended to make the fields
10810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * line up nicely when printed,
10820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * not to make them easy to parse. So we have to
10830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * apply some heuristics to figure out which field
10840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * is the SSID and which field is the flags.
10850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
10860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String ssid;
10870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String flags;
10880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (result.length == 4) {
10890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (result[3].charAt(0) == '[') {
10900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = result[3];
10910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = "";
10920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
10930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = "";
10940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = result[3];
10950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
10960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else if (result.length == 5) {
10970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = result[3];
10980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = result[4];
10990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Here, we must have 3 fields: no flags and ssid
11010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // set
11020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = "";
11030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = "";
11040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid + ssid is the hash key
11070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String key = bssid + ssid;
11080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    scanResult = mScanResultCache.get(key);
11090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.level = level;
11110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.SSID = ssid;
11120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.capabilities = flags;
11130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.frequency = frequency;
11140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Do not add scan results that have no SSID set
11160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (0 < ssid.trim().length()) {
11170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
11180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
11190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    ssid, bssid, flags, level, frequency);
11200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
11210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
11240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.w(TAG, "Misformatted scan result text with " +
11250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          result.length + " fields: " + line);
11260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return scanResult;
11310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
11340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * scanResults input format
11350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ee       2427    166     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net1
11360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ff       2412    165     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net2
11370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setScanResults(String scanResults) {
11390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (scanResults == null) {
11400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<ScanResult> scanList = new ArrayList<ScanResult>();
11440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int lineCount = 0;
11460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int scanResultsLen = scanResults.length();
11480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Parse the result string, keeping in mind that the last line does
11490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // not end with a newline.
11500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
11510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
11520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                ++lineCount;
11530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineCount == 1) {
11550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lineBeg = lineEnd + 1;
11560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    continue;
11570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineEnd > lineBeg) {
11590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String line = scanResults.substring(lineBeg, lineEnd);
11600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ScanResult scanResult = parseScanResult(line);
11610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanList.add(scanResult);
11630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
1164090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        //TODO: hidden network handling
11650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                lineBeg = lineEnd + 1;
11680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResults = scanList;
11720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1174cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    private String fetchSSID() {
1175cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String status = WifiNative.statusCommand();
1176cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        if (status == null) {
1177cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            return null;
1178cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1179cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        // extract ssid from a series of "name=value"
1180cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String[] lines = status.split("\n");
1181cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        for (String line : lines) {
1182cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String[] prop = line.split(" *= *");
1183cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (prop.length < 2) continue;
1184cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String name = prop[0];
1185cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String value = prop[1];
1186cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (name.equalsIgnoreCase("ssid")) return value;
1187cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1188cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        return null;
1189cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    }
1190cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff
119119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /*
119219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Fetch RSSI and linkspeed on current connection
119319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
119419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private void fetchRssiAndLinkSpeedNative() {
119519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newRssi = WifiNative.getRssiCommand();
119619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
119719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /* some implementations avoid negative values by adding 256
119819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * so we need to adjust for that here.
119919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
120019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newRssi > 0) newRssi -= 256;
120119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(newRssi);
120219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /*
120319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * Rather then sending the raw RSSI out every time it
120419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes, we precalculate the signal level that would
120519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * be displayed in the status bar, and only send the
120619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcast if that much more coarse-grained number
120719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes. This cuts down greatly on the number of
120819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcasts, at the cost of not mWifiInforming others
120919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * interested in RSSI of all the changes in signal
121019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * level.
121119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
121219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // TODO: The second arg to the call below needs to be a symbol somewhere, but
121319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // it's actually the size of an array of icons that's private
121419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            // to StatusBar Policy.
121519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
121619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
121719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendRssiChangeBroadcast(newRssi);
121819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
121919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mLastSignalLevel = newSignalLevel;
122019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        } else {
122119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(-200);
122219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
122319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        int newLinkSpeed = WifiNative.getLinkSpeedCommand();
122419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newLinkSpeed != -1) {
122519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
122619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
122719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
122819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
12295876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private void setHighPerfModeEnabledNative(boolean enable) {
12305876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
12315876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            Log.e(TAG, "set suspend optimizations failed!");
12325876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12335876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if (enable) {
12345876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
12355876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode active failed!");
12365876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12375876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        } else {
12385876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
12395876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                Log.e(TAG, "set power mode auto failed!");
12405876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
12415876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
12425876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    }
12435876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
124437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private void configureLinkProperties() {
124596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
124696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
124796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
124896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            // TODO - fix this for v6
124996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            synchronized (mDhcpInfo) {
125096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addLinkAddress(new LinkAddress(
125196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress),
125296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        NetworkUtils.intToInetAddress(mDhcpInfo.netmask)));
125396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
125496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
125596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
125696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
125796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
1258128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
125996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        mLinkProperties.setInterfaceName(mInterfaceName);
126096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        Log.d(TAG, "netId=" + mLastNetworkId  + " Link configured: " + mLinkProperties.toString());
12610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
12640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return Settings.Secure.getInt(mContext.getContentResolver(),
12650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
12660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
12670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
1270be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
1271be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1272be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        mContext.sendBroadcast(intent);
12730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
12760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
1277be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
12780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
12790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
12800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
12830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
12840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
12850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
128737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
12880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
12890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
12900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
12910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1293fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    private void sendErrorBroadcast(int errorCode) {
1294fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        Intent intent = new Intent(WifiManager.ERROR_ACTION);
1295fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1296fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.putExtra(WifiManager.EXTRA_ERROR_CODE, errorCode);
1297fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        mContext.sendBroadcast(intent);
1298fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1299fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1300be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void sendLinkConfigurationChangedBroadcast() {
1301be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
1302be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
130337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
13040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
13080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
1309be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
13110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
13160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param state the new @{code DetailedState}
13170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1318be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
13190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "setDetailed state, old ="
13200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                + mNetworkInfo.getDetailedState() + " and new state=" + state);
13210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
13220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkInfo.setDetailedState(state, null, null);
13230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1326be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private DetailedState getNetworkDetailedState() {
1327be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return mNetworkInfo.getDetailedState();
1328be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    }
1329be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
13300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
13320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
13330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
13350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "Reset connections and stopping DHCP");
13360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
13380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Reset connections & stop DHCP
13390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
13400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.resetConnections(mInterfaceName);
13410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!NetworkUtils.stopDhcp(mInterfaceName)) {
13430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Could not stop DHCP");
13440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Disable interface */
13470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.disableInterface(mInterfaceName);
13480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* send event to CM & network change broadcast */
1350be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        setNetworkDetailedState(DetailedState.DISCONNECTED);
13510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
13520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
13540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setIpAddress(0);
13550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
13560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
13570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setNetworkId(-1);
13580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
136037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
13610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
13630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
13640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
13690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Notifications from WifiMonitor
13700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
13710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1373b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff     * Stores supplicant state change information passed from WifiMonitor
13740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
137519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    static class StateChangeResult {
1376b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff        StateChangeResult(int networkId, String BSSID, SupplicantState state) {
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.state = state;
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.BSSID = BSSID;
13790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.networkId = networkId;
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int networkId;
13820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String BSSID;
1383b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff        SupplicantState state;
13840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a user-entered password key
13880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * may be incorrect (i.e., caused authentication to fail).
13890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyPasswordKeyMayBeIncorrect() {
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
13920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1395fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     * Send a notification that the supplicant has detected overlapped
1396fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     * WPS sessions
1397fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff     */
1398fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    void notifyWpsOverlap() {
1399fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        sendMessage(WPS_OVERLAP_EVENT);
1400fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1401fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1402fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /**
14030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a connection to the supplicant
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * daemon has been established.
14050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantConnection() {
14070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_CONNECTION_EVENT);
14080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
141168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * Send the tracker a notification that connection to the supplicant
141268825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff     * daemon is lost
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantLost() {
14150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_DISCONNECTION_EVENT);
14160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of Wifi connectivity
14200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new network state
14230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param BSSID when the new state is {@link DetailedState#CONNECTED
14240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * NetworkInfo.DetailedState.CONNECTED},
14250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * this is the MAC address of the access point. Otherwise, it
14260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * is {@code null}.
14270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyNetworkStateChange(DetailedState newState, String BSSID, int networkId) {
14290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newState == NetworkInfo.DetailedState.CONNECTED) {
1430b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff            sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT, networkId, 0, BSSID));
14310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
1432b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff            sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT, networkId, 0, BSSID));
14330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of the supplicant
14380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
14390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
14400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new {@code SupplicantState}
14410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantStateChange(int networkId, String BSSID, SupplicantState newState) {
14430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
14440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                new StateChangeResult(networkId, BSSID, newState)));
14450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a scan has completed, and results
14490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * are available.
14500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyScanResultsAvailable() {
14520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
14530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Switch scan mode over to passive.
14540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Turning off scan-only mode happens only in "Connect" mode
14550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
14560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setScanType(false);
14570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SCAN_RESULTS_EVENT);
14580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStarted() {
14610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_START_EVENT);
14620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStopped() {
14650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_STOP_EVENT);
14660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverHung() {
14690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(false);
14700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(true);
14710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
14740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
14750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
14760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DefaultState extends HierarchicalState {
14780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
14790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
14800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
14810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
148265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
148365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
148465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
1485cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
14860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
14870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
14880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
14890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
14900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
14914b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                case CMD_REMOVE_NETWORK:
14921406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_SAVE_CONFIG:
14931406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, FAILURE);
14944b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                    break;
14950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
14960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
149719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
14980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
14990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
15000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
15010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
15020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
15030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
15040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
15050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
15060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
1507e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
1508e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
1509e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
1510e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
15110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
15120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
15130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
15140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
15150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
15160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
15170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
15180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
15190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
1520fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
15240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
15255876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1526ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
152736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
15280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
1529e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
1530e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1531e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
153219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
15338e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
15340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
153502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
1536e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    /* Return failure when the state machine cannot handle WPS initiation*/
1537e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mReplyChannel.replyToMessage(message, message.what,
1538e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                                new WpsResult(Status.FAILURE));
153902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
15400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
15410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG, "Error! unhandled message" + message);
15420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
15430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
15450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class InitialState extends HierarchicalState {
15490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
15510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
15520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
15530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
15540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
15550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
15560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
15570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (WifiNative.isDriverLoaded()) {
15590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
15600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
15620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
15630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadingState extends HierarchicalState {
15680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
15690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
15700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
15710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
15720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
15740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
15750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
15760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
15770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
15780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
15790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
15804f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
15810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
15820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
15830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
15840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
15850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
15860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
15870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
15880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
15890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
15900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.loadDriver()) {
15920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver load successful");
15930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
15940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
15950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to load driver!");
15960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
15970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
15980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
15990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
16010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
16020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
16030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
16040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
16050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16064f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
16070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
16090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
16150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
16160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
16170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
16190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
16200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
16230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
16240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
16260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
16290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
16300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
16315876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1632ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
163336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
16340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
16360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
16370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
16390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
16400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
16420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
16430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadedState extends HierarchicalState {
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
16540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
16550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
16560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
16570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
16580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
16600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.startSupplicant()) {
16610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Supplicant start successful");
16620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
166396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mSupplicantStartingState);
16640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to start supplicant!");
16660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
16700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
16710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.startAccessPoint((WifiConfiguration) message.obj,
16720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
16730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
16740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
16750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in startAccessPoint()");
16760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
16770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
16780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Soft AP start successful");
16800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
16810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mSoftApStartedState);
16820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
16830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
16840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
16850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
16870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
16880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadingState extends HierarchicalState {
16920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
16930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
16940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
16950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
16960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
16980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
16990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
17000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
17010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17024f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
17030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.unloadDriver()) {
17040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver unload successful");
17050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
17060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
17110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
17180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to unload driver!");
17190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
17200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
17220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
17230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
17240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
17250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
17270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
17280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
17300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
17310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
17324f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
17330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
17340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
17350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
17390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
17410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
17420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
17430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
17450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
17460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
17480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
17490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
17500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
17530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
17540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
17550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
17560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
17575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1758ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
175936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
17600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
17630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadedState extends HierarchicalState {
17730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
17760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
17800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
17810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
17820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
17830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadingState);
17840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
17850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
17860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
17870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
17890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
17900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverFailedState extends HierarchicalState {
17940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, getName() + "\n");
17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
18030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
180796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStartingState extends HierarchicalState {
18080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
18160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
18170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
18180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Supplicant connection established");
1819b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_ENABLED);
182096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    mSupplicantRestartCount = 0;
1821b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    /* Reset the supplicant state to indicate the supplicant
1822b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                     * state is not known at this time */
1823b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1824e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
18250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
18260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
18270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = -1;
18280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
18290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
18310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
183204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.initialize(mContext);
18339e6222f4c126252c9950d072ab67d8b849d17643Irfan Sheriff
18340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //TODO: initialize and fix multicast filtering
18350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //mWM.initializeMulticastFiltering();
18360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
18384f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartedState);
18390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
184068825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case SUP_DISCONNECTION_EVENT:
184196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
184296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        Log.e(TAG, "Failed to setup control channel, restart supplicant");
184396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        WifiNative.killSupplicant();
184496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
184596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
184696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    } else {
184796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        mSupplicantRestartCount = 0;
184896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        Log.e(TAG, "Failed " + mSupplicantRestartCount +
184996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                                " times to start supplicant, unload driver");
185096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
1851b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
185296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
18530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
185468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_LOAD_DRIVER:
185568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_UNLOAD_DRIVER:
185668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_START_SUPPLICANT:
185768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_SUPPLICANT:
18580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
185968825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_AP:
18600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
18610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
18620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
18630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
18645876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1865ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
186636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
18670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
18680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
18690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
18700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
18710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
18720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
18730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
18750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
18760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
187996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStartedState extends HierarchicalState {
18800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
18820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
18830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
18840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
18850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
18866bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            /* Wifi is available as long as we have a connection to supplicant */
18876bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(true);
18880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
1892e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
18938e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
18940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
18950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
18965d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                    Log.d(TAG, "stopping supplicant");
18975d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                    if (!WifiNative.stopSupplicant()) {
18985d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff                        Log.e(TAG, "Failed to stop supplicant, issue kill");
189996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        WifiNative.killSupplicant();
190096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
19016bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
190268825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    handleNetworkDisconnect();
1903b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_DISABLING);
190468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
1905b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1906e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
190796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mSupplicantStoppingState);
190868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    break;
190996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
191096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.e(TAG, "Connection lost, restart supplicant");
191196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    WifiNative.killSupplicant();
19120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.closeSupplicantConnection();
19136bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
19140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
19150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
1916b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
1917e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
19180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
191996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
19200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
19228e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
19230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setScanResults(WifiNative.scanResultsCommand());
19240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendScanResultsAvailableBroadcast();
19250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
19271406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    boolean ok = WifiNative.pingCommand();
19281406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
19311406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    config = (WifiConfiguration) message.obj;
19321406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
19331406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                            WifiConfigStore.addOrUpdateNetwork(config));
19340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
19361406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.removeNetwork(message.arg1);
19371406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
19401406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
19411406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19438e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
19448e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    WifiConfigStore.enableAllNetworks();
19458e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    break;
19460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
19471406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.disableNetwork(message.arg1);
19481406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
19490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
19510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.addToBlacklistCommand((String)message.obj);
19520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
19540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.clearBlacklistCommand();
19550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
19571406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    ok = WifiConfigStore.saveConfig();
19581406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
19591406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
19600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
19610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
19620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
19630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
19640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
19650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
19660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
19670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
19680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
19700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
19720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
19730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
19740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
19750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
19770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
19780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
1979e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1980e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
198104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.saveNetwork(config);
1982e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
1983e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
198404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfigStore.forgetNetwork(message.arg1);
1985e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
19860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
19870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
19880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19898e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
19908e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
19918e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
19920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
19930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19946bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff
19956bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        @Override
19966bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        public void exit() {
19976bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
19986bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        }
19990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
200196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    class SupplicantStoppingState extends HierarchicalState {
200296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
200396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public void enter() {
200496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
200596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
200696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
200796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
200896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public boolean processMessage(Message message) {
200996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
201096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            switch(message.what) {
201196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_CONNECTION_EVENT:
201296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.e(TAG, "Supplicant connection received while stopping");
201396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
201496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
201596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    Log.d(TAG, "Supplicant connection lost");
201696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    WifiNative.closeSupplicantConnection();
201796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mDriverLoadedState);
201896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
201996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_LOAD_DRIVER:
202096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_UNLOAD_DRIVER:
202196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_SUPPLICANT:
202296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_SUPPLICANT:
202396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_AP:
202496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_AP:
202596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_DRIVER:
202696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_DRIVER:
202796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_MODE:
202896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_TYPE:
202996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
203096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
203196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
203296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_PACKET_FILTERING:
203396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
203496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    deferMessage(message);
203596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
203696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                default:
203796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    return NOT_HANDLED;
203896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            }
203996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
204096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            return HANDLED;
204196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
204296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    }
204396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
20440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartingState extends HierarchicalState {
20450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
20520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
20530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
20540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
20550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStartedState);
20560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
20580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
20590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
20600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
20610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
20620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
20630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
2064fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
20650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
20665876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2067ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
206836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
20690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
20700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
20710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
20720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
20730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
20740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2075e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
20760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartedState extends HierarchicalState {
20860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
20890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
209103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = true;
209203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
20930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
209465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            /**
209565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
209665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * When this mode is on, some of the low-level scan parameters used by the
209765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * driver are changed to reduce interference with bluetooth
209865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             */
209965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive);
2100ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            /* set country code */
2101ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode();
210236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            /* set frequency band of operation */
210336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            setFrequencyBand();
21043a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            /* initialize network state */
21053a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            setNetworkDetailedState(DetailedState.DISCONNECTED);
21060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
21080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
21090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.disconnectCommand();
21100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
21110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
21120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.reconnectCommand();
2114090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                transitionTo(mDisconnectedState);
21150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21208e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
21210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ACTIVE) {
21240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(true);
21250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(false);
21270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
212919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
21308e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
213119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
213219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
21335876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
21345876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    setHighPerfModeEnabledNative(message.arg1 == 1);
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2136ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
2137ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    String country = (String) message.obj;
2138ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Log.d(TAG, "set country code " + country);
2139ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) {
2140ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                        Log.e(TAG, "Failed to set country code " + country);
2141ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    }
21420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
214336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
214436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    int band =  message.arg1;
214536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Log.d(TAG, "set frequency band " + band);
214636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    if (WifiNative.setBandCommand(band)) {
214736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        mFrequencyBand.set(band);
2148cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        //Fetch the latest scan results when frequency band is set
2149cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        startScan(true);
215036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    } else {
215136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        Log.e(TAG, "Failed to set frequency band " + band);
215236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    }
215336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    break;
215465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
215565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
215665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
215765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive);
215865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    break;
21590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21604f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
21610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopDriverCommand();
21620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppingState);
21634f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
21640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
21660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.startPacketFiltering();
21670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
21690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopPacketFiltering();
21700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21748e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
21758e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
21768e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
21770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
21810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
218203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = false;
218303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
2184f99819e47cbef2ec066a21b426c7e6fe95e3de48Irfan Sheriff            mScanResults = null;
21850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppingState extends HierarchicalState {
21890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
21920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
21970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
21980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
21990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppedState);
22000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
22020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
22030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
22055876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2206ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
220736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
22080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
22110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2214e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
22150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppedState extends HierarchicalState {
22250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22334f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            switch (message.what) {
22344f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                case CMD_START_DRIVER:
22354f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
22364f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    WifiNative.startDriverCommand();
22374f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartingState);
22384f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
22394f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    break;
22404f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                default:
22414f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    return NOT_HANDLED;
22424f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            }
22434f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22444f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            return HANDLED;
22450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ScanModeState extends HierarchicalState {
22490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
22600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.reconnectCommand();
22650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
22670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
22710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
22750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
22760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectModeState extends HierarchicalState {
22860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
22950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
229719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
22980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2299fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                case WPS_OVERLAP_EVENT:
2300fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    /* We just need to broadcast the error */
2301fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
2302fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    break;
23030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
23040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
2305b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    SupplicantState state = stateChangeResult.state;
230619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // Supplicant state change
230719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [31-13] Reserved for future use
230819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // [8 - 0] Supplicant state (as defined in SupplicantState.java)
230919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    // 50023 supplicant_state_changed (custom|1|5)
231019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
231119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setSupplicantState(state);
231219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
231319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (state == SupplicantState.ASSOCIATING) {
231419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        /* BSSID is valid only in ASSOCIATING state */
231519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        mWifiInfo.setBSSID(stateChangeResult.BSSID);
231619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
231719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
231802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mSupplicantStateTracker.sendMessage(Message.obtain(message));
231902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
23200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
23220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2323e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
23240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2326e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reconnectCommand();
23270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
2329e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reassociateCommand();
23300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2331e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2332e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
2333e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
233404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
233504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* We connect to a specific network by issuing a select
233604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * to the WifiConfigStore. This enables the network,
233704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * while disabling all other networks in the supplicant.
233804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * Disabling a connected network will cause a disconnection
233904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * from the network. A reconnectCommand() will then initiate
234004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * a connection to the enabled network.
234104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     */
2342e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
234304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(config);
234404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    } else {
234504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfigStore.selectNetwork(netId);
2346e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2347e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
23488e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    /* The state tracker handles enabling networks upon completion/failure */
23498e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_CONNECT_NETWORK);
235004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
2351a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    WifiNative.reconnectCommand();
235204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
235304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* Expect a disconnection from the old connection */
2354a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    transitionTo(mDisconnectingState);
2355e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
235602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
235702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
235802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mWaitForWpsCompletionState);
2359f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    break;
23600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
23610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
23620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
23630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
23640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
23660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection established");
2367b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastNetworkId = message.arg1;
2368b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastBssid = (String) message.obj;
23690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2370cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    //TODO: make supplicant modification to push this in events
2371cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    mWifiInfo.setSSID(fetchSSID());
2372b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid);
2373b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setNetworkId(mLastNetworkId);
23740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
2375be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
23760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
23770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
23780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
23800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection lost");
23810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
23820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
23830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
23850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
23870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
23880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
23890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectingState extends HierarchicalState {
239331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mModifiedBluetoothCoexistenceMode;
239431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        int mPowerMode;
239531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean mUseStaticIp;
23960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Thread mDhcpThread;
23970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
24010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
240231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
24030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!mUseStaticIp) {
24040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = null;
240531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mModifiedBluetoothCoexistenceMode = false;
24065876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                mPowerMode = POWER_MODE_AUTO;
24070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
240865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                if (!mBluetoothConnectionActive) {
24090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
24100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * There are problems setting the Wi-Fi driver's power
24110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode to active when bluetooth coexistence mode is
24120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * enabled or sense.
24130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * We set Wi-Fi to active mode when
24150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address because we've found
24160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * compatibility issues with some routers with low power
24170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode.
24180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
24190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * In order for this active power mode to properly be set,
24200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * we disable coexistence mode until we're done with
24210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address.  One exception is if we
24220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * are currently connected to a headset, since disabling
24230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * coexistence would interrupt that connection.
24240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
242531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    mModifiedBluetoothCoexistenceMode = true;
24260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Disable the coexistence mode
24280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(
24290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
24300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
243231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                mPowerMode =  WifiNative.getPowerModeCommand();
243331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (mPowerMode < 0) {
24340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Handle the case where supplicant driver does not support
24350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // getPowerModeCommand.
24365876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    mPowerMode = POWER_MODE_AUTO;
24370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24385876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                if (mPowerMode != POWER_MODE_ACTIVE) {
24395876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
24400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "DHCP request started");
24430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = new Thread(new Runnable() {
24440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    public void run() {
244531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        DhcpInfo dhcpInfo = new DhcpInfo();
244631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfo)) {
24470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request succeeded");
244831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            synchronized (mDhcpInfo) {
244931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                                mDhcpInfo = dhcpInfo;
245031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                            }
24510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_SUCCESS);
24520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
24530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request failed: " +
24540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    NetworkUtils.getDhcpError());
24550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_FAILURE);
24560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
24570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
24580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                });
24590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread.start();
24600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
246131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                DhcpInfo dhcpInfo = WifiConfigStore.getIpConfiguration(mLastNetworkId);
246231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                if (NetworkUtils.configureInterface(mInterfaceName, dhcpInfo)) {
24630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration succeeded");
246431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    synchronized (mDhcpInfo) {
246531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        mDhcpInfo = dhcpInfo;
246631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    }
24670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_SUCCESS);
24680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
24690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration failed");
24700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_FAILURE);
24710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
24720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
24730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         }
24740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
24750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public boolean processMessage(Message message) {
24760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
24770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          switch(message.what) {
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_SUCCESS:
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mLastSignalLevel = -1; // force update of signal strength
248131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  synchronized (mDhcpInfo) {
248231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                      mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
248331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  }
248437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                  configureLinkProperties();
2485be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  if (getNetworkDetailedState() == DetailedState.CONNECTED) {
2486be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendLinkConfigurationChangedBroadcast();
2487be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  } else {
2488be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      setNetworkDetailedState(DetailedState.CONNECTED);
2489be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                      sendNetworkStateChangeBroadcast(mLastBssid);
2490be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  }
249131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //TODO: The framework is not detecting a DHCP renewal and a possible
249231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  //IP change. we should detect this and send out a config change broadcast
24930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mConnectedState);
24940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
24950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_FAILURE:
24960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mWifiInfo.setIpAddress(0);
24970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  Log.e(TAG, "IP configuration failed");
24990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /**
25000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * If we've exceeded the maximum number of retries for DHCP
25010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * to a given network, disable the network
25020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (++mReconnectCount > getMaxDhcpRetries()) {
250468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      Log.e(TAG, "Failed " +
250568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                              mReconnectCount + " times, Disabling " + mLastNetworkId);
250604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                      WifiConfigStore.disableNetwork(mLastNetworkId);
250768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                      mReconnectCount = 0;
25080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* DHCP times out after about 30 seconds, we do a
25110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * disconnect and an immediate reconnect to try again
25120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
25130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.disconnectCommand();
25140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.reconnectCommand();
25150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_DISCONNECT:
2518e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                  WifiNative.disconnectCommand();
25190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
25200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
2521a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  /* Ignore connection to same network */
2522a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff              case CMD_CONNECT_NETWORK:
2523a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  int netId = message.arg1;
2524a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  if (mWifiInfo.getNetworkId() == netId) {
2525a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                      break;
2526a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  }
2527a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  return NOT_HANDLED;
2528be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff              case CMD_SAVE_NETWORK:
2529be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  deferMessage(message);
2530be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  break;
25310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* Ignore */
25320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case NETWORK_CONNECTION_EVENT:
25330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_STOP_DRIVER:
25350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  sendMessage(CMD_DISCONNECT);
25360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  deferMessage(message);
25370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
25380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_SET_SCAN_MODE:
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (message.arg1 == SCAN_ONLY_MODE) {
25400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendMessage(CMD_DISCONNECT);
25410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      deferMessage(message);
25420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
25430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
254419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  /* Defer scan when IP is being fetched */
254519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff              case CMD_START_SCAN:
254619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  deferMessage(message);
254719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  break;
25485876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  /* Defer any power mode changes since we must keep active power mode at DHCP */
25495876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              case CMD_SET_HIGH_PERF_MODE:
25505876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  deferMessage(message);
25515876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  break;
25520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              default:
25530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return NOT_HANDLED;
25540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
25550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          return HANDLED;
25570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
25580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
25600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public void exit() {
25610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          /* reset power state & bluetooth coexistence if on DHCP */
25620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (!mUseStaticIp) {
25635876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              if (mPowerMode != POWER_MODE_ACTIVE) {
256431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                  WifiNative.setPowerModeCommand(mPowerMode);
25650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
25660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
256731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff              if (mModifiedBluetoothCoexistenceMode) {
25680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Set the coexistence mode back to its default value
25690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.setBluetoothCoexistenceModeCommand(
25700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
25710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
25720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
25730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
25750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
25770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectedState extends HierarchicalState {
25780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
25790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
25800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
25810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
258219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mRssiPollToken++;
258319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (mEnableRssiPolling) {
258419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendMessage(obtainMessage(WifiStateMachine.CMD_RSSI_POLL, mRssiPollToken, 0));
258519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
25860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
25870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
25880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
25890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
25908e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
25910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
25920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2593e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
25940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
25950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
25970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_DISCONNECT);
25980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
25990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26009beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
26019beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    if (mCm == null) {
26029beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                        mCm = (ConnectivityManager)mContext.getSystemService(
26039beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                                Context.CONNECTIVITY_SERVICE);
26049beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    }
26059beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    mCm.requestNetworkTransitionWakelock(TAG);
26069beea36441ef805a8a3c343553e281f1966c047eIrfan Sheriff                    break;
26070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
26080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
26090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
26100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
26110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
26120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
261319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
26148e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
261519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* When the network is connected, re-scanning can trigger
261619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * a reconnection. Put it in scan-only mode during scan.
261719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * When scan results are received, the mode is switched
261819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * back to CONNECT_MODE.
261919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     */
262019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
262119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
262219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
2623a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Ignore connection to same network */
2624a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                case CMD_CONNECT_NETWORK:
2625a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    int netId = message.arg1;
2626a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    if (mWifiInfo.getNetworkId() == netId) {
2627a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                        break;
2628a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    }
2629a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    return NOT_HANDLED;
2630be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                case CMD_SAVE_NETWORK:
2631be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
2632be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
2633be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
2634be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasIpChanged()) {
2635be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring IP on connection");
2636be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            NetworkUtils.resetConnections(mInterfaceName);
2637be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            transitionTo(mConnectingState);
2638be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2639be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasProxyChanged()) {
2640be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            Log.d(TAG,"Reconfiguring proxy on connection");
2641be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            configureLinkProperties();
2642be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            sendLinkConfigurationChangedBroadcast();
2643be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
2644be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    }
2645be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    break;
26460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
26470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
26480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
264919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
26508e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
265119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (message.arg1 == mRssiPollToken) {
265219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Get Info and continue polling
265319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
265419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
265519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
265619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    } else {
265719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Polling has completed
265819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
265919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
266019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_ENABLE_RSSI_POLL:
266119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
266219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mRssiPollToken++;
266319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (mEnableRssiPolling) {
266419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // first poll
266519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
266619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
266719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
266819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
266919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
26700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
26710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
26720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
26738e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
26748e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
26758e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
26760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
26770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectingState extends HierarchicalState {
26810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
26840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
26850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
26890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
26900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
26910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
26920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
26940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
26950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
26960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
26970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
269819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* Handle in  DisconnectedState */
269919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
270019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    deferMessage(message);
270119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
27020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectedState extends HierarchicalState {
27110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
2715090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2716090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            /**
2717090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * In a disconnected state, an infrequent scan that wakes
2718090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * up the device is needed to ensure a user connects to
2719090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             * an access point on the move
2720090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             */
2721090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
2722090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
2723090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2724090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
2725090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
27260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
27310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
27340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
27350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.disconnectCommand();
27360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
27370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
27380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
27410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
27420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
274319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
274419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
2745b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
274619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* DriverStartedState does the rest of the handling */
274719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    return NOT_HANDLED;
27480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
2754090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
2755090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        @Override
2756090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        public void exit() {
2757090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff            mAlarmManager.cancel(mScanIntent);
2758090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        }
27590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
276102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    class WaitForWpsCompletionState extends HierarchicalState {
276202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
276302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public void enter() {
276402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
276502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
276602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
276702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
276802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public boolean processMessage(Message message) {
276902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
277002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            switch (message.what) {
277102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                /* Defer all commands that can cause connections to a different network
277202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 * or put the state machine out of connect mode
277302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 */
277402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_STOP_DRIVER:
277502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_SET_SCAN_MODE:
277602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_CONNECT_NETWORK:
277702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_ENABLE_NETWORK:
277802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_RECONNECT:
277902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_REASSOCIATE:
278002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case NETWORK_CONNECTION_EVENT: /* Handled after IP & proxy update */
278102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    deferMessage(message);
278202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
278302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
278402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    Log.d(TAG,"Network connection lost");
278502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    handleNetworkDisconnect();
278602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
278702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case WPS_COMPLETED_EVENT:
278802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    /* we are still disconnected until we see a network connection
278902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                     * notification */
279002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mDisconnectedState);
279102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
279202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                default:
279302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    return NOT_HANDLED;
279402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            }
279502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
279602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            return HANDLED;
279702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
279802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    }
279902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
28000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SoftApStartedState extends HierarchicalState {
28010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
28100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
28110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Stopping Soft AP");
28120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
28130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.stopAccessPoint();
28150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in stopAccessPoint()");
28170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
28190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
28210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"SoftAP set on a running access point");
28220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
28230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.setAccessPoint((WifiConfiguration) message.obj,
28240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
28250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
28260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
28270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in nwService during soft AP set");
28280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
28290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            nwService.stopAccessPoint();
28300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception ee) {
28310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Slog.e(TAG, "Could not stop AP, :" + ee);
28320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
28330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
28340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* Fail client mode operation when soft AP is enabled */
28370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
28380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG,"Cannot start supplicant with a running soft AP");
28390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
28400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
2849