WifiStateMachine.java revision fc7f95abcda6fa35c175f9225358ea75c22952ab
10d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/*
20d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Copyright (C) 2010 The Android Open Source Project
30d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
40d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License");
50d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * you may not use this file except in compliance with the License.
60d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * You may obtain a copy of the License at
70d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
80d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *      http://www.apache.org/licenses/LICENSE-2.0
90d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Unless required by applicable law or agreed to in writing, software
110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS,
120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * See the License for the specific language governing permissions and
140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * limitations under the License.
150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffpackage android.net.wifi;
180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * TODO: Add soft AP states as part of WIFI_STATE_XXX
270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Retain WIFI_STATE_ENABLING that indicates driver is loading
280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Add WIFI_STATE_AP_ENABLED to indicate soft AP has started
290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and WIFI_STATE_FAILED for failure
300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Deprecate WIFI_STATE_UNKNOWN
310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Doing this will simplify the logic for sending broadcasts
330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
40090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.AlarmManager;
41090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.PendingIntent;
4234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.app.backup.IBackupManager;
4334ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.bluetooth.BluetoothAdapter;
4434ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.BroadcastReceiver;
4534ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.Context;
4634ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.Intent;
4734ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.IntentFilter;
4834ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.ConnectivityManager;
490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.DhcpInfo;
500216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwaltimport android.net.DhcpInfoInternal;
5131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriffimport android.net.DhcpStateMachine;
5227d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwaltimport android.net.InterfaceConfiguration;
5334ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.LinkAddress;
5434ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.LinkProperties;
5534ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.NetworkInfo;
560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
5727d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwaltimport android.net.NetworkUtils;
58e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriffimport android.net.wifi.WpsResult.Status;
5955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pManager;
60f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport android.net.wifi.p2p.WifiP2pService;
6155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.StateChangeResult;
620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Binder;
630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.IBinder;
640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.INetworkManagementService;
6534ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.Message;
66ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.os.Messenger;
670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.PowerManager;
6834ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.Process;
690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.RemoteException;
700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.ServiceManager;
718dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levyimport android.os.SystemClock;
7234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.SystemProperties;
7303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackbornimport android.os.WorkSource;
740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.provider.Settings;
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.EventLog;
760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Log;
7734ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.util.LruCache;
78090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport com.android.internal.app.IBatteryStats;
804b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Savilleimport com.android.internal.util.AsyncChannel;
813fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriffimport com.android.internal.util.Protocol;
8264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.State;
8364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.StateMachine;
840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriffimport java.net.InetAddress;
860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.ArrayList;
870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.List;
880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.concurrent.atomic.AtomicInteger;
89b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriffimport java.util.concurrent.atomic.AtomicBoolean;
900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport java.util.regex.Pattern;
910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff/**
930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Track the state of Wifi connectivity. All event handling is done here,
940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * and all changes in connectivity state are initiated here.
950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff *
9655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Wi-Fi now supports three modes of operation: Client, Soft Ap and Direct
9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * In the current implementation, we do not support any concurrency and thus only
9855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * one of Client, Soft Ap or Direct operation is supported at any time.
9955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
10055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * The WifiStateMachine supports Soft Ap and Client operations while WifiP2pService
10155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * handles Direct. WifiP2pService and WifiStateMachine co-ordinate to ensure only
10255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * one exists at a certain time.
10355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
1040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @hide
1050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
10664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savillepublic class WifiStateMachine extends StateMachine {
1070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String TAG = "WifiStateMachine";
1090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String NETWORKTYPE = "WIFI";
1100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final boolean DBG = false;
1110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    /* TODO: This is no more used with the hostapd code. Clean up */
1130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String SOFTAP_IFACE = "wl0.1";
1140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiMonitor mWifiMonitor;
116fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private WifiNative mWifiNative;
117fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private WifiConfigStore mWifiConfigStore;
118cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    private INetworkManagementService mNwService;
1190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ConnectivityManager mCm;
1200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results handling */
1220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private List<ScanResult> mScanResults;
1230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final Pattern scanResultPattern = Pattern.compile("\t+");
1240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULT_CACHE_SIZE = 80;
12534ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilson    private final LruCache<String, ScanResult> mScanResultCache;
1260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mInterfaceName;
128c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Tethering interface could be seperate from wlan interface */
129c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private String mTetherInterfaceName;
1300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastSignalLevel = -1;
1320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mLastBssid;
1330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastNetworkId;
1340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mEnableRssiPolling = false;
135fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    private boolean mEnableBackgroundScan = false;
13619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private int mRssiPollToken = 0;
1370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mReconnectCount = 0;
1380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mIsScanMode = false;
139fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    private boolean mScanResultIsPending = false;
1401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Tracks if the current scan settings are active */
1411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    private boolean mSetScanActive = false;
1420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    private boolean mBluetoothConnectionActive = false;
14465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff
1450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
14619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Interval in milliseconds between polling for RSSI
14719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * and linkspeed information
14819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
14919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
15019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
15119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /**
15296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Delay between supplicant restarts upon failure to establish connection
15396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
15496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;
15596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
15696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /**
15796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Number of times we attempt to restart supplicant
15896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
15996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_TRIES = 5;
16096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
16196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private int mSupplicantRestartCount = 0;
162cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    /* Tracks sequence number on stop failure message */
163cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    private int mSupplicantStopFailureToken = 0;
16496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
165c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /**
166c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff     * Tether state change notification time out
167c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff     */
168c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
169c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
170c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Tracks sequence number on a tether notification time out */
171c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private int mTetherToken = 0;
172c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
17337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private LinkProperties mLinkProperties;
1740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1754f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    // Wakelock held during wifi start/stop and driver load/unload
1764f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    private PowerManager.WakeLock mWakeLock;
1770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private Context mContext;
1790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1800216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    private DhcpInfoInternal mDhcpInfoInternal;
1810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiInfo mWifiInfo;
1820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkInfo mNetworkInfo;
1830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SupplicantStateTracker mSupplicantStateTracker;
18402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    private WpsStateMachine mWpsStateMachine;
18531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private DhcpStateMachine mDhcpStateMachine;
18602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
187090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private AlarmManager mAlarmManager;
188090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private PendingIntent mScanIntent;
18936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Tracks current frequency mode */
19036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
191090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
192b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /* Tracks if we are filtering Multicast v4 packets. Default is to filter. */
193b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    private AtomicBoolean mFilteringMulticastV4Packets = new AtomicBoolean(true);
194b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
1954b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    // Channel for sending replies.
1964b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    private AsyncChannel mReplyChannel = new AsyncChannel();
1974b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private WifiP2pManager mWifiP2pManager;
19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    //Used to initiate a connection with WifiP2pService
20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private AsyncChannel mWifiP2pChannel = new AsyncChannel();
2019575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    private AsyncChannel mWifiApConfigChannel = new AsyncChannel();
20255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Event log tags (must be in sync with event-log-tags)
2040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
2050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
2060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED  = 50023;
2070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2083fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    /* The base for wifi message types */
2093fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int BASE = Protocol.BASE_WIFI;
2100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Load the driver */
2113fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_LOAD_DRIVER                      = BASE + 1;
2120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unload the driver */
2133fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_UNLOAD_DRIVER                    = BASE + 2;
2140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load succeeded */
2153fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_LOAD_DRIVER_SUCCESS              = BASE + 3;
2160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load failed */
2173fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_LOAD_DRIVER_FAILURE              = BASE + 4;
2180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload succeeded */
2193fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_UNLOAD_DRIVER_SUCCESS            = BASE + 5;
2200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload failed */
2213fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_UNLOAD_DRIVER_FAILURE            = BASE + 6;
2220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the supplicant */
2243fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_SUPPLICANT                 = BASE + 11;
2250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the supplicant */
2263fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_STOP_SUPPLICANT                  = BASE + 12;
2270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
2283fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_DRIVER                     = BASE + 13;
229e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    /* Stop the driver */
2303fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_STOP_DRIVER                      = BASE + 14;
23131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    /* Indicates Static IP succeded */
23231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    static final int CMD_STATIC_IP_SUCCESS                = BASE + 15;
23331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    /* Indicates Static IP failed */
23431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    static final int CMD_STATIC_IP_FAILURE                = BASE + 16;
235cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    /* Indicates supplicant stop failed */
236cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    static final int CMD_STOP_SUPPLICANT_FAILED           = BASE + 17;
237e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    /* Delayed stop to avoid shutting down driver too quick*/
238e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    static final int CMD_DELAYED_STOP_DRIVER              = BASE + 18;
239e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff
2400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the soft access point */
2423fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_AP                         = BASE + 21;
2437dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Indicates soft ap start succeded */
2447dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_START_AP_SUCCESS                 = BASE + 22;
2457dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Indicates soft ap start failed */
2467dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_START_AP_FAILURE                 = BASE + 23;
2470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the soft access point */
2487dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_STOP_AP                          = BASE + 24;
249ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    /* Set the soft access point configuration */
2507dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_SET_AP_CONFIG                    = BASE + 25;
2519575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    /* Soft access point configuration set completed */
2529575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    static final int CMD_SET_AP_CONFIG_COMPLETED          = BASE + 26;
2539575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    /* Request the soft access point configuration */
2549575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    static final int CMD_REQUEST_AP_CONFIG                = BASE + 27;
2559575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    /* Response to access point configuration request */
2569575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    static final int CMD_RESPONSE_AP_CONFIG               = BASE + 28;
257c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Invoked when getting a tether state change notification */
258c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    static final int CMD_TETHER_STATE_CHANGE              = BASE + 29;
259c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* A delayed message sent to indicate tether state change failed to arrive */
260c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    static final int CMD_TETHER_NOTIFICATION_TIMED_OUT    = BASE + 30;
2610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
262c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 31;
2630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands */
2650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Is supplicant alive ? */
2663fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_PING_SUPPLICANT                  = BASE + 51;
2670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Add/update a network configuration */
2683fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ADD_OR_UPDATE_NETWORK            = BASE + 52;
2690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Delete a network */
2703fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_REMOVE_NETWORK                   = BASE + 53;
2710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable a network. The device will attempt a connection to the given network. */
2723fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_NETWORK                   = BASE + 54;
2738e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    /* Enable all networks */
2743fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_ALL_NETWORKS              = BASE + 55;
2750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disable a network. The device does not attempt a connection to the given network. */
2763fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_DISABLE_NETWORK                  = BASE + 56;
2770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Blacklist network. De-prioritizes the given BSSID for connection. */
2783fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_BLACKLIST_NETWORK                = BASE + 57;
2790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear the blacklist network list */
2803fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_CLEAR_BLACKLIST                  = BASE + 58;
2810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Save configuration */
2823fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SAVE_CONFIG                      = BASE + 59;
283e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff    /* Get configured networks*/
284e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff    static final int CMD_GET_CONFIGURED_NETWORKS          = BASE + 60;
2850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands after driver start*/
2870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Initiate a scan */
2883fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_SCAN                       = BASE + 71;
2890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
2903fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_SCAN_MODE                    = BASE + 72;
2910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
2923fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_SCAN_TYPE                    = BASE + 73;
2930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disconnect from a network */
2943fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_DISCONNECT                       = BASE + 74;
2950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reconnect to a network */
2963fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RECONNECT                        = BASE + 75;
2970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reassociate to a network */
2983fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_REASSOCIATE                      = BASE + 76;
2995876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    /* Controls power mode and suspend mode optimizations
3005876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
3015876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * When high perf mode is enabled, power mode is set to
3025876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * POWER_MODE_ACTIVE and suspend mode optimizations are disabled
3035876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
3045876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * When high perf mode is disabled, power mode is set to
3055876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * POWER_MODE_AUTO and suspend mode optimizations are enabled
3065876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
3075876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Suspend mode optimizations include:
3085876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - packet filtering
3095876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - turn off roaming
3105876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - DTIM wake up settings
3110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3123fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_HIGH_PERF_MODE               = BASE + 77;
313ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /* Set the country code */
3143fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_COUNTRY_CODE                 = BASE + 80;
3150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enables RSSI poll */
3163fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_RSSI_POLL                 = BASE + 82;
3170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* RSSI poll */
3183fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RSSI_POLL                        = BASE + 83;
3190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set up packet filtering */
3203fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_PACKET_FILTERING           = BASE + 84;
3210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear packet filter */
3223fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_STOP_PACKET_FILTERING            = BASE + 85;
323b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
324b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /* arg1 values to CMD_STOP_PACKET_FILTERING and CMD_START_PACKET_FILTERING */
325b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    static final int MULTICAST_V6  = 1;
326b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    static final int MULTICAST_V4  = 0;
327b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
328e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Connect to a specified network (network id
329e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * or WifiConfiguration) This involves increasing
330e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * the priority of the network, enabling the network
331e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * (while disabling others) and issuing a reconnect.
332e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * Note that CMD_RECONNECT just does a reconnect to
333e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an existing network. All the networks get enabled
334e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * upon a successful connection or a failure.
335e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
3363fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_CONNECT_NETWORK                  = BASE + 86;
337e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Save the specified network. This involves adding
338e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * an enabled network (if new) and updating the
339e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * config and issuing a save on supplicant config.
340e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
3413fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SAVE_NETWORK                     = BASE + 87;
342e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    /* Delete the specified network. This involves
343e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * removing the network and issuing a save on
344e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     * supplicant config.
345e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff     */
3463fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_FORGET_NETWORK                   = BASE + 88;
34702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Start Wi-Fi protected setup */
3483fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_WPS                        = BASE + 89;
34936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Set the frequency band */
3503fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_FREQUENCY_BAND               = BASE + 90;
351fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    /* Enable background scan for configured networks */
3523fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_BACKGROUND_SCAN           = BASE + 91;
353ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
354b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Commands from/to the SupplicantStateTracker */
355b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Reset the supplicant state tracker */
3563fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RESET_SUPPLICANT_STATE           = BASE + 111;
357b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff
35802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Commands/events reported by WpsStateMachine */
35902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Indicates the completion of WPS activity */
3603fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int WPS_COMPLETED_EVENT                  = BASE + 121;
361e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff    /* Reset the WPS state machine */
3623fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RESET_WPS_STATE                  = BASE + 122;
36302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
36455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Interaction with WifiP2pService */
36555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int WIFI_ENABLE_PENDING           = BASE + 131;
36655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_ENABLE_PROCEED            = BASE + 132;
36755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CONNECT_MODE   = 1;
3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ONLY_MODE = 2;
3700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ACTIVE = 1;
3720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_PASSIVE = 2;
3730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3741406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int SUCCESS = 1;
3751406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int FAILURE = -1;
3761406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
3774494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    /* Phone in emergency call back mode */
3784494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    private static final int IN_ECM_STATE = 1;
3794494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    private static final int NOT_IN_ECM_STATE = 0;
3804494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff
3810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * The maximum number of times we will retry a connection to an access point
3830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * for which we have failed in acquiring an IP address from DHCP. A value of
3840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * N means that we will make N+1 connection attempts in all.
3850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * <p>
3860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
3870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * value if a Settings value is not present.
3880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
3900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
39131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    static final int POWER_MODE_ACTIVE = 1;
39231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    static final int POWER_MODE_AUTO = 0;
39331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
39431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    /* Tracks the power mode for restoration after a DHCP request/renewal goes through */
39531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private int mPowerMode = POWER_MODE_AUTO;
3960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
397090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    /**
3982b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * Default framework scan interval in milliseconds. This is used in the scenario in which
3992b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * wifi chipset does not support background scanning to set up a
4002b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * periodic wake up scan so that the device can connect to a new access
4012b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * point on the move. {@link Settings.Secure#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
4022b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * override this.
403090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     */
4042b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    private final int mDefaultFrameworkScanIntervalMs;
4052b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
4062b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    /**
4072b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * Default supplicant scan interval in milliseconds.
4082b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} can override this.
4092b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     */
4102b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    private final int mDefaultSupplicantScanIntervalMs;
4112b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
4120f43161150903a008a5fd703078cdf446601160aIrfan Sheriff    /**
4130f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     * Minimum time interval between enabling all networks.
4140f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     * A device can end up repeatedly connecting to a bad network on screen on/off toggle
4150f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     * due to enabling every time. We add a threshold to avoid this.
4160f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     */
4170f43161150903a008a5fd703078cdf446601160aIrfan Sheriff    private static final int MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS = 10 * 60 * 1000; /* 10 minutes */
4180f43161150903a008a5fd703078cdf446601160aIrfan Sheriff    private long mLastEnableAllNetworksTime;
4190f43161150903a008a5fd703078cdf446601160aIrfan Sheriff
420e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    /**
421e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff     * Starting and shutting down driver too quick causes problems leading to driver
422e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff     * being in a bad state. Delay driver stop.
423e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff     */
424e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    private static final int DELAYED_DRIVER_STOP_MS = 2 * 60 * 1000; /* 2 minutes */
425e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    private int mDelayedStopCounter;
426e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    private boolean mInDelayedStop = false;
427090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
4289b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff    private static final int MIN_RSSI = -200;
4299b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff    private static final int MAX_RSSI = 256;
4309b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff
4310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Default parent state */
43264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDefaultState = new DefaultState();
4330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Temporary initial state */
43464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mInitialState = new InitialState();
4350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unloading the driver */
43664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverUnloadingState = new DriverUnloadingState();
4370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Loading the driver */
43864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverUnloadedState = new DriverUnloadedState();
4390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver load/unload failed */
44064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverFailedState = new DriverFailedState();
4410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loading */
44264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverLoadingState = new DriverLoadingState();
4430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded */
44464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverLoadedState = new DriverLoadedState();
4450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded, waiting for supplicant to start */
44664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSupplicantStartingState = new SupplicantStartingState();
4470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded and supplicant ready */
44864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSupplicantStartedState = new SupplicantStartedState();
44996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /* Waiting for supplicant to stop and monitor to exit */
45064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSupplicantStoppingState = new SupplicantStoppingState();
4510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start issued, waiting for completed event */
45264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStartingState = new DriverStartingState();
4530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver started */
45464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStartedState = new DriverStartedState();
4550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopping */
45664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStoppingState = new DriverStoppingState();
4570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopped */
45864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStoppedState = new DriverStoppedState();
4590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan for networks, no connection will be established */
46064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mScanModeState = new ScanModeState();
4610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connecting to an access point */
46264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mConnectModeState = new ConnectModeState();
4630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Fetching IP after network connection (assoc+auth complete) */
46464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mConnectingState = new ConnectingState();
4650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connected with IP addr */
46664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mConnectedState = new ConnectedState();
4670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* disconnect issued, waiting for network disconnect confirmation */
46864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDisconnectingState = new DisconnectingState();
4690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network is not connected, supplicant assoc+auth is not complete */
47064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDisconnectedState = new DisconnectedState();
47102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Waiting for WPS to be completed*/
47264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mWaitForWpsCompletionState = new WaitForWpsCompletionState();
4730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4747dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Soft ap is starting up */
4757dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    private State mSoftApStartingState = new SoftApStartingState();
47623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    /* Soft ap is running */
47764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSoftApStartedState = new SoftApStartedState();
478c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Soft ap is running and we are waiting for tether notification */
479c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private State mTetheringState = new TetheringState();
48023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    /* Soft ap is running and we are tethered through connectivity service */
48123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    private State mTetheredState = new TetheredState();
482c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Waiting for untether confirmation to stop soft Ap */
483c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private State mSoftApStoppingState = new SoftApStoppingState();
4840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
48555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Wait till p2p is disabled */
48655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private State mWaitForP2pDisableState = new WaitForP2pDisableState();
48755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
488c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private class TetherStateChange {
489c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        ArrayList<String> available;
490c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        ArrayList<String> active;
491c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
492c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            available = av;
493c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            active = ac;
494c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
495c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
496c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
4970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
4990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
5000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_DISABLING},
5010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLED},
5020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLING},
5030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
5040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
5050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
5070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
5100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
5110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
5120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
5130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
5140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
5150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastEnableUid = new AtomicInteger(Process.myUid());
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastApEnableUid = new AtomicInteger(Process.myUid());
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
521090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final int SCAN_REQUEST = 0;
522090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final String ACTION_START_SCAN =
523090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        "com.android.server.WifiManager.action.START_SCAN";
524090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
52503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
52603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether WIFI is running.
52703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
52803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mIsRunning = false;
5295ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
53003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
53103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether we last told the battery stats we had started.
53203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
53303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mReportedRunning = false;
53403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
53503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
53603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Most recently set source of starting WIFI.
53703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
53803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mRunningWifiUids = new WorkSource();
53903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
54003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
54103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * The last reported UIDs that were responsible for starting WIFI.
54203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
54303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mLastRunningWifiUids = new WorkSource();
54403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
5450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final IBatteryStats mBatteryStats;
5460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
547227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff    public WifiStateMachine(Context context, String wlanInterface) {
5480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        super(TAG);
5490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext = context;
551227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff        mInterfaceName = wlanInterface;
5520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
5540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
5550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
557cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
5580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
559fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative = new WifiNative(mInterfaceName);
560fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
561fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiMonitor = new WifiMonitor(this, mWifiNative);
5620216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        mDhcpInfoInternal = new DhcpInfoInternal();
5630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo = new WifiInfo();
564fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,
565fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                getHandler());
566fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWpsStateMachine = new WpsStateMachine(context, this, mWifiConfigStore, getHandler());
56737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties = new LinkProperties();
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5699575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
5709575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                context, getHandler());
5719575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        wifiApConfigStore.loadApConfiguration();
5729575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        mWifiApConfigChannel.connectSync(mContext, getHandler(), wifiApConfigStore.getMessenger());
5739575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff
5740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo.setIsAvailable(false);
57537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid = null;
5770a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastSignalLevel = -1;
5790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
580090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
581090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        Intent scanIntent = new Intent(ACTION_START_SCAN, null);
582090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
583090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
5842b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger(
5852b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                com.android.internal.R.integer.config_wifi_framework_scan_interval);
5862b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
5872b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        mDefaultSupplicantScanIntervalMs = mContext.getResources().getInteger(
5882b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                com.android.internal.R.integer.config_wifi_supplicant_scan_interval);
5892b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
590090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mContext.registerReceiver(
59143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            new BroadcastReceiver() {
59243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                @Override
59343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                public void onReceive(Context context, Intent intent) {
59443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    ArrayList<String> available = intent.getStringArrayListExtra(
59543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            ConnectivityManager.EXTRA_AVAILABLE_TETHER);
596c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    ArrayList<String> active = intent.getStringArrayListExtra(
597c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                            ConnectivityManager.EXTRA_ACTIVE_TETHER);
598c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
59943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                }
60043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
60143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
60243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        mContext.registerReceiver(
603090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new BroadcastReceiver() {
604090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    @Override
605090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    public void onReceive(Context context, Intent intent) {
606090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        startScan(false);
607090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    }
608090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                },
609090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new IntentFilter(ACTION_START_SCAN));
610090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
61134ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilson        mScanResultCache = new LruCache<String, ScanResult>(SCAN_RESULT_CACHE_SIZE);
6120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
6144f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
6150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
6170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
6180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
6190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
6200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
6210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
6220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
62396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartingState, mDefaultState);
62496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartedState, mDefaultState);
62596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartingState, mSupplicantStartedState);
62696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartedState, mSupplicantStartedState);
6270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
6280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
6290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectingState, mConnectModeState);
6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mConnectedState, mConnectModeState);
6310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
6320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
63302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                        addState(mWaitForWpsCompletionState, mConnectModeState);
63496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppingState, mSupplicantStartedState);
63596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppedState, mSupplicantStartedState);
63696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStoppingState, mDefaultState);
6377dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            addState(mSoftApStartingState, mDefaultState);
6380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
639c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                addState(mTetheringState, mSoftApStartedState);
64023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                addState(mTetheredState, mSoftApStartedState);
641c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            addState(mSoftApStoppingState, mDefaultState);
64255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            addState(mWaitForP2pDisableState, mDefaultState);
6430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
6450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
6470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
6490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
6500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
6530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
6540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
6550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6591406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncPingSupplicant(AsyncChannel channel) {
6601406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
6611406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
6621406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
6631406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
6640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
669e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
670e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
671e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
6720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
6780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
6790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
6800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
6810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
6820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
6850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
6870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
6880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
6890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
6920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
6930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
6950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
6960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
6970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
6980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
6990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
7000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
7020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
7030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
7040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
706ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    public void setWifiApConfiguration(WifiConfiguration config) {
7079575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
708ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    }
709ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff
7109575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    public WifiConfiguration syncGetWifiApConfiguration() {
7119575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        Message resultMsg = mWifiApConfigChannel.sendMessageSynchronously(CMD_REQUEST_AP_CONFIG);
712ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff        WifiConfiguration ret = (WifiConfiguration) resultMsg.obj;
713ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff        resultMsg.recycle();
714ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff        return ret;
715ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    }
716ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff
7170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
720d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiState() {
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
7220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
727d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiStateByName() {
7280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
7290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
7300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
7310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
7320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
7330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
7340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
7350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
7360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
7370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
7380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
7390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
7400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
7410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
7420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
747d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiApState() {
7480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
7490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
754d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiApStateByName() {
7550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
7560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
7570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
7580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
7590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
7600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
7610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
7620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
7630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
7660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
7670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
7680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
7690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
776d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public WifiInfo syncRequestConnectionInfo() {
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
780d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public DhcpInfo syncGetDhcpInfo() {
7810216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        synchronized (mDhcpInfoInternal) {
7820216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            return mDhcpInfoInternal.makeDhcpInfo();
78331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
7840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7894494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    public void setDriverStart(boolean enable, boolean ecm) {
7904f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        if (enable) {
7914f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_START_DRIVER);
7924f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        } else {
7934494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff            sendMessage(obtainMessage(CMD_STOP_DRIVER, ecm ? IN_ECM_STATE : NOT_IN_ECM_STATE, 0));
7944f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        }
7950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
8010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
8020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
8030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
8040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
8050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
8060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
8120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
8130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
8140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
8150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
8160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
8170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
822d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<ScanResult> syncGetScanResultsList() {
8230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mScanResults;
8240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
8280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
829e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
830e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
8310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
8350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
836e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
837e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
8380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
8420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
843e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
844e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
8450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
8490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
8510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8521406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
8531406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
8541406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        int result = resultMsg.arg1;
8551406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
8561406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
8570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
859e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff    public List<WifiConfiguration> syncGetConfiguredNetworks(AsyncChannel channel) {
860e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONFIGURED_NETWORKS);
861e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
862e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        resultMsg.recycle();
863e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        return result;
8640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
8680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
8700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8714b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
8724b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
8731406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
8744b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        resultMsg.recycle();
8754b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        return result;
8764b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    }
8774b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
8784b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    /**
8790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
8800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
8820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
8830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
8840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8851406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
8861406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
8871406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                disableOthers ? 1 : 0);
8881406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
8891406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
8901406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8991406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
9008dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId,
9018dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy                WifiConfiguration.DISABLED_UNKNOWN_REASON);
9021406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9031406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9041406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
9090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
9100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
9120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
9140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
9150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
9190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
9220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
9230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
925e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(int netId) {
926e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, netId, 0));
927e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
928e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
929e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void connectNetwork(WifiConfiguration wifiConfig) {
9300a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        /* arg1 is used to indicate netId, force a netId value of
9310a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff         * WifiConfiguration.INVALID_NETWORK_ID when we are passing
9320a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff         * a configuration since the default value of 0 is a valid netId
933a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff         */
9340a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        sendMessage(obtainMessage(CMD_CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
9350a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff                0, wifiConfig));
936e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
937e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
938e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void saveNetwork(WifiConfiguration wifiConfig) {
939e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_SAVE_NETWORK, wifiConfig));
940e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
941e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
942e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    public void forgetNetwork(int netId) {
943e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff        sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
944e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff    }
945e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
9468dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy    public void disableNetwork(Messenger replyTo, int netId, int reason) {
9478dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy        Message message = obtainMessage(CMD_DISABLE_NETWORK, netId, reason);
9488dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy        message.replyTo = replyTo;
9498dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy        sendMessage(message);
9508dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy    }
9518dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy
952651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public void startWps(Messenger replyTo, WpsInfo config) {
953ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff        Message msg = obtainMessage(CMD_START_WPS, config);
954ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff        msg.replyTo = replyTo;
955ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff        sendMessage(msg);
9565ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
9575ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
9580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
9590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
9600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9622b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    public void enableBackgroundScanCommand(boolean enabled) {
963fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0));
964fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    }
965fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff
9668e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    public void enableAllNetworks() {
9678e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        sendMessage(CMD_ENABLE_ALL_NETWORKS);
9688e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    }
9698e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff
9700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
971b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering Multicast v4 packets
972b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
973b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void startFilteringMulticastV4Packets() {
974b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        mFilteringMulticastV4Packets.set(true);
975b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_START_PACKET_FILTERING, MULTICAST_V4, 0));
976b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    }
977b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
978b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
979b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering Multicast v4 packets
980b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
981b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void stopFilteringMulticastV4Packets() {
982b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        mFilteringMulticastV4Packets.set(false);
983b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V4, 0));
984b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    }
985b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
986b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
987b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering Multicast v4 packets
9880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
989b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void startFilteringMulticastV6Packets() {
990b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_START_PACKET_FILTERING, MULTICAST_V6, 0));
9910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
994b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering Multicast v4 packets
9950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
996b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void stopFilteringMulticastV6Packets() {
997b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V6, 0));
9980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10015876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Set high performance mode of operation.
10025876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Enabling would set active power mode and disable suspend optimizations;
10035876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * disabling would set auto power mode and enable suspend optimizations
10045876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * @param enable true if enable, false otherwise
10050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10065876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    public void setHighPerfModeEnabled(boolean enable) {
10075876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
10080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1011ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code
1012ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param countryCode following ISO 3166 format
1013ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
10140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1015ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    public void setCountryCode(String countryCode, boolean persist) {
1016ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (persist) {
1017ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            Settings.Secure.putString(mContext.getContentResolver(),
1018ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    Settings.Secure.WIFI_COUNTRY_CODE,
1019ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    countryCode);
10200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
1021ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_COUNTRY_CODE, countryCode));
10220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
102536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the operational frequency band
102636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param band
102736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
102836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
102936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public void setFrequencyBand(int band, boolean persist) {
103036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        if (persist) {
103136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            Settings.Secure.putInt(mContext.getContentResolver(),
103236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    Settings.Secure.WIFI_FREQUENCY_BAND,
103336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    band);
103436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        }
103536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_FREQUENCY_BAND, band, 0));
103636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
103736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
103836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
103936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Returns the operational frequency band
104036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
104136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public int getFrequencyBand() {
104236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        return mFrequencyBand.get();
104336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
104436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
104536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
10464aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff     * Returns the wifi configuration file
10474aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff     */
10484aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    public String getConfigFile() {
1049fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return mWifiConfigStore.getConfigFile();
10504aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    }
10514aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff
10524aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    /**
105365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff     * Send a message indicating bluetooth adapter connection state changed
10540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
105565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    public void sendBluetoothAdapterStateChange(int state) {
105665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff        sendMessage(obtainMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0));
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
10610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
10630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
10640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10661406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncSaveConfig(AsyncChannel channel) {
10671406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
10681406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
10691406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
10701406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
107303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    public void updateBatteryWorkSource(WorkSource newSource) {
107403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        synchronized (mRunningWifiUids) {
107503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            try {
107603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (newSource != null) {
107703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    mRunningWifiUids.set(newSource);
107803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
107903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (mIsRunning) {
108003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
108103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // If the work source has changed since last time, need
108203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // to remove old work from battery stats.
108303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
108403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
108503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                                    mRunningWifiUids);
108603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mLastRunningWifiUids.set(mRunningWifiUids);
108703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        }
108803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    } else {
108903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Now being started, report it.
109003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
109103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.set(mRunningWifiUids);
109203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = true;
109303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
109403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                } else {
109503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
109603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Last reported we were running, time to stop.
109703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
109803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.clear();
109903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = false;
110003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
110103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
11024f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                mWakeLock.setWorkSource(newSource);
110303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            } catch (RemoteException ignore) {
110403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            }
110503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        }
110603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    }
110703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
1108bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    @Override
1109bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    public String toString() {
1110bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        StringBuffer sb = new StringBuffer();
1111bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        String LS = System.getProperty("line.separator");
1112bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
111337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
1114bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
11150216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        sb.append("mDhcpInfoInternal ").append(mDhcpInfoInternal).append(LS);
1116bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
1117bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
1118bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastBssid ").append(mLastBssid).append(LS);
1119bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
1120bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
1121bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
1122bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("Supplicant status").append(LS)
1123fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                .append(mWifiNative.status()).append(LS).append(LS);
112404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1125fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        sb.append(mWifiConfigStore.dump());
1126bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        return sb.toString();
1127bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    }
1128bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
11300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
11310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
11320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
113323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    private void checkAndSetConnectivityInstance() {
113443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        if (mCm == null) {
113543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
113643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        }
113723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    }
113823eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
1139e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff    private boolean startTethering(ArrayList<String> available) {
114023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
114123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        boolean wifiAvailable = false;
114223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
114323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        checkAndSetConnectivityInstance();
114443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
114543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
114643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
114743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        for (String intf : available) {
114843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            for (String regex : wifiRegexs) {
114943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                if (intf.matches(regex)) {
115043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
115143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    InterfaceConfiguration ifcg = null;
115243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    try {
1153cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        ifcg = mNwService.getInterfaceConfig(intf);
115443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        if (ifcg != null) {
115543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            /* IP/netmask: 192.168.43.1/255.255.255.0 */
1156ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                            ifcg.setLinkAddress(new LinkAddress(
1157ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                                    NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
1158ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                            ifcg.setInterfaceUp();
115943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
1160cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                            mNwService.setInterfaceConfig(intf, ifcg);
116143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        }
116243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    } catch (Exception e) {
11637f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Error configuring interface " + intf + ", :" + e);
1164e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                        return false;
116543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
116643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
116743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
11687f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Error tethering on " + intf);
1169e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                        return false;
117043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
1171c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    mTetherInterfaceName = intf;
1172e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                    return true;
117343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                }
117443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            }
117543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        }
1176e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff        // We found no interfaces to tether
1177e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff        return false;
117843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff    }
117943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
118023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    private void stopTethering() {
118123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
118223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        checkAndSetConnectivityInstance();
118323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
118423eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        /* Clear the interface config to allow dhcp correctly configure new
118523eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff           ip settings */
118623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        InterfaceConfiguration ifcg = null;
118723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        try {
1188cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff            ifcg = mNwService.getInterfaceConfig(mInterfaceName);
118923eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            if (ifcg != null) {
1190ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                ifcg.setLinkAddress(
1191ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                        new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
1192cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                mNwService.setInterfaceConfig(mInterfaceName, ifcg);
119323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            }
119423eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        } catch (Exception e) {
11957f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Error resetting interface " + mInterfaceName + ", :" + e);
119623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
119723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
1198c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
11997f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Untether initiate failed!");
120023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
120123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    }
120223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
1203c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private boolean isWifiTethered(ArrayList<String> active) {
1204c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
1205c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        checkAndSetConnectivityInstance();
1206c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
1207c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
1208c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        for (String intf : active) {
1209c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            for (String regex : wifiRegexs) {
1210c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                if (intf.matches(regex)) {
1211c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return true;
1212c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                }
1213c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            }
1214c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
1215c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        // We found no interfaces that are tethered
1216c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        return false;
1217c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
1218c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
1219ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /**
1220ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code from the system setting value, if any.
1221ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     */
1222ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    private void setCountryCode() {
1223ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        String countryCode = Settings.Secure.getString(mContext.getContentResolver(),
1224ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                Settings.Secure.WIFI_COUNTRY_CODE);
1225ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (countryCode != null && !countryCode.isEmpty()) {
1226ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode(countryCode, false);
1227ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        } else {
1228ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            //use driver default
1229ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        }
1230ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    }
1231ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
123236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
123336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the frequency band from the system setting value, if any.
123436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
123536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private void setFrequencyBand() {
123636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        int band = Settings.Secure.getInt(mContext.getContentResolver(),
123736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                Settings.Secure.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
123836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        setFrequencyBand(band, false);
123936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
124036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
12410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
12420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
12430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
124603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
12470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
124803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
12490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
12517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to note battery stats in wifi");
12520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
12550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12567f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("setWifiState: " + syncGetWifiStateByName());
12570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
12590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
12600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
12610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
12620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
12630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
12660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
12670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
12690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
127003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
12710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
127203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
12730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
12740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
12757f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to note battery stats in wifi");
12760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
12770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
12790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
12800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12817f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
12820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
12840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
12850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
12860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
12870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
12880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
12890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
12910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Parse the scan result line passed to us by wpa_supplicant (helper).
12920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param line the line to parse
12930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return the {@link ScanResult} object
12940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
12950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ScanResult parseScanResult(String line) {
12960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        ScanResult scanResult = null;
12970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (line != null) {
12980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /*
12990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Cache implementation (LinkedHashMap) is not synchronized, thus,
13000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * must synchronized here!
13010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
13020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            synchronized (mScanResultCache) {
13030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                String[] result = scanResultPattern.split(line);
13040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (3 <= result.length && result.length <= 5) {
13050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String bssid = result[0];
13060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid | frequency | level | flags | ssid
13070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int frequency;
13080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    int level;
13090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
13100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = Integer.parseInt(result[1]);
13110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = Integer.parseInt(result[2]);
13120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
13130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
13140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
13150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
13160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch (NumberFormatException e) {
13170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        frequency = 0;
13180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        level = 0;
13190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
13200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /*
13220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * The formatting of the results returned by
13230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * wpa_supplicant is intended to make the fields
13240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * line up nicely when printed,
13250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * not to make them easy to parse. So we have to
13260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * apply some heuristics to figure out which field
13270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     * is the SSID and which field is the flags.
13280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                     */
13290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String ssid;
13300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String flags;
13310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (result.length == 4) {
13320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (result[3].charAt(0) == '[') {
13330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = result[3];
13340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = "";
13350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } else {
13360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            flags = "";
13370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ssid = result[3];
13380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
13390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else if (result.length == 5) {
13400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = result[3];
13410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = result[4];
13420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
13430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Here, we must have 3 fields: no flags and ssid
13440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // set
13450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        flags = "";
13460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        ssid = "";
13470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
13480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // bssid + ssid is the hash key
13500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String key = bssid + ssid;
13510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    scanResult = mScanResultCache.get(key);
13520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
13530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.level = level;
13540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.SSID = ssid;
13550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.capabilities = flags;
13560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanResult.frequency = frequency;
13570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
13580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        // Do not add scan results that have no SSID set
13590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (0 < ssid.trim().length()) {
13600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
13610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
13620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                    ssid, bssid, flags, level, frequency);
13630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
13640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
13650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
13660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                } else {
13677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Misformatted scan result text with " +
13680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                          result.length + " fields: " + line);
13690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
13700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return scanResult;
13740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * scanResults input format
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ee       2427    166     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net1
13790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * 00:bb:cc:dd:cc:ff       2412    165     [WPA-EAP-TKIP][WPA2-EAP-CCMP]   Net2
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
13810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setScanResults(String scanResults) {
13820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (scanResults == null) {
13830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return;
13840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        List<ScanResult> scanList = new ArrayList<ScanResult>();
13870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int lineCount = 0;
13890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        int scanResultsLen = scanResults.length();
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Parse the result string, keeping in mind that the last line does
13920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // not end with a newline.
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
13940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
13950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                ++lineCount;
13960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineCount == 1) {
13980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    lineBeg = lineEnd + 1;
13990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    continue;
14000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
14010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                if (lineEnd > lineBeg) {
14020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    String line = scanResults.substring(lineBeg, lineEnd);
14030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    ScanResult scanResult = parseScanResult(line);
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (scanResult != null) {
14050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        scanList.add(scanResult);
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
1407090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        //TODO: hidden network handling
14080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
14100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                lineBeg = lineEnd + 1;
14110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
14120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mScanResults = scanList;
14150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1417cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    private String fetchSSID() {
1418fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        String status = mWifiNative.status();
1419cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        if (status == null) {
1420cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            return null;
1421cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1422cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        // extract ssid from a series of "name=value"
1423cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        String[] lines = status.split("\n");
1424cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        for (String line : lines) {
1425cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String[] prop = line.split(" *= *");
1426cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (prop.length < 2) continue;
1427cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String name = prop[0];
1428cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            String value = prop[1];
1429cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff            if (name.equalsIgnoreCase("ssid")) return value;
1430cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        }
1431cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff        return null;
1432cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff    }
1433cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff
143419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /*
143519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Fetch RSSI and linkspeed on current connection
143619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
143719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private void fetchRssiAndLinkSpeedNative() {
1438921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        int newRssi = -1;
1439921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        int newLinkSpeed = -1;
1440921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
1441fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        String signalPoll = mWifiNative.signalPoll();
1442921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
1443921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        if (signalPoll != null) {
1444921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff            String[] lines = signalPoll.split("\n");
1445921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff            for (String line : lines) {
1446921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                String[] prop = line.split("=");
1447921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                if (prop.length < 2) continue;
1448921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                try {
1449921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    if (prop[0].equals("RSSI")) {
1450921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                        newRssi = Integer.parseInt(prop[1]);
1451921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    } else if (prop[0].equals("LINKSPEED")) {
1452921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                        newLinkSpeed = Integer.parseInt(prop[1]);
1453921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    }
1454921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                } catch (NumberFormatException e) {
1455921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    //Ignore, defaults on rssi and linkspeed are assigned
1456921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                }
1457921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff            }
1458921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        }
1459921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
14609b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        if (newRssi != -1 && MIN_RSSI < newRssi && newRssi < MAX_RSSI) { // screen out invalid values
146119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /* some implementations avoid negative values by adding 256
146219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * so we need to adjust for that here.
146319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
146419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newRssi > 0) newRssi -= 256;
146519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(newRssi);
146619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /*
146719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * Rather then sending the raw RSSI out every time it
146819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes, we precalculate the signal level that would
146919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * be displayed in the status bar, and only send the
147019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcast if that much more coarse-grained number
147119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes. This cuts down greatly on the number of
1472ea933cb3fddbf5971dd4c62090edabbed295c3a7Irfan Sheriff             * broadcasts, at the cost of not informing others
147319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * interested in RSSI of all the changes in signal
147419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * level.
147519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
1476ea933cb3fddbf5971dd4c62090edabbed295c3a7Irfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, WifiManager.RSSI_LEVELS);
147719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
147819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendRssiChangeBroadcast(newRssi);
147919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
148019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mLastSignalLevel = newSignalLevel;
148119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        } else {
14829b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            mWifiInfo.setRssi(MIN_RSSI);
148319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
1484921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
148519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newLinkSpeed != -1) {
148619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
148719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
148819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
148919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
14905876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    private void setHighPerfModeEnabledNative(boolean enable) {
1491fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if(!mWifiNative.setSuspendOptimizations(!enable)) {
14927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("set suspend optimizations failed!");
14935876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
14945876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        if (enable) {
1495fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (!mWifiNative.setPowerMode(POWER_MODE_ACTIVE)) {
14967f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("set power mode active failed!");
14975876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
14985876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        } else {
1499fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (!mWifiNative.setPowerMode(POWER_MODE_AUTO)) {
15007f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("set power mode auto failed!");
15015876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff            }
15025876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        }
15035876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    }
15045876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
150537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private void configureLinkProperties() {
1506fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
1507fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mLinkProperties = mWifiConfigStore.getLinkProperties(mLastNetworkId);
150896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
15090216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            synchronized (mDhcpInfoInternal) {
15100216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                mLinkProperties = mDhcpInfoInternal.makeLinkProperties();
151196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
1512fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mLinkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
1513128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
151496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        mLinkProperties.setInterfaceName(mInterfaceName);
15157f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) {
15167f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            log("netId=" + mLastNetworkId  + " Link configured: " +
15177f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    mLinkProperties.toString());
15187f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        }
15190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return Settings.Secure.getInt(mContext.getContentResolver(),
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
15240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
15250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
1528be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
1529be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1530be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        mContext.sendBroadcast(intent);
15310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
15340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
1535be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
15360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
15370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
15380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
15410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
15420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
15430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
15440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
1545ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties));
15460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
15470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
15483550ac919c492f3fbaebbf868f4df0d1ea7ee784Isaac Levy        if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED)
15493550ac919c492f3fbaebbf868f4df0d1ea7ee784Isaac Levy            intent.putExtra(WifiManager.EXTRA_WIFI_INFO, new WifiInfo(mWifiInfo));
15500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendStickyBroadcast(intent);
15510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1553fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    private void sendErrorBroadcast(int errorCode) {
1554fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        Intent intent = new Intent(WifiManager.ERROR_ACTION);
1555fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1556fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        intent.putExtra(WifiManager.EXTRA_ERROR_CODE, errorCode);
1557fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff        mContext.sendBroadcast(intent);
1558fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    }
1559fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
1560be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void sendLinkConfigurationChangedBroadcast() {
1561be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
1562be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1563ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));
15640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
15650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
15680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
1569be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
15700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
15710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext.sendBroadcast(intent);
15720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
15740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
15750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
15760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param state the new @{code DetailedState}
15770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1578be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
15797f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) {
15807f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            log("setDetailed state, old ="
15817f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    + mNetworkInfo.getDetailedState() + " and new state=" + state);
15827f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        }
15837f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
15840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
15850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mNetworkInfo.setDetailedState(state, null, null);
15860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1589be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private DetailedState getNetworkDetailedState() {
1590be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return mNetworkInfo.getDetailedState();
1591be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    }
1592be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
15931523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
15941523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff    private SupplicantState handleSupplicantStateChange(Message message) {
15951523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
15961523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        SupplicantState state = stateChangeResult.state;
15971523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // Supplicant state change
15981523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // [31-13] Reserved for future use
15991523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // [8 - 0] Supplicant state (as defined in SupplicantState.java)
16001523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // 50023 supplicant_state_changed (custom|1|5)
16011523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
16021523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        mWifiInfo.setSupplicantState(state);
16031523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // Network id is only valid when we start connecting
16041523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        if (SupplicantState.isConnecting(state)) {
16051523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            mWifiInfo.setNetworkId(stateChangeResult.networkId);
16061523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        } else {
16071523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
16081523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        }
16091523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
16101523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        if (state == SupplicantState.ASSOCIATING) {
16111523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            /* BSSID is valid only in ASSOCIATING state */
16121523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            mWifiInfo.setBSSID(stateChangeResult.BSSID);
16131523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        }
16141523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
16151523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        mSupplicantStateTracker.sendMessage(Message.obtain(message));
16161523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        mWpsStateMachine.sendMessage(Message.obtain(message));
16171523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
16181523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        return state;
16191523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff    }
16201523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
16230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
16240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
16267f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("Stopping DHCP and clearing IP");
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
1629ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt         * stop DHCP
16300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
163131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (mDhcpStateMachine != null) {
163231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
163331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mDhcpStateMachine.quit();
163431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mDhcpStateMachine = null;
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1637f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        try {
1638cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff            mNwService.clearInterfaceAddresses(mInterfaceName);
16397960d9f888e31602e17b8856c77a3826bf8c841erepo sync            mNwService.disableIpv6(mInterfaceName);
1640f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        } catch (Exception e) {
16417f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to clear addresses or disable ipv6" + e);
1642f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        }
1643f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff
16440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
1645124b44d89bc00b150c9478ccddfa83cac0f1df24Robert Greenwalt        mWifiInfo.setInetAddress(null);
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
16480a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
16499b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        mWifiInfo.setRssi(MIN_RSSI);
16509b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        mWifiInfo.setLinkSpeed(-1);
16519b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff
16529b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        setNetworkDetailedState(DetailedState.DISCONNECTED);
1653fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
1654cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff
1655cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff        /* send event to CM & network change broadcast */
16569b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
16570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
165937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
16600c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff        /* Clear IP settings if the network used DHCP */
1661fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
1662fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiConfigStore.clearIpConfiguration(mLastNetworkId);
16630c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff        }
16640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
16660a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
166931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    void handlePreDhcpSetup() {
167031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (!mBluetoothConnectionActive) {
167131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            /*
167231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * There are problems setting the Wi-Fi driver's power
167331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * mode to active when bluetooth coexistence mode is
167431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * enabled or sense.
167531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * <p>
167631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * We set Wi-Fi to active mode when
167731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * obtaining an IP address because we've found
167831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * compatibility issues with some routers with low power
167931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * mode.
168031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * <p>
168131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * In order for this active power mode to properly be set,
168231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * we disable coexistence mode until we're done with
168331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * obtaining an IP address.  One exception is if we
168431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * are currently connected to a headset, since disabling
168531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * coexistence would interrupt that connection.
168631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             */
168731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            // Disable the coexistence mode
1688fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.setBluetoothCoexistenceMode(
1689fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
169031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
169131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
1692fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mPowerMode =  mWifiNative.getPowerMode();
169331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (mPowerMode < 0) {
169431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            // Handle the case where supplicant driver does not support
169531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            // getPowerModeCommand.
169631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mPowerMode = WifiStateMachine.POWER_MODE_AUTO;
169731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
169831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (mPowerMode != WifiStateMachine.POWER_MODE_ACTIVE) {
1699fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.setPowerMode(WifiStateMachine.POWER_MODE_ACTIVE);
170031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
170131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
170231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
170331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
170431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    void handlePostDhcpSetup() {
170531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        /* restore power mode */
1706fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setPowerMode(mPowerMode);
170731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
170831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        // Set the coexistence mode back to its default value
1709fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setBluetoothCoexistenceMode(
1710fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
171131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
171231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
171331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private void handleSuccessfulIpConfiguration(DhcpInfoInternal dhcpInfoInternal) {
171431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        synchronized (mDhcpInfoInternal) {
171531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mDhcpInfoInternal = dhcpInfoInternal;
171631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
171731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        mLastSignalLevel = -1; // force update of signal strength
17181667a485d7cedcbd2cf0300e9a0dffdfaa93b0a2Irfan Sheriff        mReconnectCount = 0; //Reset IP failure tracking
1719fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
172031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        InetAddress addr = NetworkUtils.numericToInetAddress(dhcpInfoInternal.ipAddress);
172131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        mWifiInfo.setInetAddress(addr);
172231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (getNetworkDetailedState() == DetailedState.CONNECTED) {
172331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            //DHCP renewal in connected state
172431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            LinkProperties linkProperties = dhcpInfoInternal.makeLinkProperties();
1725fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            linkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
172631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            linkProperties.setInterfaceName(mInterfaceName);
172731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            if (!linkProperties.equals(mLinkProperties)) {
17287f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                if (DBG) {
17297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    log("Link configuration changed for netId: " + mLastNetworkId
17307f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            + " old: " + mLinkProperties + "new: " + linkProperties);
17317f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                }
173231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                mLinkProperties = linkProperties;
173331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                sendLinkConfigurationChangedBroadcast();
173431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            }
173531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        } else {
173631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            configureLinkProperties();
173731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            setNetworkDetailedState(DetailedState.CONNECTED);
1738fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
173931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            sendNetworkStateChangeBroadcast(mLastBssid);
174031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
174131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
174231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
174331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private void handleFailedIpConfiguration() {
17447f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        loge("IP configuration failed");
174531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
174631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        mWifiInfo.setInetAddress(null);
174731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        /**
174831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         * If we've exceeded the maximum number of retries for DHCP
174931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         * to a given network, disable the network
175031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         */
175131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (++mReconnectCount > getMaxDhcpRetries()) {
17527f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed " +
175331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                    mReconnectCount + " times, Disabling " + mLastNetworkId);
1754fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiConfigStore.disableNetwork(mLastNetworkId,
17558dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy                    WifiConfiguration.DISABLED_DHCP_FAILURE);
175631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mReconnectCount = 0;
175731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
175831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
175931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        /* DHCP times out after about 30 seconds, we do a
176031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         * disconnect and an immediate reconnect to try again
176131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         */
1762fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.disconnect();
1763fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.reconnect();
1764ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    }
176531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
17667dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Current design is to not set the config on a running hostapd but instead
17677dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     * stop and start tethering when user changes config on a running access point
17687dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     *
17697dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     * TODO: Add control channel setup through hostapd that allows changing config
17707dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     * on a running daemon
17717dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     */
17729575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    private void startSoftApWithConfig(final WifiConfiguration config) {
17739575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        // start hostapd on a seperate thread
17749575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        new Thread(new Runnable() {
17759575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            public void run() {
17769575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                try {
17779575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
17789575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                } catch (Exception e) {
17799575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    loge("Exception in softap start " + e);
17809575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    try {
17819575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        mNwService.stopAccessPoint(mInterfaceName);
17829575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
17839575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    } catch (Exception e1) {
17849575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        loge("Exception in softap re-start " + e1);
17859575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        sendMessage(CMD_START_AP_FAILURE);
17869575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        return;
17879575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    }
17889575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                }
17899575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                if (DBG) log("Soft AP start successful");
17909575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                sendMessage(CMD_START_AP_SUCCESS);
1791ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff            }
17929575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        }).start();
179331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
179431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
179964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DefaultState extends State {
18000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
18030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
180455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
180555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
180655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
180755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
18087f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("WifiP2pService connection failure, error=" + message.arg1);
180955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
181055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
181155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
18127f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("WifiP2pService channel lost, message.arg1 =" + message.arg1);
181355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    //TODO: Re-establish connection to state machine after a delay
181455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    //mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
181555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
181665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
181765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
181865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
1819cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
18200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
18210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
18220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
18230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
18240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
18254b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                case CMD_REMOVE_NETWORK:
18261406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_SAVE_CONFIG:
18271406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, FAILURE);
18284b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                    break;
1829e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                case CMD_GET_CONFIGURED_NETWORKS:
1830e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what,
1831fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                            mWifiConfigStore.getConfiguredNetworks());
1832e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    break;
18330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
18340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
183519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
1836fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                case CMD_ENABLE_BACKGROUND_SCAN:
1837fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mEnableBackgroundScan = (message.arg1 == 1);
1838fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    break;
18390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
18400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
18410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
18420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
18430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
1844cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                case CMD_STOP_SUPPLICANT_FAILED:
18450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
18460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
1847e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                case CMD_DELAYED_STOP_DRIVER:
18480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
18497dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_SUCCESS:
18507dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_FAILURE:
18510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
1852c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
1853c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
1854e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
1855e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
1856e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
1857e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
185855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
185955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
186055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
186155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
186255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
186355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
186455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
186555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.WPS_OVERLAP_EVENT:
18660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
18670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
18680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
18690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
18705876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1871ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
187236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
1873e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
1874e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
1875e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
187619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
18778e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
187831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
187931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
18809575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                /* Handled by WifiApConfigStore */
18819575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_SET_AP_CONFIG:
18829575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_SET_AP_CONFIG_COMPLETED:
18839575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_REQUEST_AP_CONFIG:
18849575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_RESPONSE_AP_CONFIG:
18850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
188655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.DRIVER_HUNG_EVENT:
188755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    setWifiEnabled(false);
188855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    setWifiEnabled(true);
188955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
189002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
1891e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    /* Return failure when the state machine cannot handle WPS initiation*/
1892ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff                    mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED,
1893e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                                new WpsResult(Status.FAILURE));
189402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
189555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pService.P2P_ENABLE_PENDING:
189655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // turn off wifi and defer to be handled in DriverUnloadedState
189755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    setWifiEnabled(false);
189855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
189955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
19000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
19017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Error! unhandled message" + message);
19020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
19050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
190864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class InitialState extends State {
19090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
19110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
19127f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
19130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
19140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
19150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
19160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
19170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1918fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (mWifiNative.isDriverLoaded()) {
19190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
19200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
19210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
19220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
19230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
192455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
192555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            //Connect to WifiP2pService
192655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
192755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
192855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19297960d9f888e31602e17b8856c77a3826bf8c841erepo sync            /* IPv6 is disabled at boot time and is controlled by framework
19307960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * to be enabled only as long as we are connected to an access point
19317960d9f888e31602e17b8856c77a3826bf8c841erepo sync             *
19327960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * This fixes issues, a few being:
19337960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * - IPv6 addresses and routes stick around after disconnection
19347960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * - When connected, the kernel is unaware and can fail to start IPv6 negotiation
19357960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * - The kernel sometimes starts autoconfiguration when 802.1x is not complete
19367960d9f888e31602e17b8856c77a3826bf8c841erepo sync             */
19377960d9f888e31602e17b8856c77a3826bf8c841erepo sync            try {
19387960d9f888e31602e17b8856c77a3826bf8c841erepo sync                mNwService.disableIpv6(mInterfaceName);
19397960d9f888e31602e17b8856c77a3826bf8c841erepo sync            } catch (RemoteException re) {
19407f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to disable IPv6: " + re);
19417960d9f888e31602e17b8856c77a3826bf8c841erepo sync            } catch (IllegalStateException e) {
19427f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to disable IPv6: " + e);
19437960d9f888e31602e17b8856c77a3826bf8c841erepo sync            }
19440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
19460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
194764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverLoadingState extends State {
19480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
19507f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
19510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
19520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
19540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
19550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
19560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
19570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
19580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
19590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
19604f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
19610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
19620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
19630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
19640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
19650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
19660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
19670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
19680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
19700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1971fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if(mWifiNative.loadDriver()) {
19727f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        if (DBG) log("Driver load successful");
19730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
19740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
19757f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to load driver!");
19760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
19770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
19780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
19790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
19800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
19810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
19820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
19830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
19840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
19850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
19864f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
19870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
19880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
19890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
19900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
19910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
19920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
19937f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
19940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
19950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
19960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
19970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
19980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
19990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
20000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
20020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
20030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
20040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
20050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
20060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
20070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
20080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
20090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
20100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
20115876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2012ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
201336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
20140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
20150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
20160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
20170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
202664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverLoadedState extends State {
20270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
20300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
20347f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
20350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
20360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
20370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
20380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
2040e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                    try {
2041e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                        mNwService.wifiFirmwareReload(mInterfaceName, "STA");
2042e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                    } catch (Exception e) {
20437f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to reload STA firmware " + e);
2044e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                        // continue
2045e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                    }
20467329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                   try {
20477329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                       //A runtime crash can leave the interface up and
20487329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                       //this affects connectivity when supplicant starts up.
20497329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                       //Ensure interface is down before a supplicant start.
20507244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                        mNwService.setInterfaceDown(mInterfaceName);
20517329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                        //Set privacy extensions
20527329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                        mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
20537244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                    } catch (RemoteException re) {
20547f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Unable to change interface settings: " + re);
20557244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                    } catch (IllegalStateException ie) {
20567f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Unable to change interface settings: " + ie);
20577244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                    }
20587244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff
2059fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if(mWifiNative.startSupplicant()) {
20607f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        if (DBG) log("Supplicant start successful");
20610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
206296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mSupplicantStartingState);
20630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
20647f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to start supplicant!");
20650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
20660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
20670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
20697dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    transitionTo(mSoftApStartingState);
20700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
20730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
20750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
207964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverUnloadingState extends State {
20800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20827f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
20830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
20860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
20870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
20880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
20897f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log(getName() + message.toString() + "\n");
20904f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
2091fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if(mWifiNative.unloadDriver()) {
20927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        if (DBG) log("Driver unload successful");
20930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
20940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
20960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
20970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
20980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
20990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
21010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
21020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
21030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
21050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21067f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to unload driver!");
21070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
21080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
21100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
21110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
21120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
21150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
21170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
21190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21204f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
21210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
21220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21277f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
21280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
21290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
21300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
21310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
21330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
21340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
21360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
21370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
21380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
21390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
21400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
21410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
21420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
21440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
21455876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2146ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
214736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
21480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
21490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
21500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
21510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
21560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
216064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverUnloadedState extends State {
21610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21637f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
21640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21687f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
21690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
21700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
217155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);
217255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mWaitForP2pDisableState);
217355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
217455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pService.P2P_ENABLE_PENDING:
217555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED);
21760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
21810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
218564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverFailedState extends State {
21860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
21887f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge(getName() + "\n");
21890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
21900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21937f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
21940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
21950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
219964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SupplicantStartingState extends State {
22000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
22030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22077f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
22080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
220955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
22107f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Supplicant connection established");
2211b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_ENABLED);
221296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    mSupplicantRestartCount = 0;
2213b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    /* Reset the supplicant state to indicate the supplicant
2214b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                     * state is not known at this time */
2215b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
2216e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
22190a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff                    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
22210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2222fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2224fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiConfigStore.initialize();
22259e6222f4c126252c9950d072ab67d8b849d17643Irfan Sheriff
22260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
22274f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartedState);
22280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
222955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
223096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
22317f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to setup control channel, restart supplicant");
2232fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.killSupplicant();
223396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
223496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
223596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    } else {
22367f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed " + mSupplicantRestartCount +
223796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                                " times to start supplicant, unload driver");
2238c4501f7710b8da1bc16f0670e4e7343db01f7146Ji-Hwan Lee                        mSupplicantRestartCount = 0;
223996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
2240b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
224196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
22420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
224368825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_LOAD_DRIVER:
224468825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_UNLOAD_DRIVER:
224568825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_START_SUPPLICANT:
224668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_SUPPLICANT:
22470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
224868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_AP:
22490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
22500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
22535876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2254ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
225536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
22560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
226864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SupplicantStartedState extends State {
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22717f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
22756bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            /* Wifi is available as long as we have a connection to supplicant */
22766bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(true);
22772b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff            /* Set scan interval */
22782b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff            long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
22792b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
22802b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mDefaultSupplicantScanIntervalMs);
2281fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.setScanInterval((int)supplicantScanIntervalMs / 1000);
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22857f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
2286e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
22878e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
22880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
22890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
229096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mSupplicantStoppingState);
229168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    break;
229255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
22937f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Connection lost, restart supplicant");
2294fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.killSupplicant();
2295fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.closeSupplicantConnection();
22966bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
22970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
22980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
2299b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
2300e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff                    mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
23010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
230296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
23030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
230455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
23058e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
2306fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    setScanResults(mWifiNative.scanResults());
23070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendScanResultsAvailableBroadcast();
2308fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mScanResultIsPending = false;
23090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
2311fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    boolean ok = mWifiNative.ping();
23121406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
23130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
23151406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    config = (WifiConfiguration) message.obj;
23161406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
2317fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                            mWifiConfigStore.addOrUpdateNetwork(config));
23180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
2320fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.removeNetwork(message.arg1);
23211406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
23220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
2324fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
23251406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
23260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23278e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
23280f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                    long time =  android.os.SystemClock.elapsedRealtime();
23290f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                    if (time - mLastEnableAllNetworksTime > MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS) {
2330fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiConfigStore.enableAllNetworks();
23310f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                        mLastEnableAllNetworksTime = time;
23320f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                    }
23338e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    break;
23340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISABLE_NETWORK:
2335fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.disableNetwork(message.arg1, message.arg2);
23361406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
23370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
2339fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.addToBlacklist((String)message.obj);
23400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
2342fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.clearBlacklist();
23430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
2345fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.saveConfig();
23461406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
23471406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
23480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
23490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
23500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
23510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
23520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
23530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
23540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
23550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
23560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
23570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
23580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
23600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
23617f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Failed to start soft AP with a running supplicant");
23620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
23630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
23650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
23660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2367e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_SAVE_NETWORK:
2368e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
2369fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiConfigStore.saveNetwork(config);
2370e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
2371e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_FORGET_NETWORK:
2372fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiConfigStore.forgetNetwork(message.arg1);
2373e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
23740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
23750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
23778e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
23788e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
23798e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
23800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
23810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23826bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff
23836bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        @Override
23846bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        public void exit() {
23856bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
23866bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        }
23870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
238964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SupplicantStoppingState extends State {
239096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
239196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public void enter() {
23927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
239396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23947f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log("stopping supplicant");
2395fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (!mWifiNative.stopSupplicant()) {
23967f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to stop supplicant");
23975cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            }
2398cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff
2399cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff            /* Send ourselves a delayed message to indicate failure after a wait time */
2400cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_STOP_SUPPLICANT_FAILED,
2401cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    ++mSupplicantStopFailureToken, 0), SUPPLICANT_RESTART_INTERVAL_MSECS);
2402cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff
24035cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
24045cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            handleNetworkDisconnect();
24055cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            setWifiState(WIFI_STATE_DISABLING);
24065cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            sendSupplicantConnectionChangedBroadcast(false);
24075cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
24085cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
240996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
241096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
241196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public boolean processMessage(Message message) {
24127f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
241396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            switch(message.what) {
241455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
24157f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Supplicant connection received while stopping");
241696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
241755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
24187f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Supplicant connection lost");
2419cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    /* Socket connection can be lost when we do a graceful shutdown
2420cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                     * or when the driver is hung. Ensure supplicant is stopped here.
2421cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                     */
2422fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.killSupplicant();
2423fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.closeSupplicantConnection();
242496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mDriverLoadedState);
242596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
2426cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                case CMD_STOP_SUPPLICANT_FAILED:
2427cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    if (message.arg1 == mSupplicantStopFailureToken) {
24287f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Timed out on a supplicant stop, kill and proceed");
2429fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.killSupplicant();
2430fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.closeSupplicantConnection();
2431cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                        transitionTo(mDriverLoadedState);
2432cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    }
2433cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    break;
243496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_LOAD_DRIVER:
243596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_UNLOAD_DRIVER:
243696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_SUPPLICANT:
243796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_SUPPLICANT:
243896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_AP:
243996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_AP:
244096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_DRIVER:
244196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_DRIVER:
244296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_MODE:
244396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_TYPE:
244496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
244596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
244696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
244796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_PACKET_FILTERING:
244896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
244996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    deferMessage(message);
245096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
245196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                default:
245296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    return NOT_HANDLED;
245396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            }
245496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
245596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            return HANDLED;
245696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
245796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    }
245896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
245964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStartingState extends State {
24600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24627f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
24630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
24640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
24677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
24680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
246955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync               case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
24701523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    SupplicantState state = handleSupplicantStateChange(message);
24711523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    /* If suplicant is exiting out of INTERFACE_DISABLED state into
24721523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                     * a state that indicates driver has started, it is ready to
24731523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                     * receive driver commands
24741523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                     */
24751523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    if (SupplicantState.isDriverActive(state)) {
24761523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                        transitionTo(mDriverStartedState);
24771523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    }
24780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
24810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
248255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
248355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
248455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
248555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.WPS_OVERLAP_EVENT:
24860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
24875876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2488ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
248936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
24900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
24910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
24920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
24930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
24940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
24950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2496e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
24970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
24990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
25000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
25010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
25020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
25030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
25040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
25050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
250664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStartedState extends State {
25070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
25080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
25097f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
25100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
25110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
251203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = true;
2513e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff            mInDelayedStop = false;
251403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
25150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
251665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            /**
251765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
251865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * When this mode is on, some of the low-level scan parameters used by the
251965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * driver are changed to reduce interference with bluetooth
252065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             */
2521fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
2522ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            /* set country code */
2523ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode();
252436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            /* set frequency band of operation */
252536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            setFrequencyBand();
25263a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            /* initialize network state */
25273a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            setNetworkDetailedState(DetailedState.DISCONNECTED);
25280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2529b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            /* Remove any filtering on Multicast v6 at start */
2530fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.stopFilteringMulticastV6Packets();
2531b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
2532b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            /* Reset Multicast v4 filtering state */
2533b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            if (mFilteringMulticastV4Packets.get()) {
2534fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.startFilteringMulticastV4Packets();
2535b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            } else {
2536fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.stopFilteringMulticastV4Packets();
2537b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            }
2538b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
2540fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
2541fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.disconnect();
25420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
25430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
2544fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.setScanResultHandling(CONNECT_MODE);
2545fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.reconnect();
2546576db76106e43129d3df256524c343d0768b2a39Irfan Sheriff                // Status pulls in the current supplicant state and network connection state
2547576db76106e43129d3df256524c343d0768b2a39Irfan Sheriff                // events over the monitor connection. This helps framework sync up with
2548576db76106e43129d3df256524c343d0768b2a39Irfan Sheriff                // current supplicant state
2549fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.status();
2550090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                transitionTo(mDisconnectedState);
25510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
25520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
25530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
25540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
25557f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
25568e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
25570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
25580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
25591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    mSetScanActive = (message.arg1 == SCAN_ACTIVE);
2560fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setScanMode(mSetScanActive);
25610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
256219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
25638e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
25641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    boolean forceActive = (message.arg1 == SCAN_ACTIVE);
25651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    if (forceActive && !mSetScanActive) {
2566fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanMode(forceActive);
25671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    }
2568fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.scan();
25691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    if (forceActive && !mSetScanActive) {
2570fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanMode(mSetScanActive);
25711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    }
2572fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mScanResultIsPending = true;
257319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
25745876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
25755876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                    setHighPerfModeEnabledNative(message.arg1 == 1);
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2577ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
2578ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    String country = (String) message.obj;
25797f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("set country code " + country);
2580fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (!mWifiNative.setCountryCode(country.toUpperCase())) {
25817f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to set country code " + country);
2582ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    }
25830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
258436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
258536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    int band =  message.arg1;
25867f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("set frequency band " + band);
2587fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.setBand(band)) {
258836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        mFrequencyBand.set(band);
2589cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        //Fetch the latest scan results when frequency band is set
2590cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        startScan(true);
259136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    } else {
25927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to set frequency band " + band);
259336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    }
259436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    break;
259565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
259665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
259765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
2598fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
259965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    break;
26000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
26014494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    int mode = message.arg1;
26024494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff
26034494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    /* Already doing a delayed stop && not in ecm state */
26044494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    if (mInDelayedStop && mode != IN_ECM_STATE) {
2605e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        if (DBG) log("Already in delayed stop");
2606e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        break;
2607e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    }
2608e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    mInDelayedStop = true;
2609e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    mDelayedStopCounter++;
2610e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (DBG) log("Delayed stop message " + mDelayedStopCounter);
26114494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff
26124494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    if (mode == IN_ECM_STATE) {
26134494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        /* send a shut down immediately */
26144494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        sendMessage(obtainMessage(CMD_DELAYED_STOP_DRIVER, mDelayedStopCounter, 0));
26154494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    } else {
26164494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        /* send regular delayed shut down */
26174494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        sendMessageDelayed(obtainMessage(CMD_DELAYED_STOP_DRIVER,
26184494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                                mDelayedStopCounter, 0), DELAYED_DRIVER_STOP_MS);
26194494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    }
2620e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    break;
2621e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                case CMD_START_DRIVER:
2622e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (mInDelayedStop) {
2623e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        mInDelayedStop = false;
2624e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        mDelayedStopCounter++;
2625e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        if (DBG) log("Delayed stop ignored due to start");
2626e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    }
2627e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    break;
2628e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                case CMD_DELAYED_STOP_DRIVER:
2629e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (message.arg1 != mDelayedStopCounter) break;
2630e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (getCurrentState() != mDisconnectedState) {
2631fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.disconnect();
2632e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        handleNetworkDisconnect();
2633e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    }
26344f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
2635fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.stopDriver();
26360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverStoppingState);
26374f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
26380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
2640b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    if (message.arg1 == MULTICAST_V6) {
2641fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.startFilteringMulticastV6Packets();
2642b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else if (message.arg1 == MULTICAST_V4) {
2643fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.startFilteringMulticastV4Packets();
2644b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else {
26457f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Illegal arugments to CMD_START_PACKET_FILTERING");
2646b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    }
26470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
2649b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    if (message.arg1 == MULTICAST_V6) {
2650fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.stopFilteringMulticastV6Packets();
2651b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else if (message.arg1 == MULTICAST_V4) {
2652fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.stopFilteringMulticastV4Packets();
2653b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else {
26547f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
2655b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    }
26560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
26580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
26590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
26608e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
26618e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
26628e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
26630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
26640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
26677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
266803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = false;
266903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
2670f99819e47cbef2ec066a21b426c7e6fe95e3de48Irfan Sheriff            mScanResults = null;
26710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
26730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
267464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStoppingState extends State {
26750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26777f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
26780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
26790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26827f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
26830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
268455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
26851523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    SupplicantState state = handleSupplicantStateChange(message);
26861523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    if (state == SupplicantState.INTERFACE_DISABLED) {
26871523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                        transitionTo(mDriverStoppedState);
26881523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    }
26890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
26900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
26910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
26920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
26930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
26945876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2695ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
269636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
26970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
26980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
26990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
27000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
27010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
27020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2703e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
27040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
271364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStoppedState extends State {
27140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27167f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
27170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27217f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
27224f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            switch (message.what) {
272356379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
272456379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
272556379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    SupplicantState state = stateChangeResult.state;
272656379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // A WEXT bug means that we can be back to driver started state
272756379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // unexpectedly
272856379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    if (SupplicantState.isDriverActive(state)) {
272956379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        transitionTo(mDriverStartedState);
273056379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    }
273156379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    break;
27323ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                case CMD_START_DRIVER:
27333ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                    mWakeLock.acquire();
2734fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.startDriver();
27353ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                    mWakeLock.release();
27363ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                    transitionTo(mDriverStartingState);
27374f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    break;
27384f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                default:
27394f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    return NOT_HANDLED;
27404f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            }
27414f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27424f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            return HANDLED;
27430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
274664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class ScanModeState extends State {
27470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27497f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
27500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27547f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
27550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
27560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
27570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
27580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
27590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
27600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
2761fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanResultHandling(message.arg1);
2762fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.reconnect();
27630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
27640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
27650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
27660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
27680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
27690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
27700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
277155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
277255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
277355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
27740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
27790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
278364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class ConnectModeState extends State {
27840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27867f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
27870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27917f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
27920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
27930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
279455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
279555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT);
27960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
279755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.WPS_OVERLAP_EVENT:
2798fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    /* We just need to broadcast the error */
2799fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
2800fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff                    break;
280155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
280256379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    SupplicantState state = handleSupplicantStateChange(message);
280356379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // Due to a WEXT bug, during the time of driver start/stop
280456379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // we can go into a driver stopped state in an unexpected way.
280556379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // The sequence eventually puts interface
280656379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // up and we should be back to a connected state
280756379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    if (!SupplicantState.isDriverActive(state)) {
280856379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
280956379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                            handleNetworkDisconnect();
281056379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        }
281156379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        transitionTo(mDriverStoppedState);
2812a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        break;
2813a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    }
2814a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff
2815a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
2816a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // when authentication times out after a successful connection,
2817a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // we can figure this from the supplicant state. If supplicant
2818a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // state is DISCONNECTED, but the mNetworkInfo says we are not
2819a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // disconnected, we need to handle a disconnection
2820a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    if (state == SupplicantState.DISCONNECTED &&
2821a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                            mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
2822a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        if (DBG) log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
2823a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        handleNetworkDisconnect();
2824a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        transitionTo(mDisconnectedState);
282556379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    }
282656379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    break;
28270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
28280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
2829fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.disconnect();
28300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2832fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.reconnect();
28330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
2835fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.reassociate();
28360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2837e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                case CMD_CONNECT_NETWORK:
2838e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
2839e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
284004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
284104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* We connect to a specific network by issuing a select
284204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * to the WifiConfigStore. This enables the network,
284304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * while disabling all other networks in the supplicant.
284404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * Disabling a connected network will cause a disconnection
284504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * from the network. A reconnectCommand() will then initiate
284604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     * a connection to the enabled network.
284704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                     */
2848e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
2849fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        netId = mWifiConfigStore.selectNetwork(config);
285004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    } else {
2851fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiConfigStore.selectNetwork(netId);
2852e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
2853e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
28548e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    /* The state tracker handles enabling networks upon completion/failure */
28558e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_CONNECT_NETWORK);
285604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
2857fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.reconnect();
285804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    /* Expect a disconnection from the old connection */
2859a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    transitionTo(mDisconnectingState);
2860e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
286102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_START_WPS:
286202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    mWpsStateMachine.sendMessage(Message.obtain(message));
286302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mWaitForWpsCompletionState);
2864f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    break;
286555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
28660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
2867fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setScanResultHandling(CONNECT_MODE);
28680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
28690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
287055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
28717f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Network connection established");
2872b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastNetworkId = message.arg1;
2873b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastBssid = (String) message.obj;
28740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2875cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    //TODO: make supplicant modification to push this in events
2876cdea9193f2745fd46e69858a7c5570d95f8182dcIrfan Sheriff                    mWifiInfo.setSSID(fetchSSID());
2877b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid);
2878b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setNetworkId(mLastNetworkId);
28790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
2880be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
28810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
28820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mConnectingState);
28830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
288455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
28857f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Network connection lost");
28860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
28870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
28880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
28900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
28910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
28920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
28930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
28940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
28950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
28960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
289764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class ConnectingState extends State {
28980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
28990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
29000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
29017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
29020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
29030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29047960d9f888e31602e17b8856c77a3826bf8c841erepo sync            try {
29057960d9f888e31602e17b8856c77a3826bf8c841erepo sync                mNwService.enableIpv6(mInterfaceName);
29067960d9f888e31602e17b8856c77a3826bf8c841erepo sync            } catch (RemoteException re) {
29077f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to enable IPv6: " + re);
29087960d9f888e31602e17b8856c77a3826bf8c841erepo sync            } catch (IllegalStateException e) {
29097f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to enable IPv6: " + e);
29107960d9f888e31602e17b8856c77a3826bf8c841erepo sync            }
29117960d9f888e31602e17b8856c77a3826bf8c841erepo sync
2912fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
291331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                //start DHCP
291431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
291531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                        mContext, WifiStateMachine.this, mInterfaceName);
291631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                mDhcpStateMachine.registerForPreDhcpNotification();
291731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
29180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
2919fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                DhcpInfoInternal dhcpInfoInternal = mWifiConfigStore.getIpConfiguration(
29200216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                        mLastNetworkId);
292127d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                InterfaceConfiguration ifcg = new InterfaceConfiguration();
2922ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                ifcg.setLinkAddress(dhcpInfoInternal.makeLinkAddress());
2923ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                ifcg.setInterfaceUp();
292427d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                try {
2925cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    mNwService.setInterfaceConfig(mInterfaceName, ifcg);
29267f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Static IP configuration succeeded");
292731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                    sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
292827d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                } catch (RemoteException re) {
29297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Static IP configuration failed: " + re);
293031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                    sendMessage(CMD_STATIC_IP_FAILURE);
293127d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwalt                } catch (IllegalStateException e) {
29327f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Static IP configuration failed: " + e);
293331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                    sendMessage(CMD_STATIC_IP_FAILURE);
29340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
29350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
29367960d9f888e31602e17b8856c77a3826bf8c841erepo sync        }
29370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      @Override
29380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      public boolean processMessage(Message message) {
29397f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff          if (DBG) log(getName() + message.toString() + "\n");
29400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
29410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          switch(message.what) {
294231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
294331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handlePreDhcpSetup();
294431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
294531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  break;
294631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
294731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handlePostDhcpSetup();
294831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
294931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
295031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      transitionTo(mConnectedState);
295131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
295231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      handleFailedIpConfiguration();
295331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      transitionTo(mDisconnectingState);
2954be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  }
295531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  break;
295631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case CMD_STATIC_IP_SUCCESS:
295731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
29580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mConnectedState);
29590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
296031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case CMD_STATIC_IP_FAILURE:
296131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handleFailedIpConfiguration();
29620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
29630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
29640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_DISCONNECT:
2965fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                  mWifiNative.disconnect();
29660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  transitionTo(mDisconnectingState);
29670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
2968a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  /* Ignore connection to same network */
2969a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff              case CMD_CONNECT_NETWORK:
2970a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  int netId = message.arg1;
2971a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  if (mWifiInfo.getNetworkId() == netId) {
2972a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                      break;
2973a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  }
2974a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                  return NOT_HANDLED;
2975be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff              case CMD_SAVE_NETWORK:
2976be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  deferMessage(message);
2977be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                  break;
29780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  /* Ignore */
297955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync              case WifiMonitor.NETWORK_CONNECTION_EVENT:
29800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
29810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              case CMD_SET_SCAN_MODE:
29820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  if (message.arg1 == SCAN_ONLY_MODE) {
29830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      sendMessage(CMD_DISCONNECT);
29840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                      deferMessage(message);
29850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  }
29860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                  break;
298719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  /* Defer scan when IP is being fetched */
298819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff              case CMD_START_SCAN:
298919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  deferMessage(message);
299019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                  break;
29915876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  /* Defer any power mode changes since we must keep active power mode at DHCP */
29925876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff              case CMD_SET_HIGH_PERF_MODE:
29935876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  deferMessage(message);
29945876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff                  break;
29950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff              default:
29960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return NOT_HANDLED;
29970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          }
29980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
29990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          return HANDLED;
30000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
30010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
30020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
300364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class ConnectedState extends State {
30040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
30067f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
30070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
300819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mRssiPollToken++;
300919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (mEnableRssiPolling) {
301019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendMessage(obtainMessage(WifiStateMachine.CMD_RSSI_POLL, mRssiPollToken, 0));
301119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
30120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
30157f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
30168e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            boolean eventLoggingEnabled = true;
30170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
301831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
301931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handlePreDhcpSetup();
302031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
302131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  break;
302231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
302331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handlePostDhcpSetup();
302431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
302531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
302631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
302731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      handleFailedIpConfiguration();
302831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      transitionTo(mDisconnectingState);
302931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  }
303031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  break;
30310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
3032fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.disconnect();
30330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
30340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
30350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
30360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
30370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
30380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
30390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
30400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
304119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
30428e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
304319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* When the network is connected, re-scanning can trigger
304419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * a reconnection. Put it in scan-only mode during scan.
304519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * When scan results are received, the mode is switched
304619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * back to CONNECT_MODE.
304719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     */
3048fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
3049fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Have the parent state handle the rest */
3050fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    return NOT_HANDLED;
3051a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Ignore connection to same network */
3052a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                case CMD_CONNECT_NETWORK:
3053a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    int netId = message.arg1;
3054a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    if (mWifiInfo.getNetworkId() == netId) {
3055a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                        break;
3056a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    }
3057a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    return NOT_HANDLED;
3058be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                case CMD_SAVE_NETWORK:
3059be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
3060fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
3061be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
3062be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasIpChanged()) {
30637f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            log("Reconfiguring IP on connection");
3064be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            transitionTo(mConnectingState);
3065be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
3066be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasProxyChanged()) {
30677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            log("Reconfiguring proxy on connection");
3068be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            configureLinkProperties();
3069be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            sendLinkConfigurationChangedBroadcast();
3070be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
3071be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    }
3072be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    break;
30730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
307455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
30750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
307619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
30778e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    eventLoggingEnabled = false;
307819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (message.arg1 == mRssiPollToken) {
307919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Get Info and continue polling
308019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
308119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
308219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
308319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    } else {
308419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Polling has completed
308519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
308619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
308719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_ENABLE_RSSI_POLL:
308819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
308919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mRssiPollToken++;
309019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (mEnableRssiPolling) {
309119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // first poll
309219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
309319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
309419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
309519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
309619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
30970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
30980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
30990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
31008e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            if (eventLoggingEnabled) {
31018e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
31028e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            }
31030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
31040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
31059b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        @Override
31069b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        public void exit() {
310787f0a7b1aa3fcd688358f92389d3eeaf1ae99008Irfan Sheriff
310887f0a7b1aa3fcd688358f92389d3eeaf1ae99008Irfan Sheriff            /* Request a CS wakelock during transition to mobile */
310987f0a7b1aa3fcd688358f92389d3eeaf1ae99008Irfan Sheriff            checkAndSetConnectivityInstance();
311087f0a7b1aa3fcd688358f92389d3eeaf1ae99008Irfan Sheriff            mCm.requestNetworkTransitionWakelock(TAG);
311187f0a7b1aa3fcd688358f92389d3eeaf1ae99008Irfan Sheriff
31129b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            /* If a scan result is pending in connected state, the supplicant
31139b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff             * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit
31149b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff             */
31159b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            if (mScanResultIsPending) {
3116fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.setScanResultHandling(CONNECT_MODE);
31179b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            }
31189b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        }
31190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
31200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
312164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DisconnectingState extends State {
31220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
31247f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
31250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
31260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
31270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
31297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
31300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
31310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
31320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
31330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
31340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
31350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
313655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
31372d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                    /* If we get a SUPPLICANT_STATE_CHANGE_EVENT before NETWORK_DISCONNECTION_EVENT
31382d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                     * we have missed the network disconnection, transition to mDisconnectedState
31392d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                     * and handle the rest of the events there
31402d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                     */
314119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    deferMessage(message);
31422d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                    handleNetworkDisconnect();
31432d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                    transitionTo(mDisconnectedState);
314419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
31450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
31460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
31470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
31480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
31490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
31500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
31510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
31520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
315364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DisconnectedState extends State {
3154fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff        private boolean mAlarmEnabled = false;
31552b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        /* This is set from the overlay config file or from a secure setting.
31562b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff         * A value of 0 disables scanning in the framework.
31572b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff         */
31582b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        private long mFrameworkScanIntervalMs;
3159f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff
3160f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff        private void setScanAlarm(boolean enabled) {
3161f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            if (enabled == mAlarmEnabled) return;
3162f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            if (enabled) {
31632b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                if (mFrameworkScanIntervalMs > 0) {
31642b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
31652b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                            System.currentTimeMillis() + mFrameworkScanIntervalMs,
31662b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                            mFrameworkScanIntervalMs,
31672b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                            mScanIntent);
31682b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mAlarmEnabled = true;
31692b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                }
3170f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            } else {
3171f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                mAlarmManager.cancel(mScanIntent);
3172f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                mAlarmEnabled = false;
3173f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            }
3174f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff        }
3175f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff
31760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
31770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
31787f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
31790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
3180090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
31812b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff            mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
31822b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    Settings.Secure.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
31832b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mDefaultFrameworkScanIntervalMs);
3184fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            /*
3185fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff             * We initiate background scanning if it is enabled, otherwise we
3186fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff             * initiate an infrequent scan that wakes up the device to ensure
3187fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff             * a user connects to an access point on the move
3188090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             */
3189fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            if (mEnableBackgroundScan) {
3190fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                /* If a regular scan result is pending, do not initiate background
3191fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * scan until the scan results are returned. This is needed because
3192fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * initiating a background scan will cancel the regular scan and
3193fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * scan results will not be returned until background scanning is
3194fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * cleared
3195fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 */
3196fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                if (!mScanResultIsPending) {
3197fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.enableBackgroundScan(true);
3198fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                }
3199fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            } else {
3200f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                setScanAlarm(true);
3201fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            }
32020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
32057f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
32060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
32070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
32080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
3209fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanResultHandling(message.arg1);
32100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
3211fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.disconnect();
32120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
32130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
32140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
32150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
3216fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                case CMD_ENABLE_BACKGROUND_SCAN:
3217fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mEnableBackgroundScan = (message.arg1 == 1);
3218f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                    if (mEnableBackgroundScan) {
3219fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(true);
3220f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                        setScanAlarm(false);
3221f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                    } else {
3222fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(false);
3223f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                        setScanAlarm(true);
3224f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                    }
3225fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    break;
32260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
322755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
32280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
322955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
3230e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
3231e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
3232e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    /* ConnectModeState does the rest of the handling */
3233e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    return NOT_HANDLED;
3234e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                case CMD_START_SCAN:
3235fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Disable background scan temporarily during a regular scan */
3236fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    if (mEnableBackgroundScan) {
3237fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(false);
3238fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    }
3239fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Handled in parent state */
3240fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    return NOT_HANDLED;
324155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
3242fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Re-enable background scan when a pending scan result is received */
3243fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    if (mEnableBackgroundScan && mScanResultIsPending) {
3244fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(true);
3245fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    }
3246fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Handled in parent state */
3247fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    return NOT_HANDLED;
32480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
32490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
32500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
32510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
32520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
32530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
3254090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
3255090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        @Override
3256090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        public void exit() {
3257fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            /* No need for a background scan upon exit from a disconnected state */
3258fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            if (mEnableBackgroundScan) {
3259fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.enableBackgroundScan(false);
3260fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            }
3261f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            setScanAlarm(false);
3262090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        }
32630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
32640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
326564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class WaitForWpsCompletionState extends State {
326602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
326702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public void enter() {
32687f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
326902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
327002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
327102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
327202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public boolean processMessage(Message message) {
32737f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
327402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            switch (message.what) {
327502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                /* Defer all commands that can cause connections to a different network
327602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 * or put the state machine out of connect mode
327702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 */
327802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_STOP_DRIVER:
327902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_SET_SCAN_MODE:
328002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_CONNECT_NETWORK:
328102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_ENABLE_NETWORK:
328202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_RECONNECT:
328302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_REASSOCIATE:
328455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT: /* Handled after IP & proxy update */
328502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    deferMessage(message);
328602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
328755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
32887f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Network connection lost");
328902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    handleNetworkDisconnect();
329002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
329102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case WPS_COMPLETED_EVENT:
329202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    /* we are still disconnected until we see a network connection
329302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                     * notification */
329402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    transitionTo(mDisconnectedState);
329502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
329602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                default:
329702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    return NOT_HANDLED;
329802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            }
329902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
330002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            return HANDLED;
330102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
330202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    }
330302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
33047dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    class SoftApStartingState extends State {
33057dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        @Override
33067dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        public void enter() {
33077f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
33087dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
33097dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff
33109575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            final Message message = getCurrentMessage();
33119575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            if (message.what == CMD_START_AP) {
33129575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                final WifiConfiguration config = (WifiConfiguration) message.obj;
33137dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff
33149575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                if (config == null) {
33159575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
33169575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                } else {
33179575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
33189575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    startSoftApWithConfig(config);
33197dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                }
33209575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            } else {
33219575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                throw new RuntimeException("Illegal transition to SoftApStartingState: " + message);
33229575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            }
33237dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        }
33247dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        @Override
33257dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        public boolean processMessage(Message message) {
33267f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
33277dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            switch(message.what) {
33287dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_LOAD_DRIVER:
33297dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_UNLOAD_DRIVER:
33307dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_SUPPLICANT:
33317dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_SUPPLICANT:
33327dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP:
33337dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_AP:
33347dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_DRIVER:
33357dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_DRIVER:
33367dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_SCAN_MODE:
33377dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_SCAN_TYPE:
33387dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
33397dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
33407dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
33417dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_PACKET_FILTERING:
33427dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
3343c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
33447dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case WifiP2pService.P2P_ENABLE_PENDING:
33457dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    deferMessage(message);
33467dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    break;
33479575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
33489575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
33499575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    if (config != null) {
33509575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        startSoftApWithConfig(config);
33519575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    } else {
33529575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        loge("Softap config is null!");
33539575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        sendMessage(CMD_START_AP_FAILURE);
33549575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    }
33559575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    break;
33567dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_SUCCESS:
33577dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
33587dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    transitionTo(mSoftApStartedState);
33597dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    break;
33607dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_FAILURE:
33617dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    // initiate driver unload
33627dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
33637dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    break;
33647dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                default:
33657dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    return NOT_HANDLED;
33667dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            }
33677dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
33687dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            return HANDLED;
33697dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        }
33707dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    }
33717dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff
337264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SoftApStartedState extends State {
33730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
33740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
33757f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
33760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
33770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
33780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
33790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
33807f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
33810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
33820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
33837f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Stopping Soft AP");
33840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
3385c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3386c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    /* We have not tethered at this point, so we just shutdown soft Ap */
33870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
3388cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        mNwService.stopAccessPoint(mInterfaceName);
33890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
33907f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Exception in stopAccessPoint()");
33910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
33920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
33930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
33957dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    // Ignore a start on a running access point
33960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
33977dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    /* Fail client mode operation when soft AP is enabled */
33980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
33997f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                   loge("Cannot start supplicant with a running soft AP");
34000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
34010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
3402c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3403c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3404c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (startTethering(stateChange.available)) {
3405c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        transitionTo(mTetheringState);
3406e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                    }
340723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                    break;
340855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pService.P2P_ENABLE_PENDING:
340955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // turn of soft Ap and defer to be handled in DriverUnloadedState
341055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    setWifiApEnabled(null, false);
341155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
341255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
341355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
341455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
341555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
341655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
341755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
341855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
341955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
342055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
342155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class WaitForP2pDisableState extends State {
342255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private int mSavedArg;
342355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
342455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
34257f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
342655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
342755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
342855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            //Preserve the argument arg1 that has information used in DriverLoadingState
342955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mSavedArg = getCurrentMessage().arg1;
343055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
343155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
343255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
34337f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
343455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch(message.what) {
343555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pService.WIFI_ENABLE_PROCEED:
343655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    //restore argument from original message (CMD_LOAD_DRIVER)
343755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    message.arg1 = mSavedArg;
343855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mDriverLoadingState);
343955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
344055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_LOAD_DRIVER:
344155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_UNLOAD_DRIVER:
344255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_START_SUPPLICANT:
344355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_STOP_SUPPLICANT:
344455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_START_AP:
344555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_STOP_AP:
344655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_START_DRIVER:
344755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_STOP_DRIVER:
344855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_SET_SCAN_MODE:
344955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_SET_SCAN_TYPE:
345055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_SET_HIGH_PERF_MODE:
345155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_SET_COUNTRY_CODE:
345255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_SET_FREQUENCY_BAND:
345355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_START_PACKET_FILTERING:
345455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case CMD_STOP_PACKET_FILTERING:
345555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
345655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
34580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
34590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
34600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
34610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
34620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
34630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
346423eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
3465c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    class TetheringState extends State {
3466c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3467c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public void enter() {
3468c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + "\n");
3469c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
3470c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3471c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            /* Send ourselves a delayed message to shut down if tethering fails to notify */
3472c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
3473c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
3474c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3475c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3476c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public boolean processMessage(Message message) {
3477c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
3478c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            switch(message.what) {
3479c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3480c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3481c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (isWifiTethered(stateChange.active)) {
3482c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        transitionTo(mTetheredState);
3483c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
3484c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return HANDLED;
3485c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
3486c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (message.arg1 == mTetherToken) {
3487c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Failed to get tether update, shutdown soft access point");
3488c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        setWifiApEnabled(null, false);
3489c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
3490c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3491c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_LOAD_DRIVER:
3492c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_UNLOAD_DRIVER:
3493c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_SUPPLICANT:
3494c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_SUPPLICANT:
3495c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_AP:
3496c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_AP:
3497c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_DRIVER:
3498c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_DRIVER:
3499c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_MODE:
3500c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_TYPE:
3501c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
3502c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
3503c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
3504c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_PACKET_FILTERING:
3505c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
3506c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case WifiP2pService.P2P_ENABLE_PENDING:
3507c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    deferMessage(message);
3508c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3509c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                default:
3510c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return NOT_HANDLED;
3511c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            }
3512c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
3513c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            return HANDLED;
3514c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3515c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
3516c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
351723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    class TetheredState extends State {
351823eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        @Override
351923eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        public void enter() {
35207f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
352123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
352223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
352323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        @Override
352423eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        public boolean processMessage(Message message) {
35257f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
352623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            switch(message.what) {
3527c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3528c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3529c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (!isWifiTethered(stateChange.active)) {
3530c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Tethering reports wifi as untethered!, shut down soft Ap");
3531c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        setWifiApEnabled(null, false);
3532c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
353323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                    return HANDLED;
3534c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_AP:
3535c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (DBG) log("Untethering before stopping AP");
3536c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
3537c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    stopTethering();
3538c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    transitionTo(mSoftApStoppingState);
3539c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
354023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                default:
354123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                    return NOT_HANDLED;
354223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            }
3543c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
3544c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            return HANDLED;
3545c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3546c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
3547c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3548c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    class SoftApStoppingState extends State {
3549c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3550c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public void enter() {
3551c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + "\n");
3552c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
3553c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3554c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            /* Send ourselves a delayed message to shut down if tethering fails to notify */
3555c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
3556c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
3557c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3558c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3559c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3560c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public boolean processMessage(Message message) {
3561c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
3562c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            switch(message.what) {
3563c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3564c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3565c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3566c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    /* Wait till wifi is untethered */
3567c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (isWifiTethered(stateChange.active)) break;
3568c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3569c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    try {
3570c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        mNwService.stopAccessPoint(mInterfaceName);
3571c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    } catch(Exception e) {
3572c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Exception in stopAccessPoint()");
3573c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
3574c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    transitionTo(mDriverLoadedState);
3575c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3576c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
3577c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (message.arg1 == mTetherToken) {
3578c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Failed to get tether update, force stop access point");
3579c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        try {
3580c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                            mNwService.stopAccessPoint(mInterfaceName);
3581c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        } catch(Exception e) {
3582c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                            loge("Exception in stopAccessPoint()");
3583c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        }
3584c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        transitionTo(mDriverLoadedState);
3585c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
3586c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3587c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_LOAD_DRIVER:
3588c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_UNLOAD_DRIVER:
3589c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_SUPPLICANT:
3590c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_SUPPLICANT:
3591c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_AP:
3592c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_AP:
3593c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_DRIVER:
3594c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_DRIVER:
3595c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_MODE:
3596c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_TYPE:
3597c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
3598c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
3599c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
3600c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_PACKET_FILTERING:
3601c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
3602c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case WifiP2pService.P2P_ENABLE_PENDING:
3603c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    deferMessage(message);
3604c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3605c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                default:
3606c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return NOT_HANDLED;
3607c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            }
3608c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
3609c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            return HANDLED;
361023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
361123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    }
36127f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
36137f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    private void log(String s) {
36147f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        Log.d(TAG, s);
36157f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    }
36167f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
36177f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    private void loge(String s) {
36187f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        Log.e(TAG, s);
36197f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    }
36200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
3621