WifiStateMachine.java revision cdea9193f2745fd46e69858a7c5570d95f8182dc
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
400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.ActivityManagerNative;
410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo;
420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.DhcpInfo;
430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkUtils;
440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.ConnectivityManager;
450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkProperties;
47e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriffimport android.net.wifi.WifiConfiguration.Status;
480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Binder;
490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Message;
500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Parcelable;
510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Handler;
520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.IBinder;
530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.INetworkManagementService;
540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.PowerManager;
550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.SystemProperties;
560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.RemoteException;
570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.ServiceManager;
580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Process;
590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.provider.Settings;
600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.text.TextUtils;
610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.EventLog;
620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Log;
630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Slog;
640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.backup.IBackupManager;
650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.bluetooth.BluetoothDevice;
660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.bluetooth.BluetoothHeadset;
670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.bluetooth.BluetoothA2dp;
680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.ContentResolver;
690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Intent;
700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.content.Context;
710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.database.ContentObserver;
720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.app.IBatteryStats;
730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalState;
740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.util.HierarchicalStateMachine;
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.net.InetAddress;
770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.net.NetworkInterface;
780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.net.SocketException;
790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.net.UnknownHostException;
800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.ArrayList;
810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.BitSet;
820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.LinkedHashMap;
830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.List;
840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.Map;
850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.Set;
860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.concurrent.atomic.AtomicBoolean;
870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.concurrent.atomic.AtomicInteger;
880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.regex.Pattern;
890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Track the state of Wifi connectivity. All event handling is done here,
920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and all changes in connectivity state are initiated here.
930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @hide
950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff//TODO: we still need frequent scanning for the case when
970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff// we issue disconnect but need scan results for open network notification
980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpublic class WifiStateMachine extends HierarchicalStateMachine {
990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String TAG = "WifiStateMachine";
1010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String NETWORKTYPE = "WIFI";
1020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final boolean DBG = false;
1030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* TODO: fetch a configurable interface */
1050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String SOFTAP_IFACE = "wl0.1";
1060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiMonitor mWifiMonitor;
1080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private INetworkManagementService nwService;
1090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ConnectivityManager mCm;
1100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results handling */
1120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private List<ScanResult> mScanResults;
1130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final Pattern scanResultPattern = Pattern.compile("\t+");
1140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULT_CACHE_SIZE = 80;
1150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final LinkedHashMap<String, ScanResult> mScanResultCache;
1160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mInterfaceName;
1180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mNumAllowedChannels = 0;
1200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastSignalLevel = -1;
1210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mLastBssid;
1220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastNetworkId;
1230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mEnableRssiPolling = false;
1240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mPasswordKeyMayBeIncorrect = false;
1250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mUseStaticIp = false;
1260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mReconnectCount = 0;
1270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mIsScanMode = false;
1280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mConfigChanged = false;
1290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Instance of the bluetooth headset helper. This needs to be created
1320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * early because there is a delay before it actually 'connects', as
1330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * noted by its javadoc. If we check before it is connected, it will be
1340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * in an error state and we will not disable coexistence.
1350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private BluetoothHeadset mBluetoothHeadset;
1370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private BluetoothA2dp mBluetoothA2dp;
1390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Observes the static IP address settings.
1420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SettingsObserver mSettingsObserver;
1440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkProperties mNetworkProperties;
1450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Held during driver load and unload
1470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static PowerManager.WakeLock sWakeLock;
1480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private Context mContext;
1500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private DhcpInfo mDhcpInfo;
1520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiInfo mWifiInfo;
1530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkInfo mNetworkInfo;
1540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SupplicantStateTracker mSupplicantStateTracker;
155e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Tracks the highest priority of configured networks */
156e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private int mLastPriority = -1;
157e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Tracks if all networks need to be enabled */
158e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private boolean mEnableAllNetworks = false;
1590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Event log tags (must be in sync with event-log-tags)
1610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
1620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
1630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED  = 50023;
1640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Load the driver */
1660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_LOAD_DRIVER                      = 1;
1670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unload the driver */
1680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_UNLOAD_DRIVER                    = 2;
1690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load succeeded */
1700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_LOAD_DRIVER_SUCCESS              = 3;
1710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load failed */
1720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_LOAD_DRIVER_FAILURE              = 4;
1730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload succeeded */
1740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_UNLOAD_DRIVER_SUCCESS            = 5;
1750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload failed */
1760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_UNLOAD_DRIVER_FAILURE            = 6;
1770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the supplicant */
1790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_START_SUPPLICANT                 = 11;
1800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the supplicant */
1810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_STOP_SUPPLICANT                  = 12;
1820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
1830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_START_DRIVER                     = 13;
1840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
1850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_STOP_DRIVER                      = 14;
1860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP succeded */
1870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_IP_CONFIG_SUCCESS                = 15;
1880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates DHCP failed */
1890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_IP_CONFIG_FAILURE                = 16;
1900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Re-configure interface */
1910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_RECONFIGURE_IP                   = 17;
1920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the soft access point */
1950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_START_AP                         = 21;
1960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the soft access point */
1970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_STOP_AP                          = 22;
1980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant events */
2010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant established */
2020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SUP_CONNECTION_EVENT                 = 31;
2030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection to supplicant lost */
2040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SUP_DISCONNECTION_EVENT              = 32;
2050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start completed */
2060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DRIVER_START_EVENT                   = 33;
2070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stop completed */
2080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DRIVER_STOP_EVENT                    = 34;
2090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network connection completed */
2100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int NETWORK_CONNECTION_EVENT             = 36;
2110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network disconnection completed */
2120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int NETWORK_DISCONNECTION_EVENT          = 37;
2130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results are available */
2140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULTS_EVENT                   = 38;
2150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicate state changed */
2160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
2170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Password may be incorrect */
2180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
2190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands */
2210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Is supplicant alive ? */
2220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_PING_SUPPLICANT                  = 51;
2230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Add/update a network configuration */
2240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_ADD_OR_UPDATE_NETWORK            = 52;
2250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Delete a network */
2260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_REMOVE_NETWORK                   = 53;
2270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable a network. The device will attempt a connection to the given network. */
2280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_ENABLE_NETWORK                   = 54;
2290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disable a network. The device does not attempt a connection to the given network. */
2300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_DISABLE_NETWORK                  = 55;
2310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Blacklist network. De-prioritizes the given BSSID for connection. */
2320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_BLACKLIST_NETWORK                = 56;
2330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear the blacklist network list */
2340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_CLEAR_BLACKLIST                  = 57;
2350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Get the configured networks */
2360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_GET_NETWORK_CONFIG               = 58;
2370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Save configuration */
2380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SAVE_CONFIG                      = 59;
2390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connection status */
2400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_CONNECTION_STATUS                = 60;
2410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands after driver start*/
2430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Initiate a scan */
2440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_START_SCAN                       = 71;
2450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
2460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SET_SCAN_MODE                    = 72;
2470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
2480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SET_SCAN_TYPE                    = 73;
2490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disconnect from a network */
2500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_DISCONNECT                       = 74;
2510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reconnect to a network */
2520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_RECONNECT                        = 75;
2530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reassociate to a network */
2540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_REASSOCIATE                      = 76;
2550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set power mode
2560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * POWER_MODE_ACTIVE
2570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * POWER_MODE_AUTO
2580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
2590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SET_POWER_MODE                   = 77;
2600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set bluetooth co-existence
2610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * BLUETOOTH_COEXISTENCE_MODE_ENABLED
2620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * BLUETOOTH_COEXISTENCE_MODE_DISABLED
2630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * BLUETOOTH_COEXISTENCE_MODE_SENSE
2640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
2650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SET_BLUETOOTH_COEXISTENCE        = 78;
2660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable/disable bluetooth scan mode
2670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * true(1)
2680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * false(0)
2690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
2700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SET_BLUETOOTH_SCAN_MODE          = 79;
2710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set number of allowed channels */
2720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_SET_NUM_ALLOWED_CHANNELS         = 80;
2730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Request connectivity manager wake lock before driver stop */
2740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_REQUEST_CM_WAKELOCK              = 81;
2750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enables RSSI poll */
2760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_ENABLE_RSSI_POLL                 = 82;
2770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* RSSI poll */
2780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_RSSI_POLL                        = 83;
2790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Get current RSSI */
2800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_GET_RSSI                         = 84;
2810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Get approx current RSSI */
2820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_GET_RSSI_APPROX                  = 85;
2830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Get link speed on connection */
2840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_GET_LINK_SPEED                   = 86;
2850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Radio mac address */
2860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_GET_MAC_ADDR                     = 87;
2870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set up packet filtering */
2880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_START_PACKET_FILTERING           = 88;
2890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear packet filter */
2900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CMD_STOP_PACKET_FILTERING            = 89;
291e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Connect to a specified network (network id
292e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * or WifiConfiguration) This involves increasing
293e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * the priority of the network, enabling the network
294e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * (while disabling others) and issuing a reconnect.
295e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * Note that CMD_RECONNECT just does a reconnect to
296e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an existing network. All the networks get enabled
297e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * upon a successful connection or a failure.
298e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
299e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private static final int CMD_CONNECT_NETWORK                  = 90;
300e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Save the specified network. This involves adding
301e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an enabled network (if new) and updating the
302e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * config and issuing a save on supplicant config.
303e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
304e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private static final int CMD_SAVE_NETWORK                     = 91;
305e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Delete the specified network. This involves
306e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * removing the network and issuing a save on
307e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * supplicant config.
308e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
309e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private static final int CMD_FORGET_NETWORK                   = 92;
310e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
311e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
3120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Interval in milliseconds between polling for connection
3150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * status items that are not sent via asynchronous events.
3160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * An example is RSSI (signal strength).
3170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
3190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CONNECT_MODE   = 1;
3210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ONLY_MODE = 2;
3220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ACTIVE = 1;
3240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_PASSIVE = 2;
3250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * The maximum number of times we will retry a connection to an access point
3280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * for which we have failed in acquiring an IP address from DHCP. A value of
3290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * N means that we will make N+1 connection attempts in all.
3300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * <p>
3310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
3320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * value if a Settings value is not present.
3330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
3350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DRIVER_POWER_MODE_ACTIVE = 1;
3370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DRIVER_POWER_MODE_AUTO = 0;
3380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Default parent state */
3400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDefaultState = new DefaultState();
3410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Temporary initial state */
3420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mInitialState = new InitialState();
3430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unloading the driver */
3440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadingState = new DriverUnloadingState();
3450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Loading the driver */
3460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverUnloadedState = new DriverUnloadedState();
3470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver load/unload failed */
3480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverFailedState = new DriverFailedState();
3490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loading */
3500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadingState = new DriverLoadingState();
3510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded */
3520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverLoadedState = new DriverLoadedState();
3530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded, waiting for supplicant to start */
3540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mWaitForSupState = new WaitForSupState();
3550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded and supplicant ready */
3570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverSupReadyState = new DriverSupReadyState();
3580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start issued, waiting for completed event */
3590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartingState = new DriverStartingState();
3600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver started */
3610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStartedState = new DriverStartedState();
3620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopping */
3630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppingState = new DriverStoppingState();
3640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopped */
3650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDriverStoppedState = new DriverStoppedState();
3660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan for networks, no connection will be established */
3670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mScanModeState = new ScanModeState();
3680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connecting to an access point */
3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectModeState = new ConnectModeState();
3700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Fetching IP after network connection (assoc+auth complete) */
3710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectingState = new ConnectingState();
3720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connected with IP addr */
3730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mConnectedState = new ConnectedState();
3740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* disconnect issued, waiting for network disconnect confirmation */
3750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectingState = new DisconnectingState();
3760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network is not connected, supplicant assoc+auth is not complete */
3770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mDisconnectedState = new DisconnectedState();
3780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Soft Ap is running */
3800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private HierarchicalState mSoftApStartedState = new SoftApStartedState();
3810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Argument for Message object to indicate a synchronous call */
3830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SYNCHRONOUS_CALL = 1;
3840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int ASYNCHRONOUS_CALL = 0;
3850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
3890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_DISABLING},
3900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLED},
3910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLING},
3920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
3930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
3940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
3960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
3990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
4000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
4010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
4020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
4030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
4040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
4050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
4060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastEnableUid = new AtomicInteger(Process.myUid());
4080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastApEnableUid = new AtomicInteger(Process.myUid());
4090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final IBatteryStats mBatteryStats;
4110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public WifiStateMachine(Context context) {
4130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        super(TAG);
4140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext = context;
4160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
4180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
4190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
4210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        nwService = INetworkManagementService.Stub.asInterface(b);
4220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiMonitor = new WifiMonitor(this);
4240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mDhcpInfo = new DhcpInfo();
4250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo = new WifiInfo();
4260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
4270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mSupplicantStateTracker = new SupplicantStateTracker(context, getHandler());
4280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBluetoothHeadset = new BluetoothHeadset(mContext, null);
4300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkProperties = new NetworkProperties();
4310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo.setIsAvailable(false);
4330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkProperties.clear();
4340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid = null;
4350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
4360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastSignalLevel = -1;
4370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResultCache = new LinkedHashMap<String, ScanResult>(
4390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SCAN_RESULT_CACHE_SIZE, 0.75f, true) {
4400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /*
4410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * Limit the cache size by SCAN_RESULT_CACHE_SIZE
4420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * elements
4430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 */
4440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                @Override
4450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public boolean removeEldestEntry(Map.Entry eldest) {
4460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return SCAN_RESULT_CACHE_SIZE < this.size();
4470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
4480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        };
4490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mSettingsObserver = new SettingsObserver(new Handler());
4510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
4530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
4540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
4560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
4570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
4580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
4590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
4600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
4610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
4620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mWaitForSupState, mDriverLoadedState);
4630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverSupReadyState, mDefaultState);
4640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStartingState, mDriverSupReadyState);
4650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStartedState, mDriverSupReadyState);
4660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
4670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
4680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectingState, mConnectModeState);
4690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectedState, mConnectModeState);
4700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
4710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
4720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStoppingState, mDriverSupReadyState);
4730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverStoppedState, mDriverSupReadyState);
4740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
4750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
4770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
4790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
4810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
4820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
4830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
4850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
4860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
4870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
4890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
4900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
4910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public boolean pingSupplicant() {
4920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_PING_SUPPLICANT).boolValue;
4930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
4940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
4960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
4970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
498e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
499e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
500e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
5010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
5070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
5080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
5110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
5120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
5140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
5230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
5240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
5250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
5260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
5270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
5280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
5290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
5300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
5310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
5320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int getWifiState() {
5390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
5400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public String getWifiStateByName() {
5460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
5470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
5480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
5490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
5500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
5510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
5520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
5530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
5540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
5550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
5560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
5570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
5580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
5590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int getWifiApState() {
5660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
5670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
5710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public String getWifiApStateByName() {
5730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
5740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
5750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
5770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
5790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
5800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
5810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
5820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
5830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
5840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
5850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
5860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
5870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
5910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
5920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
5930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public WifiInfo requestConnectionInfo() {
5950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
5960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
5970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public DhcpInfo getDhcpInfo() {
5990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mDhcpInfo;
6000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setDriverStart(boolean enable) {
6060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
6070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(CMD_START_DRIVER);
6080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(CMD_STOP_DRIVER);
6100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
6170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
6180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
6190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
6210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
6280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
6290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
6310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
6320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
6330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public List<ScanResult> getScanResultsList() {
6390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mScanResults;
6400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
6440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
645e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
646e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
6470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
6510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
652e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
653e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
6540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
6580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
659e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
660e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
6610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
6650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
6670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int addOrUpdateNetwork(WifiConfiguration config) {
6690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_ADD_OR_UPDATE_NETWORK, config).intValue;
6700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public List<WifiConfiguration> getConfiguredNetworks() {
6730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_GET_NETWORK_CONFIG).configList;
6740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
6780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
6800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public boolean removeNetwork(int networkId) {
6820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(obtainMessage(CMD_REMOVE_NETWORK, networkId, 0)).boolValue;
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private class EnableNetParams {
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private int netId;
6870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private boolean disableOthers;
6880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        EnableNetParams(int n, boolean b) {
6890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            netId = n;
6900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            disableOthers = b;
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
6950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
6960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
6970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
6980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
6990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public boolean enableNetwork(int netId, boolean disableOthers) {
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_ENABLE_NETWORK,
7020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                new EnableNetParams(netId, disableOthers)).boolValue;
7030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
7070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
7090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
7100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public boolean disableNetwork(int netId) {
7120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(obtainMessage(CMD_DISABLE_NETWORK, netId, 0)).boolValue;
7130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
7170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
7180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
7200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
7220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
7230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
7270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
7300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
7310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
733e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(int netId) {
734e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, netId, 0));
735e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
736e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
737e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(WifiConfiguration wifiConfig) {
738e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, wifiConfig));
739e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
740e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
741e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void saveNetwork(WifiConfiguration wifiConfig) {
742e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_SAVE_NETWORK, wifiConfig));
743e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
744e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
745e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void forgetNetwork(int netId) {
746e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
747e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
748e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
7490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get detailed status of the connection
7510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return Example status result
7530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  bssid=aa:bb:cc:dd:ee:ff
7540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  ssid=TestNet
7550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  id=3
7560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  pairwise_cipher=NONE
7570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  group_cipher=NONE
7580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  key_mgmt=NONE
7590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  wpa_state=COMPLETED
7600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  ip_address=X.X.X.X
7610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public String status() {
7630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_CONNECTION_STATUS).stringValue;
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
7670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
7680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get RSSI to currently connected network
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return RSSI value, -1 on failure
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int getRssi() {
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_GET_RSSI).intValue;
7760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get approx RSSI to currently connected network
7800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return RSSI value, -1 on failure
7820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int getRssiApprox() {
7840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_GET_RSSI_APPROX).intValue;
7850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get link speed to currently connected network
7890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return link speed, -1 on failure
7910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int getLinkSpeed() {
7930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_GET_LINK_SPEED).intValue;
7940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get MAC address of radio
7980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return MAC address, null on failure
8000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public String getMacAddress() {
8020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_GET_MAC_ADDR).stringValue;
8030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Start packet filtering
8070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void startPacketFiltering() {
8090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_START_PACKET_FILTERING);
8100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Stop packet filtering
8140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void stopPacketFiltering() {
8160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_STOP_PACKET_FILTERING);
8170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Set power mode
8210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param mode
8220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *     DRIVER_POWER_MODE_AUTO
8230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *     DRIVER_POWER_MODE_ACTIVE
8240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setPowerMode(int mode) {
8260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_POWER_MODE, mode, 0));
8270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Set the number of allowed radio frequency channels from the system
8310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * setting value, if any.
8320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setNumAllowedChannels() {
8340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
8350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            setNumAllowedChannels(
8360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Settings.Secure.getInt(mContext.getContentResolver(),
8370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS));
8380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (Settings.SettingNotFoundException e) {
8390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mNumAllowedChannels != 0) {
8400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                setNumAllowedChannels(mNumAllowedChannels);
8410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
8420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // otherwise, use the driver default
8430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
8440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Set the number of radio frequency channels that are allowed to be used
8480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * in the current regulatory domain.
8490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param numChannels the number of allowed channels. Must be greater than 0
8500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * and less than or equal to 16.
8510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setNumAllowedChannels(int numChannels) {
8530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_NUM_ALLOWED_CHANNELS, numChannels, 0));
8540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get number of allowed channels
8580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return channel count, -1 on failure
8600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: this is not a public API and needs to be removed in favor
8620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * of asynchronous reporting. unused for now.
8630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public int getNumAllowedChannels() {
8650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return -1;
8660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Set bluetooth coex mode:
8700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param mode
8720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  BLUETOOTH_COEXISTENCE_MODE_ENABLED
8730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  BLUETOOTH_COEXISTENCE_MODE_DISABLED
8740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *  BLUETOOTH_COEXISTENCE_MODE_SENSE
8750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setBluetoothCoexistenceMode(int mode) {
8770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_BLUETOOTH_COEXISTENCE, mode, 0));
8780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
8820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * some of the low-level scan parameters used by the driver are changed to
8830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * reduce interference with A2DP streaming.
8840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param isBluetoothPlaying whether to enable or disable this mode
8860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setBluetoothScanMode(boolean isBluetoothPlaying) {
8880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_BLUETOOTH_SCAN_MODE, isBluetoothPlaying ? 1 : 0, 0));
8890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
8930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public boolean saveConfig() {
8990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(CMD_SAVE_CONFIG).boolValue;
9000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
9040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void requestCmWakeLock() {
9060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(CMD_REQUEST_CM_WAKELOCK);
9070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
9100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
9110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
9120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SyncReturn {
9140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        boolean boolValue;
9150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int intValue;
9160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String stringValue;
9170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Object objValue;
9180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<WifiConfiguration> configList;
9190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SyncParams {
9220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Object mParameter;
9230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncReturn mSyncReturn;
9240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncParams() {
9250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mSyncReturn = new SyncReturn();
9260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
9270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncParams(Object p) {
9280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mParameter = p;
9290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mSyncReturn = new SyncReturn();
9300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
9310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * message.arg2 is reserved to indicate synchronized
9350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * message.obj is used to store SyncParams
9360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SyncReturn syncedSend(Message msg) {
9380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncParams syncParams = (SyncParams) msg.obj;
9390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        msg.arg2 = SYNCHRONOUS_CALL;
9400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        synchronized(syncParams) {
9410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, "syncedSend " + msg);
9420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(msg);
9430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
9440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                syncParams.wait();
9450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch (InterruptedException e) {
9460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.e(TAG, "sendSyncMessage: unexpected interruption of wait()");
9470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return null;
9480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
9490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
9500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return syncParams.mSyncReturn;
9510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SyncReturn sendSyncMessage(Message msg) {
9540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncParams syncParams = new SyncParams();
9550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        msg.obj = syncParams;
9560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return syncedSend(msg);
9570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SyncReturn sendSyncMessage(int what, Object param) {
9600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncParams syncParams = new SyncParams(param);
9610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Message msg = obtainMessage(what, syncParams);
9620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return syncedSend(msg);
9630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SyncReturn sendSyncMessage(int what) {
9670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return sendSyncMessage(obtainMessage(what));
9680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void notifyOnMsgObject(Message msg) {
9710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        SyncParams syncParams = (SyncParams) msg.obj;
9720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (syncParams != null) {
9730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized(syncParams) {
9740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (DBG) Log.d(TAG, "notifyOnMsgObject " + msg);
9750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                syncParams.notify();
9760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
9770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
9780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        else {
9790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Error! syncParams in notifyOnMsgObject is null");
9800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
9810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
9840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
9850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
9870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
9880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mBatteryStats.noteWifiOn(mLastEnableUid.get());
9890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
9900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mBatteryStats.noteWifiOff(mLastEnableUid.get());
9910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
9920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
9930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Failed to note battery stats in wifi");
9940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
9950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
9970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) Log.d(TAG, "setWifiState: " + getWifiStateByName());
9990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
10010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
10030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
10040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
10080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
10090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
10110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
10120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mBatteryStats.noteWifiOn(mLastApEnableUid.get());
10130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
10140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mBatteryStats.noteWifiOff(mLastApEnableUid.get());
10150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
10160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
10170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.d(TAG, "Failed to note battery stats in wifi");
10180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
10190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
10210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
10220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) Log.d(TAG, "setWifiApState: " + getWifiApStateByName());
10240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
10260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
10270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
10280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
10290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
10300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Parse the scan result line passed to us by wpa_supplicant (helper).
10340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param line the line to parse
10350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return the {@link ScanResult} object
10360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ScanResult parseScanResult(String line) {
10380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        ScanResult scanResult = null;
10390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (line != null) {
10400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
10410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Cache implementation (LinkedHashMap) is not synchronized, thus,
10420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * must synchronized here!
10430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
10440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized (mScanResultCache) {
10450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String[] result = scanResultPattern.split(line);
10460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (3 <= result.length && result.length <= 5) {
10470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String bssid = result[0];
10480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid | frequency | level | flags | ssid
10490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int frequency;
10500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int level;
10510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
10520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = Integer.parseInt(result[1]);
10530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = Integer.parseInt(result[2]);
10540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
10550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
10560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
10580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch (NumberFormatException e) {
10590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = 0;
10600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = 0;
10610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
10640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * The formatting of the results returned by
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * wpa_supplicant is intended to make the fields
10660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * line up nicely when printed,
10670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * not to make them easy to parse. So we have to
10680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * apply some heuristics to figure out which field
10690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * is the SSID and which field is the flags.
10700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String ssid;
10720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String flags;
10730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (result.length == 4) {
10740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (result[3].charAt(0) == '[') {
10750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = result[3];
10760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = "";
10770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
10780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = "";
10790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = result[3];
10800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
10810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else if (result.length == 5) {
10820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = result[3];
10830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = result[4];
10840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
10850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Here, we must have 3 fields: no flags and ssid
10860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // set
10870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = "";
10880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = "";
10890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
10900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid + ssid is the hash key
10920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String key = bssid + ssid;
10930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    scanResult = mScanResultCache.get(key);
10940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
10950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.level = level;
10960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.SSID = ssid;
10970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.capabilities = flags;
10980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.frequency = frequency;
10990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Do not add scan results that have no SSID set
11010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (0 < ssid.trim().length()) {
11020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
11030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
11040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    ssid, bssid, flags, level, frequency);
11050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
11060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
11070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
11090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.w(TAG, "Misformatted scan result text with " +
11100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          result.length + " fields: " + line);
11110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return scanResult;
11160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
11190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * scanResults input format
11200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ee       2427    166     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net1
11210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ff       2412    165     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net2
11220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setScanResults(String scanResults) {
11240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (scanResults == null) {
11250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<ScanResult> scanList = new ArrayList<ScanResult>();
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int lineCount = 0;
11310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int scanResultsLen = scanResults.length();
11330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Parse the result string, keeping in mind that the last line does
11340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // not end with a newline.
11350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
11360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
11370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                ++lineCount;
11380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineCount == 1) {
11400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lineBeg = lineEnd + 1;
11410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    continue;
11420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineEnd > lineBeg) {
11440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String line = scanResults.substring(lineBeg, lineEnd);
11450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ScanResult scanResult = parseScanResult(line);
11460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
11470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanList.add(scanResult);
11480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
11490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.w(TAG, "misformatted scan result for: " + line);
11500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
11510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
11520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                lineBeg = lineEnd + 1;
11530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
11540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResults = scanList;
11570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1159cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    private String fetchSSID() {
1160cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String status = WifiNative.statusCommand();
1161cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        if (status == null) {
1162cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            return null;
1163cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1164cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        // extract ssid from a series of "name=value"
1165cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String[] lines = status.split("\n");
1166cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        for (String line : lines) {
1167cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String[] prop = line.split(" *= *");
1168cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (prop.length < 2) continue;
1169cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String name = prop[0];
1170cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String value = prop[1];
1171cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (name.equalsIgnoreCase("ssid")) return value;
1172cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1173cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        return null;
1174cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    }
1175cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff
11760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void configureNetworkProperties() {
11770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
11780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkProperties.setInterface(NetworkInterface.getByName(mInterfaceName));
11790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (SocketException e) {
11800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "SocketException creating NetworkInterface from " + mInterfaceName +
11810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ". e=" + e);
11820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (NullPointerException e) {
11840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "NPE creating NetworkInterface. e=" + e);
11850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
11860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // TODO - fix this for v6
11880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
11890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkProperties.addAddress(InetAddress.getByAddress(
11900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    NetworkUtils.v4IntToArray(mDhcpInfo.ipAddress)));
11910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (UnknownHostException e) {
11920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Exception setting IpAddress using " + mDhcpInfo + ", e=" + e);
11930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
11940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
11960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkProperties.setGateway(InetAddress.getByAddress(NetworkUtils.v4IntToArray(
11970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mDhcpInfo.gateway)));
11980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (UnknownHostException e) {
11990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Exception setting Gateway using " + mDhcpInfo + ", e=" + e);
12000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkProperties.addDns(InetAddress.getByAddress(
12040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    NetworkUtils.v4IntToArray(mDhcpInfo.dns1)));
12050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (UnknownHostException e) {
12060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Exception setting Dns1 using " + mDhcpInfo + ", e=" + e);
12070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkProperties.addDns(InetAddress.getByAddress(
12100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    NetworkUtils.v4IntToArray(mDhcpInfo.dns2)));
12110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (UnknownHostException e) {
12130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Exception setting Dns2 using " + mDhcpInfo + ", e=" + e);
12140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // TODO - add proxy info
12160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void checkUseStaticIp() {
12200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mUseStaticIp = false;
12210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final ContentResolver cr = mContext.getContentResolver();
12220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (Settings.System.getInt(cr, Settings.System.WIFI_USE_STATIC_IP) == 0) {
12240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return;
12250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (Settings.SettingNotFoundException e) {
12270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
12280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_IP);
12320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (addr != null) {
12330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpInfo.ipAddress = stringToIpAddr(addr);
12340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
12350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return;
12360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_GATEWAY);
12380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (addr != null) {
12390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpInfo.gateway = stringToIpAddr(addr);
12400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
12410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return;
12420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_NETMASK);
12440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (addr != null) {
12450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpInfo.netmask = stringToIpAddr(addr);
12460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
12470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return;
12480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_DNS1);
12500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (addr != null) {
12510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpInfo.dns1 = stringToIpAddr(addr);
12520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
12530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return;
12540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_DNS2);
12560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (addr != null) {
12570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpInfo.dns2 = stringToIpAddr(addr);
12580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
12590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpInfo.dns2 = 0;
12600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (UnknownHostException e) {
12620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
12630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mUseStaticIp = true;
12650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static int stringToIpAddr(String addrString) throws UnknownHostException {
12680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String[] parts = addrString.split("\\.");
12700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (parts.length != 4) {
12710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                throw new UnknownHostException(addrString);
12720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            int a = Integer.parseInt(parts[0])      ;
12750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            int b = Integer.parseInt(parts[1]) <<  8;
12760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            int c = Integer.parseInt(parts[2]) << 16;
12770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            int d = Integer.parseInt(parts[3]) << 24;
12780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return a | b | c | d;
12800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (NumberFormatException ex) {
12810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            throw new UnknownHostException(addrString);
12820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
12860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return Settings.Secure.getInt(mContext.getContentResolver(),
12870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
12880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
12890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private class SettingsObserver extends ContentObserver {
12920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public SettingsObserver(Handler handler) {
12930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            super(handler);
12940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            ContentResolver cr = mContext.getContentResolver();
12950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            cr.registerContentObserver(Settings.System.getUriFor(
12960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Settings.System.WIFI_USE_STATIC_IP), false, this);
12970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            cr.registerContentObserver(Settings.System.getUriFor(
12980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Settings.System.WIFI_STATIC_IP), false, this);
12990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            cr.registerContentObserver(Settings.System.getUriFor(
13000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Settings.System.WIFI_STATIC_GATEWAY), false, this);
13010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            cr.registerContentObserver(Settings.System.getUriFor(
13020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Settings.System.WIFI_STATIC_NETMASK), false, this);
13030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            cr.registerContentObserver(Settings.System.getUriFor(
13040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Settings.System.WIFI_STATIC_DNS1), false, this);
13050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            cr.registerContentObserver(Settings.System.getUriFor(
13060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Settings.System.WIFI_STATIC_DNS2), false, this);
13070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
13100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void onChange(boolean selfChange) {
13110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            super.onChange(selfChange);
13120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            boolean wasStaticIp = mUseStaticIp;
13140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            int oIp, oGw, oMsk, oDns1, oDns2;
13150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            oIp = oGw = oMsk = oDns1 = oDns2 = 0;
13160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wasStaticIp) {
13170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                oIp = mDhcpInfo.ipAddress;
13180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                oGw = mDhcpInfo.gateway;
13190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                oMsk = mDhcpInfo.netmask;
13200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                oDns1 = mDhcpInfo.dns1;
13210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                oDns2 = mDhcpInfo.dns2;
13220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            checkUseStaticIp();
13240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mWifiInfo.getSupplicantState() == SupplicantState.UNINITIALIZED) {
13260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return;
13270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            boolean changed =
13300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                (wasStaticIp != mUseStaticIp) ||
13310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    (wasStaticIp && (
13320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        oIp   != mDhcpInfo.ipAddress ||
13330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        oGw   != mDhcpInfo.gateway ||
13340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        oMsk  != mDhcpInfo.netmask ||
13350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        oDns1 != mDhcpInfo.dns1 ||
13360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        oDns2 != mDhcpInfo.dns2));
13370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (changed) {
13390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                sendMessage(CMD_RECONFIGURE_IP);
13400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mConfigChanged = true;
13410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Whether to disable coexistence mode while obtaining IP address. This
13470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * logic will return true only if the current bluetooth
13480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * headset/handsfree state is disconnected. This means if it is in an
13490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * error state, we will NOT disable coexistence mode to err on the side
13500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * of safety.
13510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
13520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return Whether to disable coexistence mode.
13530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean shouldDisableCoexistenceMode() {
13550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int state = mBluetoothHeadset.getState(mBluetoothHeadset.getCurrentHeadset());
13560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return state == BluetoothHeadset.STATE_DISCONNECTED;
13570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void checkIsBluetoothPlaying() {
13600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        boolean isBluetoothPlaying = false;
13610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Set<BluetoothDevice> connected = mBluetoothA2dp.getConnectedSinks();
13620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (BluetoothDevice device : connected) {
13640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mBluetoothA2dp.getSinkState(device) == BluetoothA2dp.STATE_PLAYING) {
13650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                isBluetoothPlaying = true;
13660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break;
13670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setBluetoothScanMode(isBluetoothPlaying);
13700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
13730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!ActivityManagerNative.isSystemReady()) return;
13740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
13760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
13790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!ActivityManagerNative.isSystemReady()) return;
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
13820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
13830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
13840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
13870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
13880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
13890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_PROPERTIES, mNetworkProperties);
13920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
13940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
13950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendConfigChangeBroadcast() {
13980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.CONFIG_CHANGED_ACTION);
13990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_PROPERTIES, mNetworkProperties);
14000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
14010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantStateChangedBroadcast(StateChangeResult sc, boolean failedAuth) {
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
14050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
14070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable)sc.state);
14080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (failedAuth) {
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(
14100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiManager.EXTRA_SUPPLICANT_ERROR,
14110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiManager.ERROR_AUTHENTICATING);
14120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
14140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1416e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private void sendSupplicantConfigChangedBroadcast() {
1417e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION);
1418e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        mContext.sendBroadcast(intent);
1419e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
1420e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
14210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
14220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!ActivityManagerNative.isSystemReady()) return;
14230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
14250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
14260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
14270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
14310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param state the new @{code DetailedState}
14320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
14330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setDetailedState(NetworkInfo.DetailedState state) {
14340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "setDetailed state, old ="
14350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                + mNetworkInfo.getDetailedState() + " and new state=" + state);
14360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
14370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkInfo.setDetailedState(state, null, null);
14380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static String removeDoubleQuotes(String string) {
14420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (string.length() <= 2) return "";
14430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      return string.substring(1, string.length() - 1);
14440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static String convertToQuotedString(String string) {
14470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return "\"" + string + "\"";
14480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static String makeString(BitSet set, String[] strings) {
14510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        StringBuffer buf = new StringBuffer();
14520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int nextSetBit = -1;
14530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Make sure all set bits are in [0, strings.length) to avoid
14550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * going out of bounds on strings.  (Shouldn't happen, but...) */
14560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        set = set.get(0, strings.length);
14570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
14590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
14600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // remove trailing space
14630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (set.cardinality() > 0) {
14640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            buf.setLength(buf.length() - 1);
14650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return buf.toString();
14680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static int lookupString(String string, String[] strings) {
14710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int size = strings.length;
14720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        string = string.replace('-', '_');
14740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int i = 0; i < size; i++)
14760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (string.equals(strings[i]))
14770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return i;
14780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // if we ever get here, we should probably add the
14800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // value to WifiConfiguration to reflect that it's
14810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // supported by the WPA supplicant
14820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.w(TAG, "Failed to look-up a string: " + string);
14830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return -1;
14850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1487e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    private void enableAllNetworks() {
1488e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        if (mEnableAllNetworks) {
1489e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            mEnableAllNetworks = false;
1490e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            List<WifiConfiguration> configList = getConfiguredNetworksNative();
1491e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            for (WifiConfiguration config : configList) {
1492e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                if(config != null && config.status == Status.DISABLED) {
1493e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.enableNetworkCommand(config.networkId, false);
1494e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                }
1495e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            }
1496e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiNative.saveConfigCommand();
1497e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            sendSupplicantConfigChangedBroadcast();
1498e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        }
1499e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
1500e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
15010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int addOrUpdateNetworkNative(WifiConfiguration config) {
15020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
15030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * If the supplied networkId is -1, we create a new empty
15040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * network configuration. Otherwise, the networkId should
15050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * refer to an existing configuration.
15060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
15070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int netId = config.networkId;
15080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        boolean newNetwork = netId == -1;
15090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // networkId of -1 means we want to create a new network
15100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newNetwork) {
15120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            netId = WifiNative.addNetworkCommand();
15130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (netId < 0) {
15140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.e(TAG, "Failed to add a network!");
15150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return -1;
15160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
15170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setVariables: {
15200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.SSID != null &&
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.ssidVarName,
15250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        config.SSID)) {
15260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set SSID: "+config.SSID);
15270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.BSSID != null &&
15310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.bssidVarName,
15340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        config.BSSID)) {
15350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set BSSID: "+config.BSSID);
15360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String allowedKeyManagementString =
15400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
15410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.allowedKeyManagement.cardinality() != 0 &&
15420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.KeyMgmt.varName,
15450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedKeyManagementString)) {
15460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set key_mgmt: "+
15470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedKeyManagementString);
15480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String allowedProtocolsString =
15520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                makeString(config.allowedProtocols, WifiConfiguration.Protocol.strings);
15530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.allowedProtocols.cardinality() != 0 &&
15540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.Protocol.varName,
15570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedProtocolsString)) {
15580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set proto: "+
15590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedProtocolsString);
15600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String allowedAuthAlgorithmsString =
15640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                makeString(config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.strings);
15650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.allowedAuthAlgorithms.cardinality() != 0 &&
15660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.AuthAlgorithm.varName,
15690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedAuthAlgorithmsString)) {
15700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set auth_alg: "+
15710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedAuthAlgorithmsString);
15720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String allowedPairwiseCiphersString =
15760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    makeString(config.allowedPairwiseCiphers,
15770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiConfiguration.PairwiseCipher.strings);
15780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.allowedPairwiseCiphers.cardinality() != 0 &&
15790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.PairwiseCipher.varName,
15820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedPairwiseCiphersString)) {
15830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set pairwise: "+
15840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedPairwiseCiphersString);
15850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String allowedGroupCiphersString =
15890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                makeString(config.allowedGroupCiphers, WifiConfiguration.GroupCipher.strings);
15900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.allowedGroupCiphers.cardinality() != 0 &&
15910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
15920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
15930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.GroupCipher.varName,
15940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedGroupCiphersString)) {
15950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set group: "+
15960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        allowedGroupCiphersString);
15970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
15980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // Prevent client screw-up by passing in a WifiConfiguration we gave it
16010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // by preventing "*" as a key.
16020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.preSharedKey != null && !config.preSharedKey.equals("*") &&
16030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    !WifiNative.setNetworkVariableCommand(
16040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
16050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.pskVarName,
16060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        config.preSharedKey)) {
16070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "failed to set psk: "+config.preSharedKey);
16080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
16090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            boolean hasSetKey = false;
16120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.wepKeys != null) {
16130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                for (int i = 0; i < config.wepKeys.length; i++) {
16140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Prevent client screw-up by passing in a WifiConfiguration we gave it
16150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // by preventing "*" as a key.
16160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
16170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (!WifiNative.setNetworkVariableCommand(
16180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    netId,
16190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    WifiConfiguration.wepKeyVarNames[i],
16200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    config.wepKeys[i])) {
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG,
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    "failed to set wep_key"+i+": " +
16230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    config.wepKeys[i]);
16240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break setVariables;
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
16260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        hasSetKey = true;
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (hasSetKey) {
16320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (!WifiNative.setNetworkVariableCommand(
16330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            netId,
16340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            WifiConfiguration.wepTxKeyIdxVarName,
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Integer.toString(config.wepTxKeyIndex))) {
16360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,
16370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            "failed to set wep_tx_keyidx: "+
16380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            config.wepTxKeyIndex);
16390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break setVariables;
16400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!WifiNative.setNetworkVariableCommand(
16440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
16450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.priorityVarName,
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Integer.toString(config.priority))) {
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, config.SSID + ": failed to set priority: "
16480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        +config.priority);
16490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
16500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (config.hiddenSSID && !WifiNative.setNetworkVariableCommand(
16530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        netId,
16540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiConfiguration.hiddenSSIDVarName,
16550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Integer.toString(config.hiddenSSID ? 1 : 0))) {
16560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, config.SSID + ": failed to set hiddenSSID: "+
16570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        config.hiddenSSID);
16580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                break setVariables;
16590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            for (WifiConfiguration.EnterpriseField field
16620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    : config.enterpriseFields) {
16630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String varName = field.varName();
16640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String value = field.value();
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (value != null) {
16660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (field != config.eap) {
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        value = (value.length() == 0) ? "NULL" : convertToQuotedString(value);
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (!WifiNative.setNetworkVariableCommand(
16700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                netId,
16710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                varName,
16720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                value)) {
16730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, config.SSID + ": failed to set " + varName +
16740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                ": " + value);
16750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break setVariables;
16760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
16770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
16780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
16790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return netId;
16800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newNetwork) {
16830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            WifiNative.removeNetworkCommand(netId);
16840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.d(TAG,
16850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    "Failed to set a network variable, removed network: "
16860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    + netId);
16870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return -1;
16900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private List<WifiConfiguration> getConfiguredNetworksNative() {
16930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String listStr = WifiNative.listNetworksCommand();
1694e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        mLastPriority = 0;
16950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<WifiConfiguration> networks =
16960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new ArrayList<WifiConfiguration>();
16970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (listStr == null)
16980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return networks;
16990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String[] lines = listStr.split("\n");
17010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Skip the first line, which is a header
17020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int i = 1; i < lines.length; i++) {
17030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String[] result = lines[i].split("\t");
17040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // network-id | ssid | bssid | flags
17050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            WifiConfiguration config = new WifiConfiguration();
17060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
17070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.networkId = Integer.parseInt(result[0]);
17080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch(NumberFormatException e) {
17090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                continue;
17100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (result.length > 3) {
17120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (result[3].indexOf("[CURRENT]") != -1)
17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.status = WifiConfiguration.Status.CURRENT;
17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                else if (result[3].indexOf("[DISABLED]") != -1)
17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.status = WifiConfiguration.Status.DISABLED;
17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                else
17170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.status = WifiConfiguration.Status.ENABLED;
17180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
17190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.status = WifiConfiguration.Status.ENABLED;
17200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            readNetworkVariables(config);
1722e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            if (config.priority > mLastPriority) {
1723e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                mLastPriority = config.priority;
1724e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            }
17250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            networks.add(config);
17260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return networks;
17280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
17310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Read the variables from the supplicant daemon that are needed to
17320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * fill in the WifiConfiguration object.
17330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
17340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param config the {@link WifiConfiguration} object to be filled in.
17350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
17360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void readNetworkVariables(WifiConfiguration config) {
17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int netId = config.networkId;
17390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (netId < 0)
17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
17410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
17430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * TODO: maybe should have a native method that takes an array of
17440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * variable names and returns an array of values. But we'd still
17450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * be doing a round trip to the supplicant daemon for each variable.
17460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
17470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String value;
17480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.ssidVarName);
17500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            config.SSID = removeDoubleQuotes(value);
17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
17530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            config.SSID = null;
17540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.bssidVarName);
17570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
17580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            config.BSSID = value;
17590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
17600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            config.BSSID = null;
17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.priorityVarName);
17640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        config.priority = -1;
17650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
17660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
17670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.priority = Integer.parseInt(value);
17680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch (NumberFormatException ignore) {
17690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.hiddenSSIDVarName);
17730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        config.hiddenSSID = false;
17740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
17750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
17760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.hiddenSSID = Integer.parseInt(value) != 0;
17770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch (NumberFormatException ignore) {
17780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.wepTxKeyIdxVarName);
17820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        config.wepTxKeyIndex = -1;
17830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
17840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
17850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.wepTxKeyIndex = Integer.parseInt(value);
17860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch (NumberFormatException ignore) {
17870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int i = 0; i < 4; i++) {
17910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            value = WifiNative.getNetworkVariableCommand(netId,
17920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiConfiguration.wepKeyVarNames[i]);
17930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!TextUtils.isEmpty(value)) {
17940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.wepKeys[i] = value;
17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.wepKeys[i] = null;
17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.pskVarName);
18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
18020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            config.preSharedKey = value;
18030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
18040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            config.preSharedKey = null;
18050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(config.networkId,
18080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiConfiguration.Protocol.varName);
18090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
18100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String vals[] = value.split(" ");
18110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            for (String val : vals) {
18120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                int index =
18130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lookupString(val, WifiConfiguration.Protocol.strings);
18140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (0 <= index) {
18150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.allowedProtocols.set(index);
18160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
18170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(config.networkId,
18210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiConfiguration.KeyMgmt.varName);
18220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
18230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String vals[] = value.split(" ");
18240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            for (String val : vals) {
18250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                int index =
18260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lookupString(val, WifiConfiguration.KeyMgmt.strings);
18270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (0 <= index) {
18280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.allowedKeyManagement.set(index);
18290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
18300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(config.networkId,
18340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiConfiguration.AuthAlgorithm.varName);
18350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
18360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String vals[] = value.split(" ");
18370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            for (String val : vals) {
18380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                int index =
18390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lookupString(val, WifiConfiguration.AuthAlgorithm.strings);
18400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (0 <= index) {
18410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.allowedAuthAlgorithms.set(index);
18420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
18430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(config.networkId,
18470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiConfiguration.PairwiseCipher.varName);
18480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
18490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String vals[] = value.split(" ");
18500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            for (String val : vals) {
18510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                int index =
18520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lookupString(val, WifiConfiguration.PairwiseCipher.strings);
18530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (0 <= index) {
18540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.allowedPairwiseCiphers.set(index);
18550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
18560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        value = WifiNative.getNetworkVariableCommand(config.networkId,
18600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiConfiguration.GroupCipher.varName);
18610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!TextUtils.isEmpty(value)) {
18620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            String vals[] = value.split(" ");
18630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            for (String val : vals) {
18640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                int index =
18650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lookupString(val, WifiConfiguration.GroupCipher.strings);
18660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (0 <= index) {
18670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    config.allowedGroupCiphers.set(index);
18680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
18690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (WifiConfiguration.EnterpriseField field :
18730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                config.enterpriseFields) {
18740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            value = WifiNative.getNetworkVariableCommand(netId,
18750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    field.varName());
18760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!TextUtils.isEmpty(value)) {
18770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (field != config.eap) value = removeDoubleQuotes(value);
18780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                field.setValue(value);
18790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
18800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
18810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
18830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
18840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
18850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Poll for info not reported via events
18860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * RSSI & Linkspeed
18870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
18880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void requestPolledInfo() {
18890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int newRssi = WifiNative.getRssiCommand();
18900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
18910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* some implementations avoid negative values by adding 256
18920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * so we need to adjust for that here.
18930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
18940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (newRssi > 0) newRssi -= 256;
18950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mWifiInfo.setRssi(newRssi);
18960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
18970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Rather then sending the raw RSSI out every time it
18980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * changes, we precalculate the signal level that would
18990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * be displayed in the status bar, and only send the
19000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * broadcast if that much more coarse-grained number
19010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * changes. This cuts down greatly on the number of
19020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * broadcasts, at the cost of not mWifiInforming others
19030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * interested in RSSI of all the changes in signal
19040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * level.
19050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
19060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // TODO: The second arg to the call below needs to be a symbol somewhere, but
19070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // it's actually the size of an array of icons that's private
19080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // to StatusBar Policy.
19090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
19100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
19110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                sendRssiChangeBroadcast(newRssi);
19120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mLastSignalLevel = newSignalLevel;
19140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
19150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mWifiInfo.setRssi(-200);
19160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int newLinkSpeed = WifiNative.getLinkSpeedCommand();
19180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newLinkSpeed != -1) {
19190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
19200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
19240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
19250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
19260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
19270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
19280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Log.d(TAG, "Reset connections and stopping DHCP");
19290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
19310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Reset connections & stop DHCP
19320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
19330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.resetConnections(mInterfaceName);
19340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (!NetworkUtils.stopDhcp(mInterfaceName)) {
19360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, "Could not stop DHCP");
19370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Disable interface */
19400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        NetworkUtils.disableInterface(mInterfaceName);
19410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* send event to CM & network change broadcast */
19430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setDetailedState(DetailedState.DISCONNECTED);
19440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
19450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
19470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setIpAddress(0);
19480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
19490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
19500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setNetworkId(-1);
19510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
19530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkProperties.clear();
19540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
19560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastNetworkId = -1;
19570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
19620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Notifications from WifiMonitor
19630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
19640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
19660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * A structure for supplying information about a supplicant state
19670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * change in the STATE_CHANGE event message that comes from the
19680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * WifiMonitor
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * thread.
19700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
19710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static class StateChangeResult {
19720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        StateChangeResult(int networkId, String BSSID, Object state) {
19730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.state = state;
19740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.BSSID = BSSID;
19750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            this.networkId = networkId;
19760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int networkId;
19780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        String BSSID;
19790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Object state;
19800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
19830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a user-entered password key
19840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * may be incorrect (i.e., caused authentication to fail).
19850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
19860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyPasswordKeyMayBeIncorrect() {
19870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
19880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
19910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a connection to the supplicant
19920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * daemon has been established.
19930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
19940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantConnection() {
19950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_CONNECTION_EVENT);
19960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
19990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a connection to the supplicant
20000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * daemon has been established.
20010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
20020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantLost() {
20030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SUP_DISCONNECTION_EVENT);
20040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
20070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of Wifi connectivity
20080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
20090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
20100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new network state
20110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param BSSID when the new state is {@link DetailedState#CONNECTED
20120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * NetworkInfo.DetailedState.CONNECTED},
20130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * this is the MAC address of the access point. Otherwise, it
20140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * is {@code null}.
20150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
20160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyNetworkStateChange(DetailedState newState, String BSSID, int networkId) {
20170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (newState == NetworkInfo.DetailedState.CONNECTED) {
20180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(NETWORK_CONNECTION_EVENT,
20190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    new StateChangeResult(networkId, BSSID, newState)));
20200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
20210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(NETWORK_DISCONNECTION_EVENT,
20220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    new StateChangeResult(networkId, BSSID, newState)));
20230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
20270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that the state of the supplicant
20280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * has changed.
20290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId the configured network on which the state change occurred
20300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param newState the new {@code SupplicantState}
20310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
20320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifySupplicantStateChange(int networkId, String BSSID, SupplicantState newState) {
20330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
20340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                new StateChangeResult(networkId, BSSID, newState)));
20350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
20380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Send the tracker a notification that a scan has completed, and results
20390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * are available.
20400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
20410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyScanResultsAvailable() {
20420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
20430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Switch scan mode over to passive.
20440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * Turning off scan-only mode happens only in "Connect" mode
20450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
20460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setScanType(false);
20470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(SCAN_RESULTS_EVENT);
20480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStarted() {
20510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_START_EVENT);
20520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverStopped() {
20550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(DRIVER_STOP_EVENT);
20560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    void notifyDriverHung() {
20590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(false);
20600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setWifiEnabled(true);
20610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
20650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
20660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
20670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DefaultState extends HierarchicalState {
20690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
20710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
20720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SyncParams syncParams;
20730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
20740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
20750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
20760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
20770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
20780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
20790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
20800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_RSSI:
20810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_RSSI_APPROX:
20820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_LINK_SPEED:
20830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_MAC_ADDR:
20840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
20850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CONNECTION_STATUS:
20860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_NETWORK_CONFIG:
20870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg2 == SYNCHRONOUS_CALL) {
20880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams = (SyncParams) message.obj;
20890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.boolValue = false;
20900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.intValue = -1;
20910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.stringValue = null;
20920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.configList = null;
20930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        notifyOnMsgObject(message);
20940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
20950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
20970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
20980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_ENABLE_RSSI_POLL);
20990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
21010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
21020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
21030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
21040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
21050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
21060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
21080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
2109e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
2110e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
2111e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
2112e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONFIGURE_IP:
21140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
21150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
21170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
21180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
21190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
21200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
21210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
21220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
21240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
21250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
21260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
21280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
21290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
21300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
21310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
2132e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2133e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
2134e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG, "Error! unhandled message" + message);
21380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class InitialState extends HierarchicalState {
21450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
21470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
21490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
21500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
21510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
21520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (WifiNative.isDriverLoaded()) {
21550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
21560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
21580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
21590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadingState extends HierarchicalState {
21640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
21670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
21700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
21710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
21720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
21730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
21740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
21750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
21760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sWakeLock.acquire();
21770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
21780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
21790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
21800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
21810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
21820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
21830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
21840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
21850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.loadDriver()) {
21880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver load successful");
21890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
21900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to load driver!");
21920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
21930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
21940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
21950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
21970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
21980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
22000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
22010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sWakeLock.release();
22030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
22040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
22050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
22110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
22120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
22130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
22150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
22160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
22190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
22210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
22220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
22240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
22260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
22270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
22280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
22290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
22300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
22310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
22340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverLoadedState extends HierarchicalState {
22440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
22540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
22550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
22570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.startSupplicant()) {
22580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Supplicant start successful");
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
22600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        setWifiState(WIFI_STATE_ENABLED);
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mWaitForSupState);
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to start supplicant!");
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
22650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
22680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.startAccessPoint((WifiConfiguration) message.obj,
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
22710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in startAccessPoint()");
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
22750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
22760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Soft AP start successful");
22780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
22790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mSoftApStartedState);
22800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadingState extends HierarchicalState {
22900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
22930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
22960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
22970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
22980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
22990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
23000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sWakeLock.acquire();
23010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if(WifiNative.unloadDriver()) {
23020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Driver unload successful");
23030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
23040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
23060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
23070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
23080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
23090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
23100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
23110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
23120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
23130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
23140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
23150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
23160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Failed to unload driver!");
23170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
23180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
23200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
23210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
23220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
23230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
23240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
23250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
23260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
23270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
23280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
23290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
23300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sWakeLock.release();
23310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
23320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
23330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
23380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
23390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
23400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
23410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
23430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
23440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
23460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
23470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
23480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
23490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
23500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
23510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
23520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
23530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
23540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
23550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
23560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
23570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
23580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
23590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
23600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
23610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
23620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
23640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
23660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
23670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
23680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverUnloadedState extends HierarchicalState {
23720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
23750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
23800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
23810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
23820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadingState);
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 DriverFailedState extends HierarchicalState {
23930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            Log.e(TAG, getName() + "\n");
23960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
24000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
24010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
24020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
24040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class WaitForSupState extends HierarchicalState {
24070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
24100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
24110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
24140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
24150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
24160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_CONNECTION_EVENT:
24170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Supplicant connection established");
24180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.resetSupplicantState();
24190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
24200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
24210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = -1;
24220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
24230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
24250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //TODO: initialize and fix multicast filtering
24270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //mWM.initializeMulticastFiltering();
24280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (mBluetoothA2dp == null) {
24300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mBluetoothA2dp = new BluetoothA2dp(mContext);
24310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
24320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    checkIsBluetoothPlaying();
24330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    checkUseStaticIp();
24350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
24360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverSupReadyState);
24370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
24390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Stop supplicant received");
24400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopSupplicant();
24410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
24420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Fail soft ap when waiting for supplicant start */
24440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
24450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
24460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
24470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
24490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
24500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
24510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
24520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
24530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
24540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
24550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
24560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
24570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
24580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
24590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
24610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
24620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
24630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
24650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
24660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
24670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
24680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
24690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
24710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverSupReadyState extends HierarchicalState {
24730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
24760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
24770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
24780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
24820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
24830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SyncParams syncParams;
2484e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
24850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
24860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
24870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Stop supplicant received");
24880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopSupplicant();
24890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //$FALL-THROUGH$
24900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUP_DISCONNECTION_EVENT:  /* Supplicant died */
24910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
24920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.closeSupplicantConnection();
24930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
24940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
24950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.resetSupplicantState();
24960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
24970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
24980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* When supplicant dies, unload driver and enter failed state */
24990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //TODO: consider bringing up supplicant again
25000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.what == SUP_DISCONNECTION_EVENT) {
25010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.d(TAG, "Supplicant died, unloading driver");
25020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
25030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
25040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
25060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.startDriverCommand();
25080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStartingState);
25090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
25110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setScanResults(WifiNative.scanResultsCommand());
25120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendScanResultsAvailableBroadcast();
25130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
25150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
25160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.boolValue = WifiNative.pingCommand();
25170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
25180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
25200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
2522e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) syncParams.mParameter;
25230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.intValue = addOrUpdateNetworkNative(config);
25240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
2525e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    sendSupplicantConfigChangedBroadcast();
25260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
25280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg2 == SYNCHRONOUS_CALL) {
25300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams = (SyncParams) message.obj;
25310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.boolValue = WifiNative.removeNetworkCommand(
25320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                message.arg1);
25330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        notifyOnMsgObject(message);
25340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
25350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* asynchronous handling */
25360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.removeNetworkCommand(message.arg1);
25370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
2538e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    sendSupplicantConfigChangedBroadcast();
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
25410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg2 == SYNCHRONOUS_CALL) {
25430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams = (SyncParams) message.obj;
25440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        EnableNetParams enableNetParams = (EnableNetParams) syncParams.mParameter;
25450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.boolValue = WifiNative.enableNetworkCommand(
25460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                enableNetParams.netId, enableNetParams.disableOthers);
25470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        notifyOnMsgObject(message);
25480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
25490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* asynchronous handling */
25500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.enableNetworkCommand(message.arg1, message.arg2 == 1);
25510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
2552e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    sendSupplicantConfigChangedBroadcast();
25530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
25550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg2 == SYNCHRONOUS_CALL) {
25570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams = (SyncParams) message.obj;
25580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.boolValue = WifiNative.disableNetworkCommand(
25590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                message.arg1);
25600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        notifyOnMsgObject(message);
25610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
25620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* asynchronous handling */
25630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.disableNetworkCommand(message.arg1);
25640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
2565e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    sendSupplicantConfigChangedBroadcast();
25660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
25680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.addToBlacklistCommand((String)message.obj);
25700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
25720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.clearBlacklistCommand();
25730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_NETWORK_CONFIG:
25750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.configList = getConfiguredNetworksNative();
25770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
25780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
25800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg2 == SYNCHRONOUS_CALL) {
25810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams = (SyncParams) message.obj;
25820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        syncParams.mSyncReturn.boolValue = WifiNative.saveConfigCommand();
25830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        notifyOnMsgObject(message);
25840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
25850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* asynchronous handling */
25860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.saveConfigCommand();
25870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
25880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
25890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
25900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
25910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
25920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
25930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
25940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
25950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
25960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
25970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
25980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CONNECTION_STATUS:
26000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
26010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.stringValue = WifiNative.statusCommand();
26020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
26030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_MAC_ADDR:
26050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
26060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.stringValue = WifiNative.getMacAddressCommand();
26070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
26080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
26100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
26110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
26120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
26130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
26140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
26160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
26170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2618e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
2619e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
2620e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = addOrUpdateNetworkNative(config);
2621e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    /* enable a new network */
2622e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config.networkId < 0) {
2623e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                        WifiNative.enableNetworkCommand(netId, false);
2624e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2625e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.saveConfigCommand();
2626e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    sendSupplicantConfigChangedBroadcast();
2627e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
2628e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
2629e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.removeNetworkCommand(message.arg1);
2630e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.saveConfigCommand();
2631e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    sendSupplicantConfigChangedBroadcast();
2632e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
26330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
26340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
26350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
26360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
26370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartingState extends HierarchicalState {
26410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
26440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
26450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
26490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
26500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_START_EVENT:
26510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStartedState);
26520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
26540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
26550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
26560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
26570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
26580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
26590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
26600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
26610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
26620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
26630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
26640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
26650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
26660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
26670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
26680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
26690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
26700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2671e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
26720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
26740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
26750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
26760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
26770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
26780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStartedState extends HierarchicalState {
26820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
26850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
26860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
26880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mBatteryStats.noteWifiRunning();
26890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch (RemoteException ignore) {}
26900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize channel count */
26920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            setNumAllowedChannels();
26930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
26940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
26950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
26960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.disconnectCommand();
26970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
26980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
26990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
27000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* If supplicant has already connected, before we could finish establishing
27010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * the control channel connection, we miss all the supplicant events.
27020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * Disconnect and reconnect when driver has started to ensure we receive
27030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * all supplicant events.
27040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 *
27050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * TODO: This is a bit unclean, ideally the supplicant should never
27060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * connect until told to do so by the framework
27070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 */
27080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.disconnectCommand();
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiNative.reconnectCommand();
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mConnectModeState);
27110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SyncParams syncParams;
27170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
27180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
27190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ACTIVE) {
27200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(true);
27210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
27220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanModeCommand(false);
27230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
27260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setPowerModeCommand(message.arg1);
27270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
27290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(message.arg1);
27300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
27320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceScanModeCommand(message.arg1 == 1);
27330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
27350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mNumAllowedChannels = message.arg1;
27360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setNumAllowedChannelsCommand(message.arg1);
27370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
27390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore another driver start */
27400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
27420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopDriverCommand();
27430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppingState);
27440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REQUEST_CM_WAKELOCK:
27460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (mCm == null) {
27470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mCm = (ConnectivityManager)mContext.getSystemService(
27480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                Context.CONNECTIVITY_SERVICE);
27490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mCm.requestNetworkTransitionWakelock(TAG);
27510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
27530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.startPacketFiltering();
27540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
27560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.stopPacketFiltering();
27570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
27660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            try {
27680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mBatteryStats.noteWifiStopped();
27690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } catch (RemoteException ignore) { }
2770f99819e47cbef2ec066a21b426c7e6fe95e3de48Irfan Sheriff            mScanResults = null;
27710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
27740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppingState extends HierarchicalState {
27750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
27780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
27830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
27840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DRIVER_STOP_EVENT:
27850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppedState);
27860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
27880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
27890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
27900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
27910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_POWER_MODE:
27920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_COEXISTENCE:
27930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_BLUETOOTH_SCAN_MODE:
27940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_NUM_ALLOWED_CHANNELS:
27950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
27960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
27970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
27980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
27990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
28000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2801e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
28020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
28110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DriverStoppedState extends HierarchicalState {
28120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
28210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
28240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ScanModeState extends HierarchicalState {
28250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SyncParams syncParams;
28340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
28350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
28360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
28370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
28380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
28390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
28400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
28410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.reconnectCommand();
28420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
28430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
28440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
28450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
2847e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
28480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
28500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
28510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
28520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
28530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
28540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
28550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
28560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
28650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectModeState extends HierarchicalState {
28660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
28680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
28690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
28700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
28720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
28730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
28740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SyncParams syncParams;
28750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
28760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
28770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case PASSWORD_MAY_BE_INCORRECT_EVENT:
28780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mPasswordKeyMayBeIncorrect = true;
28790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SUPPLICANT_STATE_CHANGE_EVENT:
28810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
28820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.handleEvent(stateChangeResult);
28830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
28850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* We need to set scan type in completed state */
28860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Message newMsg = obtainMessage();
28870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    newMsg.copyFrom(message);
28880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mSupplicantStateTracker.sendMessage(newMsg);
28890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
28910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2892e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
28930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2895e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reconnectCommand();
28960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
2898e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.reassociateCommand();
28990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2900e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2901e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
2902e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
2903e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
2904e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                        netId = addOrUpdateNetworkNative(config);
2905e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2906e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    // Reset the priority of each network at start or if it goes too high.
2907e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (mLastPriority == -1 || mLastPriority > 1000000) {
2908e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                        List<WifiConfiguration> configList = getConfiguredNetworksNative();
2909e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                        for (WifiConfiguration conf : configList) {
2910e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                            if (conf.networkId != -1) {
2911e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                                conf.priority = 0;
2912e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                                addOrUpdateNetworkNative(conf);
2913e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                            }
2914e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                        }
2915e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                        mLastPriority = 0;
2916e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2917e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
2918e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    // Set to the highest priority and save the configuration.
2919e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = new WifiConfiguration();
2920e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config.networkId = netId;
2921e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config.priority = ++mLastPriority;
2922e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
2923e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    addOrUpdateNetworkNative(config);
2924e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.saveConfigCommand();
2925e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
2926e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    // Connect to network by disabling others.
2927e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.enableNetworkCommand(netId, true);
2928e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiNative.reconnectCommand();
2929e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    mEnableAllNetworks = true;
2930e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    /* Dont send a supplicant config change broadcast here
2931e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                     * as it is better to not expose the temporary disabling
2932e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                     * of all networks
2933e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                     */
2934e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
29350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCAN_RESULTS_EVENT:
29360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
29370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
29380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
29390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
29400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
29410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection established");
29420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    stateChangeResult = (StateChangeResult) message.obj;
29430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2944cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    //TODO: make supplicant modification to push this in events
2945cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    mWifiInfo.setSSID(fetchSSID());
29460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid = stateChangeResult.BSSID);
29470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
29480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastNetworkId = stateChangeResult.networkId;
2949e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    enableAllNetworks();
29500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
29510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setDetailedState(DetailedState.OBTAINING_IPADDR);
29520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
29530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
29550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
29570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Network connection lost");
2958e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    enableAllNetworks();
29590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
29600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
29610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_RSSI:
29630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
29640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.intValue = WifiNative.getRssiCommand();
29650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
29660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_RSSI_APPROX:
29680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
29690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.intValue = WifiNative.getRssiApproxCommand();
29700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
29710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_GET_LINK_SPEED:
29730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams = (SyncParams) message.obj;
29740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    syncParams.mSyncReturn.intValue = WifiNative.getLinkSpeedCommand();
29750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    notifyOnMsgObject(message);
29760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
29780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
29790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
29800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
29810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
29820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
29830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
29840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectingState extends HierarchicalState {
29860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        boolean modifiedBluetoothCoexistenceMode;
29870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int powerMode;
29880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Thread mDhcpThread;
29890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
29910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
29920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
29930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
29940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (!mUseStaticIp) {
29960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = null;
29980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                modifiedBluetoothCoexistenceMode = false;
29990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                powerMode = DRIVER_POWER_MODE_AUTO;
30000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (shouldDisableCoexistenceMode()) {
30020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
30030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * There are problems setting the Wi-Fi driver's power
30040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode to active when bluetooth coexistence mode is
30050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * enabled or sense.
30060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
30070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * We set Wi-Fi to active mode when
30080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address because we've found
30090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * compatibility issues with some routers with low power
30100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * mode.
30110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * <p>
30120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * In order for this active power mode to properly be set,
30130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * we disable coexistence mode until we're done with
30140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * obtaining an IP address.  One exception is if we
30150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * are currently connected to a headset, since disabling
30160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * coexistence would interrupt that connection.
30170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
30180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    modifiedBluetoothCoexistenceMode = true;
30190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Disable the coexistence mode
30210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setBluetoothCoexistenceModeCommand(
30220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
30230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
30240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                powerMode =  WifiNative.getPowerModeCommand();
30260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (powerMode < 0) {
30270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Handle the case where supplicant driver does not support
30280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // getPowerModeCommand.
30290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    powerMode = DRIVER_POWER_MODE_AUTO;
30300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
30310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (powerMode != DRIVER_POWER_MODE_ACTIVE) {
30320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    WifiNative.setPowerModeCommand(DRIVER_POWER_MODE_ACTIVE);
30330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
30340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Log.d(TAG, "DHCP request started");
30360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread = new Thread(new Runnable() {
30370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    public void run() {
30380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {
30390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request succeeded");
30400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_SUCCESS);
30410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
30420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Log.d(TAG, "DHCP request failed: " +
30430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    NetworkUtils.getDhcpError());
30440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessage(CMD_IP_CONFIG_FAILURE);
30450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
30460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
30470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                });
30480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mDhcpThread.start();
30490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
30500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (NetworkUtils.configureInterface(mInterfaceName, mDhcpInfo)) {
30510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration succeeded");
30520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_SUCCESS);
30530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
30540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.v(TAG, "Static IP configuration failed");
30550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_IP_CONFIG_FAILURE);
30560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
30570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
30580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         }
30590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
30600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public boolean processMessage(Message message) {
30610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
30620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          switch(message.what) {
30640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_SUCCESS:
30650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mReconnectCount = 0;
30660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mLastSignalLevel = -1; // force update of signal strength
30670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
30680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  Log.d(TAG, "IP configuration: " + mDhcpInfo);
30690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  configureNetworkProperties();
30700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  setDetailedState(DetailedState.CONNECTED);
30710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  sendNetworkStateChangeBroadcast(mLastBssid);
30720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  //TODO: we could also detect an IP config change
30730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // from a DHCP renewal and send out a config change
30740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // broadcast
30750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (mConfigChanged) {
30760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendConfigChangeBroadcast();
30770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      mConfigChanged = false;
30780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
30790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mConnectedState);
30800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
30810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_IP_CONFIG_FAILURE:
30820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  mWifiInfo.setIpAddress(0);
30830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  Log.e(TAG, "IP configuration failed");
30850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /**
30860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * If we've exceeded the maximum number of retries for DHCP
30870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * to a given network, disable the network
30880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
30890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (++mReconnectCount > getMaxDhcpRetries()) {
30900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          Log.e(TAG, "Failed " +
30910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                  mReconnectCount + " times, Disabling " + mLastNetworkId);
30920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      WifiNative.disableNetworkCommand(mLastNetworkId);
3093e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                      sendSupplicantConfigChangedBroadcast();
30940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
30950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
30960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* DHCP times out after about 30 seconds, we do a
30970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   * disconnect and an immediate reconnect to try again
30980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                   */
30990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.disconnectCommand();
31000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.reconnectCommand();
31010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
31020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
31030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_DISCONNECT:
3104e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                  WifiNative.disconnectCommand();
31050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
31060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
31070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* Ignore */
31080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case NETWORK_CONNECTION_EVENT:
31090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
31100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_STOP_DRIVER:
31110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  sendMessage(CMD_DISCONNECT);
31120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  deferMessage(message);
31130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
31140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_SET_SCAN_MODE:
31150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (message.arg1 == SCAN_ONLY_MODE) {
31160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendMessage(CMD_DISCONNECT);
31170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      deferMessage(message);
31180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
31190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
31200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_RECONFIGURE_IP:
31210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  deferMessage(message);
31220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
31230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              default:
31240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return NOT_HANDLED;
31250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
31260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
31270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          return HANDLED;
31280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
31290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
31300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
31310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public void exit() {
31320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          /* reset power state & bluetooth coexistence if on DHCP */
31330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          if (!mUseStaticIp) {
31340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              if (powerMode != DRIVER_POWER_MODE_ACTIVE) {
31350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.setPowerModeCommand(powerMode);
31360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
31370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
31380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              if (modifiedBluetoothCoexistenceMode) {
31390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  // Set the coexistence mode back to its default value
31400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  WifiNative.setBluetoothCoexistenceModeCommand(
31410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
31420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              }
31430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
31440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
31450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
31460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
31470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
31480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class ConnectedState extends HierarchicalState {
31490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
31510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
31520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
31530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
31540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
31560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
31570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
31580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
3159e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    WifiNative.disconnectCommand();
31600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
31610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONFIGURE_IP:
31630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Reconfiguring IP on connection");
31640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    NetworkUtils.resetConnections(mInterfaceName);
31650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
31660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
31680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendMessage(CMD_DISCONNECT);
31690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
31700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
31720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
31730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
31740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
31750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
31760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
31780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_CONNECTION_EVENT:
31790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
31810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
31820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
31830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
31840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
31850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
31860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
31870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
31880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectingState extends HierarchicalState {
31890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
31910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
31920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
31930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
31940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
31960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
31970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
31980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
31990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
32000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
32020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
32030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
32040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
32050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
32070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
32080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
32090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
32100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
32110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
32130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
32140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class DisconnectedState extends HierarchicalState {
32150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
32170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
32180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
32190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
32220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
32230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
32240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
32250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
32260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(message.arg1);
32270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
32280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.disconnectCommand();
32290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
32300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
32310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
32320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
32340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case NETWORK_DISCONNECTION_EVENT:
32350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
32370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
32380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
32390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
32400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
32410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
32430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
32440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SoftApStartedState extends HierarchicalState {
32450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
32470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + "\n");
32480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
32490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
32520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
32530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
32540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
32550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"Stopping Soft AP");
32560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
32570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
32580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.stopAccessPoint();
32590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
32600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in stopAccessPoint()");
32610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
32620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
32630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
32650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.d(TAG,"SoftAP set on a running access point");
32660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
32670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        nwService.setAccessPoint((WifiConfiguration) message.obj,
32680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    mInterfaceName,
32690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    SOFTAP_IFACE);
32700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
32710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        Log.e(TAG, "Exception in nwService during soft AP set");
32720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
32730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            nwService.stopAccessPoint();
32740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception ee) {
32750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            Slog.e(TAG, "Could not stop AP, :" + ee);
32760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
32770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
32780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
32790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* Fail client mode operation when soft AP is enabled */
32810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
32820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    Log.e(TAG,"Cannot start supplicant with a running soft AP");
32830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
32840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
32860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
32870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
32880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
32890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
32900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
32920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
32930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
32940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    class SupplicantStateTracker extends HierarchicalStateMachine {
32950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
32960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private int mRssiPollToken = 0;
32970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
32980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
32990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * The max number of the WPA supplicant loop iterations before we
33000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * decide that the loop should be terminated:
33010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
33020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int MAX_SUPPLICANT_LOOP_ITERATIONS = 4;
33030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private int mLoopDetectIndex = 0;
33040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private int mLoopDetectCount = 0;
33050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /**
33070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         *  Supplicant state change commands follow
33080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         *  the ordinal values defined in SupplicantState.java
33090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
33100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int DISCONNECTED           = 0;
33110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int INACTIVE               = 1;
33120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int SCANNING               = 2;
33130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int ASSOCIATING            = 3;
33140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int ASSOCIATED             = 4;
33150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int FOUR_WAY_HANDSHAKE     = 5;
33160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int GROUP_HANDSHAKE        = 6;
33170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int COMPLETED              = 7;
33180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int DORMANT                = 8;
33190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int UNINITIALIZED          = 9;
33200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private static final int INVALID                = 10;
33210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mUninitializedState = new UninitializedState();
33230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mInitializedState = new InitializedState();;
33240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mInactiveState = new InactiveState();
33250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mDisconnectState = new DisconnectedState();
33260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mScanState = new ScanState();
33270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mConnectState = new ConnectState();
33280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mHandshakeState = new HandshakeState();
33290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mCompletedState = new CompletedState();
33300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private HierarchicalState mDormantState = new DormantState();
33310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public SupplicantStateTracker(Context context, Handler target) {
33330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            super(TAG, target.getLooper());
33340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mUninitializedState);
33360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitializedState);
33370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mInactiveState, mInitializedState);
33380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDisconnectState, mInitializedState);
33390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mScanState, mInitializedState);
33400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mConnectState, mInitializedState);
33410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mHandshakeState, mConnectState);
33420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mCompletedState, mConnectState);
33430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDormantState, mInitializedState);
33440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            setInitialState(mUninitializedState);
33460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            //start the state machine
33480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            start();
33490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
33500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void handleEvent(StateChangeResult stateChangeResult) {
33520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SupplicantState newState = (SupplicantState) stateChangeResult.state;
33530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // Supplicant state change
33550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-13] Reserved for future use
33560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [8 - 0] Supplicant state (as defined in SupplicantState.java)
33570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50023 supplicant_state_changed (custom|1|5)
33580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, newState.ordinal());
33590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(newState.ordinal(), stateChangeResult));
33610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
33620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void resetSupplicantState() {
33640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            transitionTo(mUninitializedState);
33650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
33660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private void resetLoopDetection() {
33680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mLoopDetectCount = 0;
33690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mLoopDetectIndex = 0;
33700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
33710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
33720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        private boolean handleTransition(Message msg) {
33730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (DBG) Log.d(TAG, getName() + msg.toString() + "\n");
33740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (msg.what) {
33750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DISCONNECTED:
33760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectState);
33770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case SCANNING:
33790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mScanState);
33800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case ASSOCIATING:
33820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
33830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* BSSID is valid only in ASSOCIATING state */
33840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mWifiInfo.setBSSID(stateChangeResult.BSSID);
33850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //$FALL-THROUGH$
33860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case ASSOCIATED:
33870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case FOUR_WAY_HANDSHAKE:
33880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case GROUP_HANDSHAKE:
33890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mHandshakeState);
33900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case COMPLETED:
33920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mCompletedState);
33930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case DORMANT:
33950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDormantState);
33960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case INACTIVE:
33980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mInactiveState);
33990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
34000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case UNINITIALIZED:
34010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case INVALID:
34020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mUninitializedState);
34030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
34040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
34050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
34060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
34080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            SupplicantState supState = (SupplicantState) stateChangeResult.state;
34090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            setDetailedState(WifiInfo.getDetailedStateOf(supState));
34100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mWifiInfo.setSupplicantState(supState);
34110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mWifiInfo.setNetworkId(stateChangeResult.networkId);
34120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
34130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
34140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /********************************************************
34160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         * HSM states
34170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         *******************************************************/
34180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class InitializedState extends HierarchicalState {
34200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
34220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
34230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
34240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
34260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
34270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                switch (message.what) {
34280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case CMD_START_SCAN:
34290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
34300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
34310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    default:
34320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (DBG) Log.w(TAG, "Ignoring " + message);
34330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
34340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
34350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return HANDLED;
34360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
34380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class UninitializedState extends HierarchicalState {
34400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
34420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
34430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mNetworkInfo.setIsAvailable(false);
34440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 resetLoopDetection();
34450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mPasswordKeyMayBeIncorrect = false;
34460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
34470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
34490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                switch(message.what) {
34500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    default:
34510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (!handleTransition(message)) {
34520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            if (DBG) Log.w(TAG, "Ignoring " + message);
34530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
34540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
34550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
34560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return HANDLED;
34570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public void exit() {
34600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mNetworkInfo.setIsAvailable(true);
34610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
34630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class InactiveState extends HierarchicalState {
34650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
34670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
34680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 Message message = getCurrentMessage();
34690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
34700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mNetworkInfo.setIsAvailable(false);
34720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 resetLoopDetection();
34730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mPasswordKeyMayBeIncorrect = false;
34740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 sendSupplicantStateChangedBroadcast(stateChangeResult, false);
34760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
34770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
34790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return handleTransition(message);
34800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public void exit() {
34830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mNetworkInfo.setIsAvailable(true);
34840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
34860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class DisconnectedState extends HierarchicalState {
34890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
34900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
34910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
34920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 Message message = getCurrentMessage();
34930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
34940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 resetLoopDetection();
34960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
34970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 /* If a disconnect event happens after a password key failure
34980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  * event, disable the network
34990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  */
35000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (mPasswordKeyMayBeIncorrect) {
35010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     Log.d(TAG, "Failed to authenticate, disabling network " +
35020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                             mWifiInfo.getNetworkId());
35030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     WifiNative.disableNetworkCommand(mWifiInfo.getNetworkId());
35040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     mPasswordKeyMayBeIncorrect = false;
35050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     sendSupplicantStateChangedBroadcast(stateChangeResult, true);
3506e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                     sendSupplicantConfigChangedBroadcast();
35070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 }
35080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 else {
35090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     sendSupplicantStateChangedBroadcast(stateChangeResult, false);
35100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 }
35110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
35120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
35140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return handleTransition(message);
35150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
35160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
35170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class ScanState extends HierarchicalState {
35190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
35210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
35220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 Message message = getCurrentMessage();
35230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
35240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mPasswordKeyMayBeIncorrect = false;
35260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 resetLoopDetection();
35270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 sendSupplicantStateChangedBroadcast(stateChangeResult, false);
35280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
35290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
35310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return handleTransition(message);
35320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
35330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
35340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class ConnectState extends HierarchicalState {
35360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
35380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
35390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
35400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
35420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                switch (message.what) {
35430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case CMD_START_SCAN:
35440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
35450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
35460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
35470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    default:
35480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return NOT_HANDLED;
35490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
35500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return HANDLED;
35510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
35520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
35530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class HandshakeState extends HierarchicalState {
35550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
35570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
35580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 final Message message = getCurrentMessage();
35590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
35600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (mLoopDetectIndex > message.what) {
35620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     mLoopDetectCount++;
35630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 }
35640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) {
35650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     WifiNative.disableNetworkCommand(stateChangeResult.networkId);
3566e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                     sendSupplicantConfigChangedBroadcast();
35670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     mLoopDetectCount = 0;
35680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 }
35690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mLoopDetectIndex = message.what;
35710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mPasswordKeyMayBeIncorrect = false;
35730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 sendSupplicantStateChangedBroadcast(stateChangeResult, false);
35740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
35750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
35770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return handleTransition(message);
35780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
35790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
35800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class CompletedState extends HierarchicalState {
35820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
35830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             public void enter() {
35840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (DBG) Log.d(TAG, getName() + "\n");
35850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 Message message = getCurrentMessage();
35860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
35870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mRssiPollToken++;
35890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 if (mEnableRssiPolling) {
35900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
35910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                             POLL_RSSI_INTERVAL_MSECS);
35920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 }
35930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 resetLoopDetection();
35950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 mPasswordKeyMayBeIncorrect = false;
35970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 sendSupplicantStateChangedBroadcast(stateChangeResult, false);
35980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             }
35990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
36000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
36010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                switch(message.what) {
36020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case ASSOCIATING:
36030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case ASSOCIATED:
36040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case FOUR_WAY_HANDSHAKE:
36050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case GROUP_HANDSHAKE:
36060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case COMPLETED:
36070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
36080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case CMD_RSSI_POLL:
36090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (message.arg1 == mRssiPollToken) {
36100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Get Info and continue polling
36110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            requestPolledInfo();
36120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
36130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    POLL_RSSI_INTERVAL_MSECS);
36140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
36150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Polling has completed
36160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
36170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
36180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    case CMD_ENABLE_RSSI_POLL:
36190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mRssiPollToken++;
36200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (mEnableRssiPolling) {
36210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // first poll
36220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            requestPolledInfo();
36230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
36240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    POLL_RSSI_INTERVAL_MSECS);
36250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
36260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        break;
36270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    default:
36280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return handleTransition(message);
36290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
36300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return HANDLED;
36310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
36320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
36330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
36340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        class DormantState extends HierarchicalState {
36350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
36360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public void enter() {
36370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (DBG) Log.d(TAG, getName() + "\n");
36380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                Message message = getCurrentMessage();
36390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
36400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
36410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                resetLoopDetection();
36420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                mPasswordKeyMayBeIncorrect = false;
36430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
36440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                sendSupplicantStateChangedBroadcast(stateChangeResult, false);
36450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
36460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                /* TODO: reconnect is now being handled at DHCP failure handling
36470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * If we run into issues with staying in Dormant state, might
36480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 * need a reconnect here
36490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                 */
36500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
36510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            @Override
36520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            public boolean processMessage(Message message) {
36530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return handleTransition(message);
36540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
36550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
36560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
36570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
3658