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/**
2690542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff * TODO:
270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Deprecate WIFI_STATE_UNKNOWN
280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
35090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.AlarmManager;
36090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriffimport android.app.PendingIntent;
3734ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.app.backup.IBackupManager;
3834ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.bluetooth.BluetoothAdapter;
3934ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.BroadcastReceiver;
4034ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.Context;
4134ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.Intent;
4234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.content.IntentFilter;
437d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriffimport android.content.pm.PackageManager;
443fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriffimport android.database.ContentObserver;
4534ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.ConnectivityManager;
460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.DhcpInfo;
470216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwaltimport android.net.DhcpInfoInternal;
4831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriffimport android.net.DhcpStateMachine;
4927d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwaltimport android.net.InterfaceConfiguration;
5034ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.LinkAddress;
5134ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.LinkProperties;
5234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.net.NetworkInfo;
530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
5427d3c5907cc6f4366a7af3f0941d8d29d9b2440bRobert Greenwaltimport android.net.NetworkUtils;
55f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zhengimport android.net.wifi.RssiPacketCountInfo;
56e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriffimport android.net.wifi.WpsResult.Status;
5755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pManager;
58f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport android.net.wifi.p2p.WifiP2pService;
5955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.StateChangeResult;
600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Binder;
610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.IBinder;
620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.INetworkManagementService;
6334ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.Message;
64ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriffimport android.os.Messenger;
650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.PowerManager;
6634ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.Process;
670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.RemoteException;
680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.ServiceManager;
698dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levyimport android.os.SystemClock;
7034ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.os.SystemProperties;
715ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
7203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackbornimport android.os.WorkSource;
730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.provider.Settings;
740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.EventLog;
750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.util.Log;
7634ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilsonimport android.util.LruCache;
77090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
783809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriffimport com.android.internal.R;
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 *
9690542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff * Wi-Fi now supports three modes of operation: Client, SoftAp and p2p
9790542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff * In the current implementation, we support concurrent wifi p2p and wifi operation.
9890542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff * The WifiStateMachine handles SoftAp and Client operations while WifiP2pService
9990542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff * handles p2p operation.
10055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
1010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @hide
1020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */
10364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savillepublic class WifiStateMachine extends StateMachine {
1040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String TAG = "WifiStateMachine";
1060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final String NETWORKTYPE = "WIFI";
1070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final boolean DBG = false;
1080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiMonitor mWifiMonitor;
110fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private WifiNative mWifiNative;
111fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private WifiConfigStore mWifiConfigStore;
112cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    private INetworkManagementService mNwService;
1130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private ConnectivityManager mCm;
1140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1157d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private final boolean mP2pSupported;
1163809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff    private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
1179f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff    private boolean mTemporarilyDisconnectWifi = false;
1184dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    private final String mPrimaryDeviceType;
1197d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
1200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan results handling */
12106d371f87be2588de6dddeefb919911c24e58e09Irfan Sheriff    private List<ScanResult> mScanResults = new ArrayList<ScanResult>();
1220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final Pattern scanResultPattern = Pattern.compile("\t+");
1230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_RESULT_CACHE_SIZE = 80;
12434ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilson    private final LruCache<String, ScanResult> mScanResultCache;
1250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
126262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff    /* Chipset supports background scan */
127262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff    private final boolean mBackgroundScanSupported;
128262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff
1290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mInterfaceName;
130c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Tethering interface could be seperate from wlan interface */
131c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private String mTetherInterfaceName;
1320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastSignalLevel = -1;
1340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private String mLastBssid;
1350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mLastNetworkId;
1360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mEnableRssiPolling = false;
137fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    private boolean mEnableBackgroundScan = false;
13819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private int mRssiPollToken = 0;
1390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int mReconnectCount = 0;
1400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private boolean mIsScanMode = false;
141fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    private boolean mScanResultIsPending = false;
1421f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Tracks if the current scan settings are active */
1431f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    private boolean mSetScanActive = false;
1441c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff    /* Tracks if state machine has received any screen state change broadcast yet.
1451c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff     * We can miss one of these at boot.
1461c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff     */
1471c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff    private AtomicBoolean mScreenBroadcastReceived = new AtomicBoolean(false);
1480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    private boolean mBluetoothConnectionActive = false;
15065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff
151262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff    private PowerManager.WakeLock mSuspendWakeLock;
152262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff
1530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
15419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Interval in milliseconds between polling for RSSI
15519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * and linkspeed information
15619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
15719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
15819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
15919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /**
16096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Delay between supplicant restarts upon failure to establish connection
16196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
16296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;
16396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
16496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /**
16596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     * Number of times we attempt to restart supplicant
16696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff     */
16796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private static final int SUPPLICANT_RESTART_TRIES = 5;
16896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
16996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    private int mSupplicantRestartCount = 0;
170cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    /* Tracks sequence number on stop failure message */
171cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    private int mSupplicantStopFailureToken = 0;
17296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
173c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /**
174c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff     * Tether state change notification time out
175c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff     */
176c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
177c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
178c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Tracks sequence number on a tether notification time out */
179c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private int mTetherToken = 0;
180c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
181f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff    /**
182f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff     * Driver start time out.
183f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff     */
184f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff    private static final int DRIVER_START_TIME_OUT_MSECS = 10000;
185f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff
186f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff    /* Tracks sequence number on a driver time out */
187f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff    private int mDriverStartToken = 0;
188f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff
18937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private LinkProperties mLinkProperties;
1900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
191027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff    /* Tracks sequence number on a periodic scan message */
192027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff    private int mPeriodicScanToken = 0;
193027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff
1944f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    // Wakelock held during wifi start/stop and driver load/unload
1954f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff    private PowerManager.WakeLock mWakeLock;
1960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private Context mContext;
1980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1990216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    private DhcpInfoInternal mDhcpInfoInternal;
2000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private WifiInfo mWifiInfo;
2010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private NetworkInfo mNetworkInfo;
2020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private SupplicantStateTracker mSupplicantStateTracker;
20331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private DhcpStateMachine mDhcpStateMachine;
20402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
205090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private AlarmManager mAlarmManager;
206090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private PendingIntent mScanIntent;
207f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer    private PendingIntent mDriverStopIntent;
208f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer
20936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /* Tracks current frequency mode */
21036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
211090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
212b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /* Tracks if we are filtering Multicast v4 packets. Default is to filter. */
213b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    private AtomicBoolean mFilteringMulticastV4Packets = new AtomicBoolean(true);
214b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
2154b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    // Channel for sending replies.
2164b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    private AsyncChannel mReplyChannel = new AsyncChannel();
2174b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private WifiP2pManager mWifiP2pManager;
21955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    //Used to initiate a connection with WifiP2pService
22055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private AsyncChannel mWifiP2pChannel = new AsyncChannel();
2219575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    private AsyncChannel mWifiApConfigChannel = new AsyncChannel();
22255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    // Event log tags (must be in sync with event-log-tags)
2240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
2250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
2260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED  = 50023;
2270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2283fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    /* The base for wifi message types */
2293fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int BASE = Protocol.BASE_WIFI;
2300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Load the driver */
2313fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_LOAD_DRIVER                      = BASE + 1;
2320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unload the driver */
2333fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_UNLOAD_DRIVER                    = BASE + 2;
2340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load succeeded */
2353fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_LOAD_DRIVER_SUCCESS              = BASE + 3;
2360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver load failed */
2373fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_LOAD_DRIVER_FAILURE              = BASE + 4;
2380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload succeeded */
2393fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_UNLOAD_DRIVER_SUCCESS            = BASE + 5;
2400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Indicates driver unload failed */
2413fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_UNLOAD_DRIVER_FAILURE            = BASE + 6;
2420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the supplicant */
2443fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_SUPPLICANT                 = BASE + 11;
2450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the supplicant */
2463fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_STOP_SUPPLICANT                  = BASE + 12;
2470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the driver */
2483fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_DRIVER                     = BASE + 13;
249e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    /* Stop the driver */
2503fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_STOP_DRIVER                      = BASE + 14;
25131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    /* Indicates Static IP succeded */
25231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    static final int CMD_STATIC_IP_SUCCESS                = BASE + 15;
25331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    /* Indicates Static IP failed */
25431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    static final int CMD_STATIC_IP_FAILURE                = BASE + 16;
255cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    /* Indicates supplicant stop failed */
256cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff    static final int CMD_STOP_SUPPLICANT_FAILED           = BASE + 17;
257e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    /* Delayed stop to avoid shutting down driver too quick*/
258e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    static final int CMD_DELAYED_STOP_DRIVER              = BASE + 18;
259f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff    /* A delayed message sent to start driver when it fail to come up */
260f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff    static final int CMD_DRIVER_START_TIMED_OUT           = BASE + 19;
261da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    /* Ready to switch to network as default */
262da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    static final int CMD_CAPTIVE_CHECK_COMPLETE           = BASE + 20;
2630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Start the soft access point */
2653fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_AP                         = BASE + 21;
2667dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Indicates soft ap start succeded */
2677dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_START_AP_SUCCESS                 = BASE + 22;
2687dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Indicates soft ap start failed */
2697dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_START_AP_FAILURE                 = BASE + 23;
2700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Stop the soft access point */
2717dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_STOP_AP                          = BASE + 24;
272ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    /* Set the soft access point configuration */
2737dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    static final int CMD_SET_AP_CONFIG                    = BASE + 25;
2749575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    /* Soft access point configuration set completed */
2759575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    static final int CMD_SET_AP_CONFIG_COMPLETED          = BASE + 26;
2769575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    /* Request the soft access point configuration */
2779575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    static final int CMD_REQUEST_AP_CONFIG                = BASE + 27;
2789575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    /* Response to access point configuration request */
2799575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    static final int CMD_RESPONSE_AP_CONFIG               = BASE + 28;
280c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Invoked when getting a tether state change notification */
281c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    static final int CMD_TETHER_STATE_CHANGE              = BASE + 29;
282c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* A delayed message sent to indicate tether state change failed to arrive */
283c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    static final int CMD_TETHER_NOTIFICATION_TIMED_OUT    = BASE + 30;
2840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
285c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 31;
2860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands */
2880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Is supplicant alive ? */
2893fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_PING_SUPPLICANT                  = BASE + 51;
2900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Add/update a network configuration */
2913fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ADD_OR_UPDATE_NETWORK            = BASE + 52;
2920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Delete a network */
2933fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_REMOVE_NETWORK                   = BASE + 53;
2940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enable a network. The device will attempt a connection to the given network. */
2953fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_NETWORK                   = BASE + 54;
2968e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    /* Enable all networks */
2973fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_ALL_NETWORKS              = BASE + 55;
2980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Blacklist network. De-prioritizes the given BSSID for connection. */
299d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    static final int CMD_BLACKLIST_NETWORK                = BASE + 56;
3000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear the blacklist network list */
301d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    static final int CMD_CLEAR_BLACKLIST                  = BASE + 57;
3020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Save configuration */
303d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    static final int CMD_SAVE_CONFIG                      = BASE + 58;
304e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff    /* Get configured networks*/
305d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    static final int CMD_GET_CONFIGURED_NETWORKS          = BASE + 59;
3060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Supplicant commands after driver start*/
3080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Initiate a scan */
3093fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_SCAN                       = BASE + 71;
3100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
3113fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_SCAN_MODE                    = BASE + 72;
3120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
3133fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_SCAN_TYPE                    = BASE + 73;
3140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Disconnect from a network */
3153fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_DISCONNECT                       = BASE + 74;
3160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reconnect to a network */
3173fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RECONNECT                        = BASE + 75;
3180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Reassociate to a network */
3193fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_REASSOCIATE                      = BASE + 76;
320e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff    /* Controls suspend mode optimizations
3215876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
322e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff     * When high perf mode is enabled, suspend mode optimizations are disabled
3235876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
324e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff     * When high perf mode is disabled, suspend mode optimizations are enabled
3255876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     *
3265876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Suspend mode optimizations include:
3275876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - packet filtering
3285876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - turn off roaming
3295876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * - DTIM wake up settings
3300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3313fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_HIGH_PERF_MODE               = BASE + 77;
332ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /* Set the country code */
3333fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_COUNTRY_CODE                 = BASE + 80;
3340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Enables RSSI poll */
3353fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_RSSI_POLL                 = BASE + 82;
3360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* RSSI poll */
3373fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RSSI_POLL                        = BASE + 83;
3380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Set up packet filtering */
3393fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_START_PACKET_FILTERING           = BASE + 84;
3400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Clear packet filter */
3413fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_STOP_PACKET_FILTERING            = BASE + 85;
342ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    /* Enable suspend mode optimizations in the driver */
343ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    static final int CMD_SET_SUSPEND_OPT_ENABLED          = BASE + 86;
344027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff    /* When there are no saved networks, we do a periodic scan to notify user of
345027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff     * an open network */
346027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff    static final int CMD_NO_NETWORKS_PERIODIC_SCAN        = BASE + 88;
347b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
348b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /* arg1 values to CMD_STOP_PACKET_FILTERING and CMD_START_PACKET_FILTERING */
349b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    static final int MULTICAST_V6  = 1;
350b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    static final int MULTICAST_V4  = 0;
351b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
352d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff   /* Set the frequency band */
3533fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_SET_FREQUENCY_BAND               = BASE + 90;
354fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    /* Enable background scan for configured networks */
3553fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_ENABLE_BACKGROUND_SCAN           = BASE + 91;
356ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
357b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Commands from/to the SupplicantStateTracker */
358b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff    /* Reset the supplicant state tracker */
3593fc75e9267a585101a06edc13d141b58efb9691fIrfan Sheriff    static final int CMD_RESET_SUPPLICANT_STATE           = BASE + 111;
360b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff
3617d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    /* P2p commands */
36262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    /* We are ok with no response here since we wont do much with it anyway */
3637d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public static final int CMD_ENABLE_P2P                = BASE + 131;
36462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    /* In order to shut down supplicant cleanly, we wait till p2p has
36562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff     * been disabled */
36662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    public static final int CMD_DISABLE_P2P_REQ           = BASE + 132;
36762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    public static final int CMD_DISABLE_P2P_RSP           = BASE + 133;
36855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int CONNECT_MODE   = 1;
3700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ONLY_MODE = 2;
3710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_ACTIVE = 1;
3730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int SCAN_PASSIVE = 2;
3740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3751406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int SUCCESS = 1;
3761406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    private static final int FAILURE = -1;
3771406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
3784494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    /* Phone in emergency call back mode */
3794494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    private static final int IN_ECM_STATE = 1;
3804494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    private static final int NOT_IN_ECM_STATE = 0;
3814494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff
3820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
3830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * The maximum number of times we will retry a connection to an access point
3840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * for which we have failed in acquiring an IP address from DHCP. A value of
3850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * N means that we will make N+1 connection attempts in all.
3860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * <p>
3870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
3880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * value if a Settings value is not present.
3890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
3900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
3910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
392ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    /* Tracks if suspend optimizations need to be disabled by DHCP,
393ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff     * screen or due to high perf mode.
394ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff     * When any of them needs to disable it, we keep the suspend optimizations
395ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff     * disabled
396ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff     */
397ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private int mSuspendOptNeedsDisabled = 0;
398ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff
399ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private static final int SUSPEND_DUE_TO_DHCP       = 1;
400ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private static final int SUSPEND_DUE_TO_HIGH_PERF  = 1<<1;
401ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private static final int SUSPEND_DUE_TO_SCREEN     = 1<<2;
402ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff
403ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    /* Tracks if user has enabled suspend optimizations through settings */
404ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private AtomicBoolean mUserWantsSuspendOpt = new AtomicBoolean(true);
4050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
406090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    /**
4072b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * Default framework scan interval in milliseconds. This is used in the scenario in which
4082b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * wifi chipset does not support background scanning to set up a
4092b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * periodic wake up scan so that the device can connect to a new access
4106f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate     * point on the move. {@link Settings.Global#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
4112b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     * override this.
412090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff     */
4132b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    private final int mDefaultFrameworkScanIntervalMs;
4142b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
4152b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    /**
416027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff     * Supplicant scan interval in milliseconds.
4176f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate     * Comes from {@link Settings.Global#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} or
418027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff     * from the default config if the setting is not set
4192b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff     */
420027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff    private long mSupplicantScanIntervalMs;
4212b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
4220f43161150903a008a5fd703078cdf446601160aIrfan Sheriff    /**
4230f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     * Minimum time interval between enabling all networks.
4240f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     * A device can end up repeatedly connecting to a bad network on screen on/off toggle
4250f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     * due to enabling every time. We add a threshold to avoid this.
4260f43161150903a008a5fd703078cdf446601160aIrfan Sheriff     */
4270f43161150903a008a5fd703078cdf446601160aIrfan Sheriff    private static final int MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS = 10 * 60 * 1000; /* 10 minutes */
4280f43161150903a008a5fd703078cdf446601160aIrfan Sheriff    private long mLastEnableAllNetworksTime;
4290f43161150903a008a5fd703078cdf446601160aIrfan Sheriff
430e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    /**
431e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff     * Starting and shutting down driver too quick causes problems leading to driver
432e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff     * being in a bad state. Delay driver stop.
433e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff     */
43409a12bcfab6600a8cc017f0a5f92259dfc8fc471Mike Lockwood    private final int mDriverStopDelayMs;
435e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    private int mDelayedStopCounter;
436e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff    private boolean mInDelayedStop = false;
437090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
4389b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff    private static final int MIN_RSSI = -200;
4399b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff    private static final int MAX_RSSI = 256;
4409b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff
4410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Default parent state */
44264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDefaultState = new DefaultState();
4430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Temporary initial state */
44464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mInitialState = new InitialState();
4450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Unloading the driver */
44664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverUnloadingState = new DriverUnloadingState();
4470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Loading the driver */
44864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverUnloadedState = new DriverUnloadedState();
4490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver load/unload failed */
45064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverFailedState = new DriverFailedState();
4510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loading */
45264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverLoadingState = new DriverLoadingState();
4530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded */
45464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverLoadedState = new DriverLoadedState();
4550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded, waiting for supplicant to start */
45664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSupplicantStartingState = new SupplicantStartingState();
4570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver loaded and supplicant ready */
45864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSupplicantStartedState = new SupplicantStartedState();
45996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    /* Waiting for supplicant to stop and monitor to exit */
46064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSupplicantStoppingState = new SupplicantStoppingState();
4610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver start issued, waiting for completed event */
46264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStartingState = new DriverStartingState();
4630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver started */
46464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStartedState = new DriverStartedState();
46562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    /* Wait until p2p is disabled
46662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff     * This is a special state which is entered right after we exit out of DriverStartedState
46762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff     * before transitioning to another state.
46862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff     */
46962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    private State mWaitForP2pDisableState = new WaitForP2pDisableState();
4700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopping */
47164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStoppingState = new DriverStoppingState();
4720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Driver stopped */
47364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDriverStoppedState = new DriverStoppedState();
4740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Scan for networks, no connection will be established */
47564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mScanModeState = new ScanModeState();
4760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connecting to an access point */
47764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mConnectModeState = new ConnectModeState();
47807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    /* Connected at 802.11 (L2) level */
47907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    private State mL2ConnectedState = new L2ConnectedState();
48007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    /* fetching IP after connection to access point (assoc+auth complete) */
48107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    private State mObtainingIpState = new ObtainingIpState();
48207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    /* Waiting for link quality verification to be complete */
48307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    private State mVerifyingLinkState = new VerifyingLinkState();
484da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    /* Waiting for captive portal check to be complete */
485da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    private State mCaptivePortalCheckState = new CaptivePortalCheckState();
4860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Connected with IP addr */
48764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mConnectedState = new ConnectedState();
4880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* disconnect issued, waiting for network disconnect confirmation */
48964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDisconnectingState = new DisconnectingState();
4900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /* Network is not connected, supplicant assoc+auth is not complete */
49164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mDisconnectedState = new DisconnectedState();
49202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    /* Waiting for WPS to be completed*/
493d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private State mWpsRunningState = new WpsRunningState();
4940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
4957dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Soft ap is starting up */
4967dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    private State mSoftApStartingState = new SoftApStartingState();
49723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    /* Soft ap is running */
49864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private State mSoftApStartedState = new SoftApStartedState();
499c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Soft ap is running and we are waiting for tether notification */
500c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private State mTetheringState = new TetheringState();
50123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    /* Soft ap is running and we are tethered through connectivity service */
50223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    private State mTetheredState = new TetheredState();
503c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    /* Waiting for untether confirmation to stop soft Ap */
504c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private State mSoftApStoppingState = new SoftApStoppingState();
5050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
506c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private class TetherStateChange {
507c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        ArrayList<String> available;
508c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        ArrayList<String> active;
509c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
510c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            available = av;
511c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            active = ac;
512c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
513c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
514c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
5150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
5180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_DISABLING},
5190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLED},
5200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_ENABLING},
5210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
5220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
5230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
5250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
5270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
5280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
5290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
5300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
5310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
5320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
5330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
5340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
5350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastEnableUid = new AtomicInteger(Process.myUid());
5370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final AtomicInteger mLastApEnableUid = new AtomicInteger(Process.myUid());
5380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
539090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final int SCAN_REQUEST = 0;
540090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff    private static final String ACTION_START_SCAN =
541090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        "com.android.server.WifiManager.action.START_SCAN";
542090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
543f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer    private static final String DELAYED_STOP_COUNTER = "DelayedStopCounter";
544f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer    private static final int DRIVER_STOP_REQUEST = 0;
545f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer    private static final String ACTION_DELAYED_DRIVER_STOP =
546f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer        "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP";
547f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer
54803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
54903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether WIFI is running.
55003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
55103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mIsRunning = false;
5525ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
55303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
55403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Keep track of whether we last told the battery stats we had started.
55503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
55603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private boolean mReportedRunning = false;
55703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
55803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
55903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * Most recently set source of starting WIFI.
56003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
56103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mRunningWifiUids = new WorkSource();
56203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
56303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    /**
56403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     * The last reported UIDs that were responsible for starting WIFI.
56503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn     */
56603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    private final WorkSource mLastRunningWifiUids = new WorkSource();
56703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
5680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private final IBatteryStats mBatteryStats;
5690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
570227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff    public WifiStateMachine(Context context, String wlanInterface) {
5710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        super(TAG);
5720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mContext = context;
574227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff        mInterfaceName = wlanInterface;
5750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
5770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
5780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
580cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
5810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5827d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
5837d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                PackageManager.FEATURE_WIFI_DIRECT);
5847d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
585fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative = new WifiNative(mInterfaceName);
586fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
587fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiMonitor = new WifiMonitor(this, mWifiNative);
5880216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        mDhcpInfoInternal = new DhcpInfoInternal();
5890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo = new WifiInfo();
590fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,
591fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                getHandler());
59237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties = new LinkProperties();
5930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
5949575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
5959575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                context, getHandler());
5969575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        wifiApConfigStore.loadApConfiguration();
5979575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        mWifiApConfigChannel.connectSync(mContext, getHandler(), wifiApConfigStore.getMessenger());
5989575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff
5990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mNetworkInfo.setIsAvailable(false);
60037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
6010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid = null;
6020a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
6030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastSignalLevel = -1;
6040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
605090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
606090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        Intent scanIntent = new Intent(ACTION_START_SCAN, null);
607090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
608090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
6092b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger(
6103809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                R.integer.config_wifi_framework_scan_interval);
6112b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
61209a12bcfab6600a8cc017f0a5f92259dfc8fc471Mike Lockwood        mDriverStopDelayMs = mContext.getResources().getInteger(
6133809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                R.integer.config_wifi_driver_stop_delay);
61409a12bcfab6600a8cc017f0a5f92259dfc8fc471Mike Lockwood
615262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff        mBackgroundScanSupported = mContext.getResources().getBoolean(
6163809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                R.bool.config_wifi_background_scan_support);
617262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff
6184dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        mPrimaryDeviceType = mContext.getResources().getString(
6193809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                R.string.config_wifi_p2p_device_type);
6204dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
621bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        mUserWantsSuspendOpt.set(Settings.Global.getInt(mContext.getContentResolver(),
622bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                    Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
6233fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff
624090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        mContext.registerReceiver(
62543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            new BroadcastReceiver() {
62643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                @Override
62743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                public void onReceive(Context context, Intent intent) {
62843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    ArrayList<String> available = intent.getStringArrayListExtra(
62943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            ConnectivityManager.EXTRA_AVAILABLE_TETHER);
630c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    ArrayList<String> active = intent.getStringArrayListExtra(
631c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                            ConnectivityManager.EXTRA_ACTIVE_TETHER);
632c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
63343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                }
63443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
63543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
63643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        mContext.registerReceiver(
637090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new BroadcastReceiver() {
638090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    @Override
639090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    public void onReceive(Context context, Intent intent) {
640090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                        startScan(false);
641090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                    }
642090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                },
643090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                new IntentFilter(ACTION_START_SCAN));
644090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
645633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        IntentFilter screenFilter = new IntentFilter();
646633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        screenFilter.addAction(Intent.ACTION_SCREEN_ON);
647633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        screenFilter.addAction(Intent.ACTION_SCREEN_OFF);
648633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        BroadcastReceiver screenReceiver = new BroadcastReceiver() {
649262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff            @Override
650262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff            public void onReceive(Context context, Intent intent) {
651262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                String action = intent.getAction();
652262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff
653262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                if (action.equals(Intent.ACTION_SCREEN_ON)) {
6541c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                    handleScreenStateChanged(true);
655262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
6561c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                    handleScreenStateChanged(false);
657262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                }
658262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff            }
659262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff        };
660633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        mContext.registerReceiver(screenReceiver, screenFilter);
6613fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff
662f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer        mContext.registerReceiver(
663f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                new BroadcastReceiver() {
664f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                    @Override
665f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                    public void onReceive(Context context, Intent intent) {
666f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                       int counter = intent.getIntExtra(DELAYED_STOP_COUNTER, 0);
667f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                       sendMessage(obtainMessage(CMD_DELAYED_STOP_DRIVER, counter, 0));
668f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                    }
669f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                },
670f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                new IntentFilter(ACTION_DELAYED_DRIVER_STOP));
671262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff
672bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
673bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED), false,
6743fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff                new ContentObserver(getHandler()) {
6753fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff                    @Override
6763fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff                    public void onChange(boolean selfChange) {
677bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                        mUserWantsSuspendOpt.set(Settings.Global.getInt(mContext.getContentResolver(),
678bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                                Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
6793fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff                    }
6803fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff                });
6813fb4ba616edb114b3197936eb67f481eb86b7caeIrfan Sheriff
68234ee52e60c7bd220d755f30ee7924cc04e0b3ca2Jesse Wilson        mScanResultCache = new LruCache<String, ScanResult>(SCAN_RESULT_CACHE_SIZE);
6830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
6854f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
6860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
687262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff        mSuspendWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WifiSuspend");
688262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff        mSuspendWakeLock.setReferenceCounted(false);
689262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff
6900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        addState(mDefaultState);
6910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mInitialState, mDefaultState);
6920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadingState, mDefaultState);
6930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverUnloadedState, mDefaultState);
6940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                addState(mDriverFailedState, mDriverUnloadedState);
6950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadingState, mDefaultState);
6960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mDriverLoadedState, mDefaultState);
69796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartingState, mDefaultState);
69896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStartedState, mDefaultState);
69996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartingState, mSupplicantStartedState);
70096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStartedState, mSupplicantStartedState);
7010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mScanModeState, mDriverStartedState);
7020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    addState(mConnectModeState, mDriverStartedState);
70307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        addState(mL2ConnectedState, mConnectModeState);
70407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                            addState(mObtainingIpState, mL2ConnectedState);
70507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                            addState(mVerifyingLinkState, mL2ConnectedState);
706da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                            addState(mCaptivePortalCheckState, mL2ConnectedState);
70707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                            addState(mConnectedState, mL2ConnectedState);
7080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectingState, mConnectModeState);
7090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        addState(mDisconnectedState, mConnectModeState);
710d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        addState(mWpsRunningState, mConnectModeState);
71162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                addState(mWaitForP2pDisableState, mSupplicantStartedState);
71296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppingState, mSupplicantStartedState);
71396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                addState(mDriverStoppedState, mSupplicantStartedState);
71496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            addState(mSupplicantStoppingState, mDefaultState);
7157dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            addState(mSoftApStartingState, mDefaultState);
7160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            addState(mSoftApStartedState, mDefaultState);
717c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                addState(mTetheringState, mSoftApStartedState);
71823eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                addState(mTetheredState, mSoftApStartedState);
719c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            addState(mSoftApStoppingState, mDefaultState);
7200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        setInitialState(mInitialState);
7220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
723bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        setLogRecSize(100);
7240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (DBG) setDbg(true);
7250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //start the state machine
7270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        start();
7280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
7310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Methods exposed for public use
7320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
7330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
73407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    public Messenger getMessenger() {
73507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        return new Messenger(getHandler());
73607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    }
7370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7401406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncPingSupplicant(AsyncChannel channel) {
7411406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
7421406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
7431406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
7441406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
7450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
750e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void startScan(boolean forceActive) {
751e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
752e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                SCAN_ACTIVE : SCAN_PASSIVE, 0));
7530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiEnabled(boolean enable) {
7590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastEnableUid.set(Binder.getCallingUid());
7600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
7610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
7620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
7630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_START_SUPPLICANT);
7640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
7650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_SUPPLICANT);
7660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
7670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
7680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
7690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
7710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
7730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
7740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
7750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastApEnableUid.set(Binder.getCallingUid());
7760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (enable) {
7770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered prior to load */
7780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
7790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
7800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } else {
7810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(CMD_STOP_AP);
7820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Argument is the state that is entered upon success */
7830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
7840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
7850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
7860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
787ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    public void setWifiApConfiguration(WifiConfiguration config) {
7889575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
789ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    }
790ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff
7919575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    public WifiConfiguration syncGetWifiApConfiguration() {
7929575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        Message resultMsg = mWifiApConfigChannel.sendMessageSynchronously(CMD_REQUEST_AP_CONFIG);
793ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff        WifiConfiguration ret = (WifiConfiguration) resultMsg.obj;
794ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff        resultMsg.recycle();
795ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff        return ret;
796ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    }
797ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff
7980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
7990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
801d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiState() {
8020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiState.get();
8030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
808d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiStateByName() {
8090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiState.get()) {
8100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLING:
8110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
8120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_DISABLED:
8130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
8140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLING:
8150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
8160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_ENABLED:
8170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
8180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_STATE_UNKNOWN:
8190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "unknown state";
8200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
8210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
8220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
8230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
828d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public int syncGetWifiApState() {
8290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiApState.get();
8300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
835d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public String syncGetWifiApStateByName() {
8360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        switch (mWifiApState.get()) {
8370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLING:
8380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabling";
8390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_DISABLED:
8400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "disabled";
8410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLING:
8420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabling";
8430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_ENABLED:
8440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "enabled";
8450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            case WIFI_AP_STATE_FAILED:
8460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "failed";
8470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            default:
8480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                return "[invalid state]";
8490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
8500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Get status information for the current connection, if any.
8540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return a {@link WifiInfo} object containing information about the current connection
8550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
8560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
857d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public WifiInfo syncRequestConnectionInfo() {
8580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        return mWifiInfo;
8590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
861d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public DhcpInfo syncGetDhcpInfo() {
8620216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        synchronized (mDhcpInfoInternal) {
8630216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            return mDhcpInfoInternal.makeDhcpInfo();
86431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
8650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8704494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff    public void setDriverStart(boolean enable, boolean ecm) {
8714f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        if (enable) {
8724f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            sendMessage(CMD_START_DRIVER);
8734f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        } else {
8744494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff            sendMessage(obtainMessage(CMD_STOP_DRIVER, ecm ? IN_ECM_STATE : NOT_IN_ECM_STATE, 0));
8754f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff        }
8760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
878da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    public void captivePortalCheckComplete() {
879da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        sendMessage(obtainMessage(CMD_CAPTIVE_CHECK_COMPLETE));
880da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    }
881da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
8820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanOnlyMode(boolean enable) {
8860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (enable) {
8870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, SCAN_ONLY_MODE, 0));
8880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
8890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_MODE, CONNECT_MODE, 0));
8900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
8910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
8920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
8930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
8940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
8950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
8960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void setScanType(boolean active) {
8970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      if (active) {
8980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_ACTIVE, 0));
8990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      } else {
9000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff          sendMessage(obtainMessage(CMD_SET_SCAN_TYPE, SCAN_PASSIVE, 0));
9010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff      }
9020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: doc
9060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
907d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff    public List<ScanResult> syncGetScanResultsList() {
90806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        synchronized (mScanResultCache) {
90906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            List<ScanResult> scanList = new ArrayList<ScanResult>();
91006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            for(ScanResult result: mScanResults) {
91106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                scanList.add(new ScanResult(result));
91206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            }
91306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            return scanList;
91406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        }
9150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disconnect from Access Point
9190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
920e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void disconnectCommand() {
921e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_DISCONNECT);
9220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a reconnection to AP
9260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
927e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reconnectCommand() {
928e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_RECONNECT);
9290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Initiate a re-association to AP
9330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
934e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff    public void reassociateCommand() {
935e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff        sendMessage(CMD_REASSOCIATE);
9360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Add a network synchronously
9400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return network id of the new network
9420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9431406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
9441406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
9451406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        int result = resultMsg.arg1;
9461406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9471406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
950e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff    public List<WifiConfiguration> syncGetConfiguredNetworks(AsyncChannel channel) {
951e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONFIGURED_NETWORKS);
952e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
953e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        resultMsg.recycle();
954e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        return result;
9550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Delete a network
9590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param networkId id of the network to be removed
9610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9624b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
9634b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
9641406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9654b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        resultMsg.recycle();
9664b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville        return result;
9674b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    }
9684b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville
9694b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville    /**
9700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Enable a network
9710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
9730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param disableOthers true, if all other networks have to be disabled
9740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
9750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9761406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
9771406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
9781406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                disableOthers ? 1 : 0);
9791406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
9801406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9811406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Disable a network
9860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
9870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param netId network id of the network
9880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
9890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
9901406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
991d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(WifiManager.DISABLE_NETWORK, netId);
992d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        boolean result = (resultMsg.arg1 != WifiManager.DISABLE_NETWORK_FAILED);
9931406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
9941406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
9950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
9960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
9970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
9980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Blacklist a BSSID. This will avoid the AP if there are
9990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * alternate APs to connect
10000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
10010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @param bssid BSSID of the network
10020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void addToBlacklist(String bssid) {
10040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_BLACKLIST_NETWORK, bssid));
10050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Clear the blacklist list
10090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
10100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void clearBlacklist() {
10120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        sendMessage(obtainMessage(CMD_CLEAR_BLACKLIST));
10130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    public void enableRssiPolling(boolean enabled) {
10160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
10170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10192b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff    public void enableBackgroundScanCommand(boolean enabled) {
1020fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff       sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0));
1021fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff    }
1022fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff
10238e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    public void enableAllNetworks() {
10248e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        sendMessage(CMD_ENABLE_ALL_NETWORKS);
10258e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff    }
10268e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff
10270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1028b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering Multicast v4 packets
1029b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
1030b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void startFilteringMulticastV4Packets() {
1031b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        mFilteringMulticastV4Packets.set(true);
1032b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_START_PACKET_FILTERING, MULTICAST_V4, 0));
1033b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    }
1034b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
1035b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
1036b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering Multicast v4 packets
1037b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
1038b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void stopFilteringMulticastV4Packets() {
1039b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        mFilteringMulticastV4Packets.set(false);
1040b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V4, 0));
1041b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    }
1042b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
1043b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
1044b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering Multicast v4 packets
10450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1046b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void startFilteringMulticastV6Packets() {
1047b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_START_PACKET_FILTERING, MULTICAST_V6, 0));
10480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1051b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering Multicast v4 packets
10520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1053b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    public void stopFilteringMulticastV6Packets() {
1054b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff        sendMessage(obtainMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V6, 0));
10550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
10585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Set high performance mode of operation.
10595876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * Enabling would set active power mode and disable suspend optimizations;
10605876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * disabling would set auto power mode and enable suspend optimizations
10615876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff     * @param enable true if enable, false otherwise
10620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
10635876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff    public void setHighPerfModeEnabled(boolean enable) {
10645876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff        sendMessage(obtainMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0));
10650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
1068ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code
1069ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param countryCode following ISO 3166 format
1070ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
10710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1072ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    public void setCountryCode(String countryCode, boolean persist) {
1073ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (persist) {
1074bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown            Settings.Global.putString(mContext.getContentResolver(),
1075bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                    Settings.Global.WIFI_COUNTRY_CODE,
1076ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    countryCode);
10770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
1078ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_COUNTRY_CODE, countryCode));
10790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
10800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
10810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
108236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the operational frequency band
108336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param band
108436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * @param persist {@code true} if the setting should be remembered.
108536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
108636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public void setFrequencyBand(int band, boolean persist) {
108736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        if (persist) {
1088bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey            Settings.Global.putInt(mContext.getContentResolver(),
1089bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                    Settings.Global.WIFI_FREQUENCY_BAND,
109036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    band);
109136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        }
109236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        sendMessage(obtainMessage(CMD_SET_FREQUENCY_BAND, band, 0));
109336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
109436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
109536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
109636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Returns the operational frequency band
109736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
109836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    public int getFrequencyBand() {
109936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        return mFrequencyBand.get();
110036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
110136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
110236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
11034aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff     * Returns the wifi configuration file
11044aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff     */
11054aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    public String getConfigFile() {
1106fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return mWifiConfigStore.getConfigFile();
11074aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    }
11084aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff
11094aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    /**
111065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff     * Send a message indicating bluetooth adapter connection state changed
11110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
111265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff    public void sendBluetoothAdapterStateChange(int state) {
111365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff        sendMessage(obtainMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0));
11140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
11160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
11170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Save configuration on supplicant
11180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
11190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * @return {@code true} if the operation succeeds, {@code false} otherwise
11200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *
11210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * TODO: deprecate this
11220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
11231406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff    public boolean syncSaveConfig(AsyncChannel channel) {
11241406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
11251406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        boolean result = (resultMsg.arg1 != FAILURE);
11261406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        resultMsg.recycle();
11271406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff        return result;
11280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
11290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
113003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    public void updateBatteryWorkSource(WorkSource newSource) {
113103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        synchronized (mRunningWifiUids) {
113203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            try {
113303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (newSource != null) {
113403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    mRunningWifiUids.set(newSource);
113503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
113603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                if (mIsRunning) {
113703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
113803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // If the work source has changed since last time, need
113903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // to remove old work from battery stats.
114003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
114103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
114203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                                    mRunningWifiUids);
114303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                            mLastRunningWifiUids.set(mRunningWifiUids);
114403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        }
114503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    } else {
114603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Now being started, report it.
114703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
114803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.set(mRunningWifiUids);
114903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = true;
115003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
115103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                } else {
115203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    if (mReportedRunning) {
115303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        // Last reported we were running, time to stop.
115403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
115503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mLastRunningWifiUids.clear();
115603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                        mReportedRunning = false;
115703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                    }
115803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                }
11594f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                mWakeLock.setWorkSource(newSource);
116003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            } catch (RemoteException ignore) {
116103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            }
116203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn        }
116303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn    }
116403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn
1165bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    @Override
1166bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    public String toString() {
1167bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        StringBuffer sb = new StringBuffer();
1168bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        String LS = System.getProperty("line.separator");
1169bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
117037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
1171bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
11720216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        sb.append("mDhcpInfoInternal ").append(mDhcpInfoInternal).append(LS);
1173bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
1174bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
1175bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastBssid ").append(mLastBssid).append(LS);
1176bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
1177bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
1178bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
1179ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        sb.append("mUserWantsSuspendOpt ").append(mUserWantsSuspendOpt).append(LS);
1180ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        sb.append("mSuspendOptNeedsDisabled ").append(mSuspendOptNeedsDisabled).append(LS);
1181bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        sb.append("Supplicant status").append(LS)
1182fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                .append(mWifiNative.status()).append(LS).append(LS);
118304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1184fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        sb.append(mWifiConfigStore.dump());
1185bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff        return sb.toString();
1186bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff    }
1187bbc85ab3229ea51b1358711fba99e3bf170ab825Irfan Sheriff
118860792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff    @Override
1189bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected boolean recordLogRec(Message msg) {
119060792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff        //Ignore screen on/off & common messages when driver has started
119160792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff        if (getCurrentState() == mConnectedState || getCurrentState() == mDisconnectedState) {
119260792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            switch (msg.what) {
119360792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_LOAD_DRIVER:
119460792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_START_SUPPLICANT:
119560792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_START_DRIVER:
119660792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_SET_SCAN_MODE:
119760792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1198ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                case CMD_SET_SUSPEND_OPT_ENABLED:
119960792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_ENABLE_BACKGROUND_SCAN:
120060792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
120160792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                return false;
120260792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            }
120360792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff        }
120460792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff
120560792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff        switch (msg.what) {
120660792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            case CMD_START_SCAN:
120760792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            case CMD_ENABLE_RSSI_POLL:
120860792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            case CMD_RSSI_POLL:
120960792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            case CMD_DELAYED_STOP_DRIVER:
121060792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            case WifiMonitor.SCAN_RESULTS_EVENT:
1211f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng            case WifiManager.RSSI_PKTCNT_FETCH:
121260792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                return false;
121360792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff            default:
121460792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff                return true;
121560792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff        }
121660792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff    }
121760792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff
12180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /*********************************************************
12190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Internal private functions
12200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     ********************************************************/
12210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
12221c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff    private void handleScreenStateChanged(boolean screenOn) {
12231c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        if (DBG) log("handleScreenStateChanged: " + screenOn);
12241c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        enableRssiPolling(screenOn);
12251c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        if (mBackgroundScanSupported) {
12261c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            enableBackgroundScanCommand(screenOn == false);
12271c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        }
12281c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff
12291c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        if (screenOn) enableAllNetworks();
12301c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        if (mUserWantsSuspendOpt.get()) {
12311c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            if (screenOn) {
12321c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                sendMessage(obtainMessage(CMD_SET_SUSPEND_OPT_ENABLED, 0, 0));
12331c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            } else {
12341c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                //Allow 2s for suspend optimizations to be set
12351c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                mSuspendWakeLock.acquire(2000);
12361c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                sendMessage(obtainMessage(CMD_SET_SUSPEND_OPT_ENABLED, 1, 0));
12371c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            }
12381c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        }
12391c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff        mScreenBroadcastReceived.set(true);
12401c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff    }
12411c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff
124223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    private void checkAndSetConnectivityInstance() {
124343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        if (mCm == null) {
124443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
124543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        }
124623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    }
124723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
1248e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff    private boolean startTethering(ArrayList<String> available) {
124923eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
125023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        boolean wifiAvailable = false;
125123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
125223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        checkAndSetConnectivityInstance();
125343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
125443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
125543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
125643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        for (String intf : available) {
125743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            for (String regex : wifiRegexs) {
125843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                if (intf.matches(regex)) {
125943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
126043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    InterfaceConfiguration ifcg = null;
126143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    try {
1262cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        ifcg = mNwService.getInterfaceConfig(intf);
126343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        if (ifcg != null) {
126443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                            /* IP/netmask: 192.168.43.1/255.255.255.0 */
1265ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                            ifcg.setLinkAddress(new LinkAddress(
1266ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                                    NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
1267ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                            ifcg.setInterfaceUp();
126843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
1269cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                            mNwService.setInterfaceConfig(intf, ifcg);
127043e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                        }
127143e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    } catch (Exception e) {
12727f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Error configuring interface " + intf + ", :" + e);
1273e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                        return false;
127443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
127543e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
127643e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
12777f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Error tethering on " + intf);
1278e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                        return false;
127943e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                    }
1280c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    mTetherInterfaceName = intf;
1281e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                    return true;
128243e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff                }
128343e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff            }
128443e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff        }
1285e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff        // We found no interfaces to tether
1286e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff        return false;
128743e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff    }
128843e747ef59e67734392d2d189e59fb9d11901037Irfan Sheriff
128923eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    private void stopTethering() {
129023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
129123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        checkAndSetConnectivityInstance();
129223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
129323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        /* Clear the interface config to allow dhcp correctly configure new
129423eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff           ip settings */
129523eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        InterfaceConfiguration ifcg = null;
129623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        try {
1297a6b6556082d371da030f2b32699380d1e0f00c28Vishal Mahaveer            ifcg = mNwService.getInterfaceConfig(mTetherInterfaceName);
129823eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            if (ifcg != null) {
1299ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                ifcg.setLinkAddress(
1300ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                        new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
1301a6b6556082d371da030f2b32699380d1e0f00c28Vishal Mahaveer                mNwService.setInterfaceConfig(mTetherInterfaceName, ifcg);
130223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            }
130323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        } catch (Exception e) {
1304a6b6556082d371da030f2b32699380d1e0f00c28Vishal Mahaveer            loge("Error resetting interface " + mTetherInterfaceName + ", :" + e);
130523eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
130623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
1307c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
13087f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Untether initiate failed!");
130923eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
131023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    }
131123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
1312c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    private boolean isWifiTethered(ArrayList<String> active) {
1313c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
1314c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        checkAndSetConnectivityInstance();
1315c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
1316c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
1317c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        for (String intf : active) {
1318c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            for (String regex : wifiRegexs) {
1319c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                if (intf.matches(regex)) {
1320c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return true;
1321c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                }
1322c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            }
1323c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
1324c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        // We found no interfaces that are tethered
1325c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        return false;
1326c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
1327c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
1328ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    /**
1329ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     * Set the country code from the system setting value, if any.
1330ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff     */
1331ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    private void setCountryCode() {
1332bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
1333bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                Settings.Global.WIFI_COUNTRY_CODE);
1334ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        if (countryCode != null && !countryCode.isEmpty()) {
1335ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode(countryCode, false);
1336ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        } else {
1337ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            //use driver default
1338ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff        }
1339ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff    }
1340ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
134136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    /**
134236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     * Set the frequency band from the system setting value, if any.
134336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff     */
134436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    private void setFrequencyBand() {
1345bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        int band = Settings.Global.getInt(mContext.getContentResolver(),
1346bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
134736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff        setFrequencyBand(band, false);
134836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff    }
134936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff
1350ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private void setSuspendOptimizationsNative(int reason, boolean enabled) {
1351ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        if (DBG) log("setSuspendOptimizationsNative: " + reason + " " + enabled);
1352ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        if (enabled) {
1353ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            mSuspendOptNeedsDisabled &= ~reason;
1354ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            /* None of dhcp, screen or highperf need it disabled and user wants it enabled */
1355ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) {
1356ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                mWifiNative.setSuspendOptimizations(true);
1357ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            }
1358ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        } else {
1359ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            mSuspendOptNeedsDisabled |= reason;
1360ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            mWifiNative.setSuspendOptimizations(false);
1361ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        }
1362ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    }
1363ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff
1364ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    private void setSuspendOptimizations(int reason, boolean enabled) {
1365ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        if (DBG) log("setSuspendOptimizations: " + reason + " " + enabled);
1366ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        if (enabled) {
1367ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            mSuspendOptNeedsDisabled &= ~reason;
1368ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        } else {
1369ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff            mSuspendOptNeedsDisabled |= reason;
1370ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        }
1371ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        if (DBG) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
1372ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff    }
1373ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff
13740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiState(int wifiState) {
13750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiState = mWifiState.get();
13760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
13780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiState == WIFI_STATE_ENABLED) {
137903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
13800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiState == WIFI_STATE_DISABLED) {
138103f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
13820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
13830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
13847f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to note battery stats in wifi");
13850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
13860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiState.set(wifiState);
13880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13897f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("setWifiState: " + syncGetWifiStateByName());
13900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
13920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
13930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
13940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
13955ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
13960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
13970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
13980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void setWifiApState(int wifiApState) {
13990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final int previousWifiApState = mWifiApState.get();
14000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        try {
14020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (wifiApState == WIFI_AP_STATE_ENABLED) {
140303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOn();
14040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
140503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn                mBatteryStats.noteWifiOff();
14060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
14070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        } catch (RemoteException e) {
14087f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to note battery stats in wifi");
14090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
14100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        // Update state
14120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiApState.set(wifiApState);
14130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14147f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
14150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
14160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
14170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
14180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
14190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
14205ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
14210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
14220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
142306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String BSSID_STR = "bssid=";
142406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String FREQ_STR = "freq=";
142506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String LEVEL_STR = "level=";
142606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String TSF_STR = "tsf=";
142706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String FLAGS_STR = "flags=";
142806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String SSID_STR = "ssid=";
142906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private static final String DELIMITER_STR = "====";
14300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
143106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * Format:
143206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * bssid=68:7f:76:d7:1a:6e
143306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * freq=2412
143406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * level=-44
143506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * tsf=1344626243700342
143606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * flags=[WPA2-PSK-CCMP][WPS][ESS]
143706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * ssid=zfdy
143806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * ====
143906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * bssid=68:5f:74:d7:1a:6f
144006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * freq=5180
144106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * level=-73
144206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * tsf=1344626243700373
144306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * flags=[WPA2-PSK-CCMP][WPS][ESS]
144406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * ssid=zuby
144506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * ====
14460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
144706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    private void setScanResults(String scanResults) {
144806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        String bssid = "";
144906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        int level = 0;
145006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        int freq = 0;
145106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        long tsf = 0;
145206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        String flags = "";
1453b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff        WifiSsid wifiSsid = null;
145406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev
145506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        if (scanResults == null) {
145606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            return;
145706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        }
145806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev
145906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev        synchronized(mScanResultCache) {
146006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            mScanResults = new ArrayList<ScanResult>();
146106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            String[] lines = scanResults.split("\n");
146206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev
146306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            for (String line : lines) {
146406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                if (line.startsWith(BSSID_STR)) {
146506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    bssid = line.substring(BSSID_STR.length());
146606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                } else if (line.startsWith(FREQ_STR)) {
1467b31f78f93768fef269617ec788a5c6655a375f80Irfan Sheriff                    try {
146806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        freq = Integer.parseInt(line.substring(FREQ_STR.length()));
146906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    } catch (NumberFormatException e) {
147006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        freq = 0;
147106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    }
147206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                } else if (line.startsWith(LEVEL_STR)) {
147306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    try {
147406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        level = Integer.parseInt(line.substring(LEVEL_STR.length()));
14750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* some implementations avoid negative values by adding 256
14760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         * so we need to adjust for that here.
14770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                         */
14780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        if (level > 0) level -= 256;
147906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    } catch(NumberFormatException e) {
1480578531082b8e8c8aa03868e69591b7613b0e8b8eIliyan Malchev                        level = 0;
14810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
148206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                } else if (line.startsWith(TSF_STR)) {
148306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    try {
148406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        tsf = Long.parseLong(line.substring(TSF_STR.length()));
148506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    } catch (NumberFormatException e) {
148606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        tsf = 0;
1487578531082b8e8c8aa03868e69591b7613b0e8b8eIliyan Malchev                    }
148806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                } else if (line.startsWith(FLAGS_STR)) {
148906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    flags = line.substring(FLAGS_STR.length());
149006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                } else if (line.startsWith(SSID_STR)) {
1491b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                    wifiSsid = WifiSsid.createFromAsciiEncoded(
1492b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                            line.substring(SSID_STR.length()));
149306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                } else if (line.startsWith(DELIMITER_STR)) {
149406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    if (bssid != null) {
1495b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                        String ssid = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
149606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        String key = bssid + ssid;
149706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        ScanResult scanResult = mScanResultCache.get(key);
149806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        if (scanResult != null) {
149906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                            scanResult.level = level;
1500b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                            scanResult.wifiSsid = wifiSsid;
1501b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                            // Keep existing API
1502b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                            scanResult.SSID = (wifiSsid != null) ? wifiSsid.toString() :
1503b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                                    WifiSsid.NONE;
150406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                            scanResult.capabilities = flags;
150506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                            scanResult.frequency = freq;
150606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                            scanResult.timestamp = tsf;
150706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        } else {
15080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            scanResult =
15090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                new ScanResult(
1510b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                                        wifiSsid, bssid, flags, level, freq, tsf);
15110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            mScanResultCache.put(key, scanResult);
15120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
151306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                        mScanResults.add(scanResult);
15140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
151506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    bssid = null;
151606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    level = 0;
151706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    freq = 0;
151806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    tsf = 0;
151906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev                    flags = "";
1520b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                    wifiSsid = null;
15210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
15220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
15230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
15240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
15250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
152619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    /*
152719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     * Fetch RSSI and linkspeed on current connection
152819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff     */
152919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    private void fetchRssiAndLinkSpeedNative() {
1530921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        int newRssi = -1;
1531921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        int newLinkSpeed = -1;
1532921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
1533fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        String signalPoll = mWifiNative.signalPoll();
1534921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
1535921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        if (signalPoll != null) {
1536921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff            String[] lines = signalPoll.split("\n");
1537921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff            for (String line : lines) {
1538921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                String[] prop = line.split("=");
1539921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                if (prop.length < 2) continue;
1540921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                try {
1541921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    if (prop[0].equals("RSSI")) {
1542921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                        newRssi = Integer.parseInt(prop[1]);
1543921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    } else if (prop[0].equals("LINKSPEED")) {
1544921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                        newLinkSpeed = Integer.parseInt(prop[1]);
1545921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    }
1546921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                } catch (NumberFormatException e) {
1547921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                    //Ignore, defaults on rssi and linkspeed are assigned
1548921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff                }
1549921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff            }
1550921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        }
1551921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
15529b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        if (newRssi != -1 && MIN_RSSI < newRssi && newRssi < MAX_RSSI) { // screen out invalid values
155319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /* some implementations avoid negative values by adding 256
155419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * so we need to adjust for that here.
155519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
155619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newRssi > 0) newRssi -= 256;
155719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setRssi(newRssi);
155819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            /*
155919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * Rather then sending the raw RSSI out every time it
156019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes, we precalculate the signal level that would
156119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * be displayed in the status bar, and only send the
156219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * broadcast if that much more coarse-grained number
156319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * changes. This cuts down greatly on the number of
1564ea933cb3fddbf5971dd4c62090edabbed295c3a7Irfan Sheriff             * broadcasts, at the cost of not informing others
156519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * interested in RSSI of all the changes in signal
156619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             * level.
156719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff             */
1568ea933cb3fddbf5971dd4c62090edabbed295c3a7Irfan Sheriff            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, WifiManager.RSSI_LEVELS);
156919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (newSignalLevel != mLastSignalLevel) {
157019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                sendRssiChangeBroadcast(newRssi);
157119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
157219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mLastSignalLevel = newSignalLevel;
157319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        } else {
15749b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            mWifiInfo.setRssi(MIN_RSSI);
157519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
1576921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
157719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        if (newLinkSpeed != -1) {
157819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mWifiInfo.setLinkSpeed(newLinkSpeed);
157919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff        }
158019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff    }
158119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff
1582b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng    /*
1583b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng     * Fetch TX packet counters on current connection
1584b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng     */
1585f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng    private void fetchPktcntNative(RssiPacketCountInfo info) {
1586b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng        String pktcntPoll = mWifiNative.pktcntPoll();
1587b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng
1588b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng        if (pktcntPoll != null) {
1589b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng            String[] lines = pktcntPoll.split("\n");
1590b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng            for (String line : lines) {
1591b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                String[] prop = line.split("=");
1592b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                if (prop.length < 2) continue;
1593b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                try {
1594b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                    if (prop[0].equals("TXGOOD")) {
1595f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                        info.txgood = Integer.parseInt(prop[1]);
1596b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                    } else if (prop[0].equals("TXBAD")) {
1597f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                        info.txbad = Integer.parseInt(prop[1]);
1598b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                    }
1599b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                } catch (NumberFormatException e) {
1600b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                    //Ignore
1601b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng                }
1602b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng            }
1603b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng        }
1604b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng    }
1605b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng
160637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    private void configureLinkProperties() {
1607fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
1608fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mLinkProperties = mWifiConfigStore.getLinkProperties(mLastNetworkId);
160996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
16100216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            synchronized (mDhcpInfoInternal) {
16110216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                mLinkProperties = mDhcpInfoInternal.makeLinkProperties();
161296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
1613fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mLinkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
1614128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
161596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        mLinkProperties.setInterfaceName(mInterfaceName);
16167f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) {
16177f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            log("netId=" + mLastNetworkId  + " Link configured: " +
16187f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    mLinkProperties.toString());
16197f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        }
16200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private int getMaxDhcpRetries() {
1623bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown        return Settings.Global.getInt(mContext.getContentResolver(),
1624bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                                      Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
16250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                      DEFAULT_MAX_DHCP_RETRIES);
16260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendScanResultsAvailableBroadcast() {
1629be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
1630be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16315ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
16320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendRssiChangeBroadcast(final int newRssi) {
16350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
1636be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
163817d9f6753aa7a00af425fec2305ece5f8b367794Irfan Sheriff        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendNetworkStateChangeBroadcast(String bssid) {
16420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
1643ea22ddd6bc855238f5e806bf576c48a672d05e4bIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
164407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
1645ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties));
16460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (bssid != null)
16470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
164807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        if (mNetworkInfo.getDetailedState() == DetailedState.VERIFYING_POOR_LINK ||
164907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) {
16503550ac919c492f3fbaebbf868f4df0d1ea7ee784Isaac Levy            intent.putExtra(WifiManager.EXTRA_WIFI_INFO, new WifiInfo(mWifiInfo));
165107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        }
16525ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1655be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void sendLinkConfigurationChangedBroadcast() {
1656be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
1657be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1658ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));
16595ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
16600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
16630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
1664be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
16665ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
16670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
16690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
16700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Record the detailed state of a network.
1671a45746efadd11bb7dfab026fb3c81a25fae74ca4Jeff Smith     * @param state the new {@code DetailedState}
16720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
1673be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
16747f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) {
16757f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            log("setDetailed state, old ="
16767f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    + mNetworkInfo.getDetailedState() + " and new state=" + state);
16777f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        }
16787f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
16790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        if (state != mNetworkInfo.getDetailedState()) {
1680da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            mNetworkInfo.setDetailedState(state, null, mWifiInfo.getSSID());
16810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
16820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
16830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1684be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    private DetailedState getNetworkDetailedState() {
1685be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return mNetworkInfo.getDetailedState();
1686be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff    }
1687be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
16881523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
16891523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff    private SupplicantState handleSupplicantStateChange(Message message) {
16901523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
16911523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        SupplicantState state = stateChangeResult.state;
16921523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // Supplicant state change
16931523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // [31-13] Reserved for future use
16941523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // [8 - 0] Supplicant state (as defined in SupplicantState.java)
16951523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // 50023 supplicant_state_changed (custom|1|5)
16961523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
16971523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        mWifiInfo.setSupplicantState(state);
16981523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        // Network id is only valid when we start connecting
16991523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        if (SupplicantState.isConnecting(state)) {
17001523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            mWifiInfo.setNetworkId(stateChangeResult.networkId);
17011523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        } else {
17021523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
17031523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        }
17041523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
1705b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng        mWifiInfo.setBSSID(stateChangeResult.BSSID);
1706b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff        mWifiInfo.setSSID(stateChangeResult.wifiSsid);
17071523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
17081523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        mSupplicantStateTracker.sendMessage(Message.obtain(message));
17091523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
17101523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff        return state;
17111523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff    }
17121523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff
17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /**
17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * using the interface, stopping DHCP & disabling interface
17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     */
17170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    private void handleNetworkDisconnect() {
17187f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("Stopping DHCP and clearing IP");
17190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /*
1721ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt         * stop DHCP
17220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff         */
172331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (mDhcpStateMachine != null) {
17244aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff            /* In case we were in middle of DHCP operation
17254aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff               restore back powermode */
17264aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff            handlePostDhcpSetup();
172731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
17280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
1730f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        try {
1731cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff            mNwService.clearInterfaceAddresses(mInterfaceName);
17327960d9f888e31602e17b8856c77a3826bf8c841erepo sync            mNwService.disableIpv6(mInterfaceName);
1733f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        } catch (Exception e) {
17347f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to clear addresses or disable ipv6" + e);
1735f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        }
1736f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff
17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Reset data structures */
1738124b44d89bc00b150c9478ccddfa83cac0f1df24Robert Greenwalt        mWifiInfo.setInetAddress(null);
17390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setBSSID(null);
17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mWifiInfo.setSSID(null);
17410a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
17429b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        mWifiInfo.setRssi(MIN_RSSI);
17439b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        mWifiInfo.setLinkSpeed(-1);
17449f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey        mWifiInfo.setMeteredHint(false);
17459b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff
17469b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        setNetworkDetailedState(DetailedState.DISCONNECTED);
1747fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
1748cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff
1749cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff        /* send event to CM & network change broadcast */
17509b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        sendNetworkStateChangeBroadcast(mLastBssid);
17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        /* Clear network properties */
175337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        mLinkProperties.clear();
17540c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff        /* Clear IP settings if the network used DHCP */
1755fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
1756fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiConfigStore.clearIpConfiguration(mLastNetworkId);
17570c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff        }
17580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
17590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        mLastBssid= null;
17600a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
176331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    void handlePreDhcpSetup() {
176431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (!mBluetoothConnectionActive) {
176531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            /*
176631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * There are problems setting the Wi-Fi driver's power
176731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * mode to active when bluetooth coexistence mode is
176831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * enabled or sense.
176931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * <p>
177031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * We set Wi-Fi to active mode when
177131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * obtaining an IP address because we've found
177231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * compatibility issues with some routers with low power
177331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * mode.
177431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * <p>
177531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * In order for this active power mode to properly be set,
177631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * we disable coexistence mode until we're done with
177731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * obtaining an IP address.  One exception is if we
177831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * are currently connected to a headset, since disabling
177931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             * coexistence would interrupt that connection.
178031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff             */
178131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            // Disable the coexistence mode
1782fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.setBluetoothCoexistenceMode(
1783fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
178431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
178531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
1786ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        /* Disable power save and suspend optimizations during DHCP */
17879da603c2da67207869d7fde18817165fa95d3592Irfan Sheriff        // Note: The order here is important for now. Brcm driver changes
17889da603c2da67207869d7fde18817165fa95d3592Irfan Sheriff        // power settings when we control suspend mode optimizations.
17899da603c2da67207869d7fde18817165fa95d3592Irfan Sheriff        // TODO: Remove this comment when the driver is fixed.
1790ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
17919da603c2da67207869d7fde18817165fa95d3592Irfan Sheriff        mWifiNative.setPowerSave(false);
179231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
179331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
179431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
179531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    void handlePostDhcpSetup() {
1796ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        /* Restore power save and suspend optimizations */
1797ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
17989da603c2da67207869d7fde18817165fa95d3592Irfan Sheriff        mWifiNative.setPowerSave(true);
179931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
180031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        // Set the coexistence mode back to its default value
1801fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setBluetoothCoexistenceMode(
1802fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
180331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
180431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
180531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private void handleSuccessfulIpConfiguration(DhcpInfoInternal dhcpInfoInternal) {
180631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        synchronized (mDhcpInfoInternal) {
180731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mDhcpInfoInternal = dhcpInfoInternal;
180831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
180931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        mLastSignalLevel = -1; // force update of signal strength
18101667a485d7cedcbd2cf0300e9a0dffdfaa93b0a2Irfan Sheriff        mReconnectCount = 0; //Reset IP failure tracking
1811fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
181231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        InetAddress addr = NetworkUtils.numericToInetAddress(dhcpInfoInternal.ipAddress);
181331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        mWifiInfo.setInetAddress(addr);
18149f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey        mWifiInfo.setMeteredHint(dhcpInfoInternal.hasMeteredHint());
181531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        if (getNetworkDetailedState() == DetailedState.CONNECTED) {
181631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            //DHCP renewal in connected state
181731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            LinkProperties linkProperties = dhcpInfoInternal.makeLinkProperties();
1818fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            linkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
181931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            linkProperties.setInterfaceName(mInterfaceName);
182031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            if (!linkProperties.equals(mLinkProperties)) {
18217f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                if (DBG) {
18227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    log("Link configuration changed for netId: " + mLastNetworkId
18237f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            + " old: " + mLinkProperties + "new: " + linkProperties);
18247f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                }
182531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                mLinkProperties = linkProperties;
182631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                sendLinkConfigurationChangedBroadcast();
182731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            }
182831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        } else {
182931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            configureLinkProperties();
183031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
183131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
183231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
183331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    private void handleFailedIpConfiguration() {
18347f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        loge("IP configuration failed");
183531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
183631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        mWifiInfo.setInetAddress(null);
18379f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey        mWifiInfo.setMeteredHint(false);
183831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        /**
183931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         * If we've exceeded the maximum number of retries for DHCP
184031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         * to a given network, disable the network
184131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         */
184279f5a0416fe76d5063b4d9995edd84a49b77995eMike Lockwood        int maxRetries = getMaxDhcpRetries();
184379f5a0416fe76d5063b4d9995edd84a49b77995eMike Lockwood        // maxRetries == 0 means keep trying forever
184479f5a0416fe76d5063b4d9995edd84a49b77995eMike Lockwood        if (maxRetries > 0 && ++mReconnectCount > maxRetries) {
18457f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed " +
184631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                    mReconnectCount + " times, Disabling " + mLastNetworkId);
1847fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiConfigStore.disableNetwork(mLastNetworkId,
18488dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy                    WifiConfiguration.DISABLED_DHCP_FAILURE);
184931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff            mReconnectCount = 0;
185031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        }
185131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
185231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff        /* DHCP times out after about 30 seconds, we do a
185331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         * disconnect and an immediate reconnect to try again
185431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff         */
1855fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.disconnect();
1856fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.reconnect();
1857ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff    }
185831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
18597dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    /* Current design is to not set the config on a running hostapd but instead
18607dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     * stop and start tethering when user changes config on a running access point
18617dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     *
18627dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     * TODO: Add control channel setup through hostapd that allows changing config
18637dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     * on a running daemon
18647dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff     */
18659575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff    private void startSoftApWithConfig(final WifiConfiguration config) {
18669575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        // start hostapd on a seperate thread
18679575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        new Thread(new Runnable() {
18689575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            public void run() {
18699575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                try {
187090542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff                    mNwService.startAccessPoint(config, mInterfaceName);
18719575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                } catch (Exception e) {
18729575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    loge("Exception in softap start " + e);
18739575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    try {
18749575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        mNwService.stopAccessPoint(mInterfaceName);
187590542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff                        mNwService.startAccessPoint(config, mInterfaceName);
18769575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    } catch (Exception e1) {
18779575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        loge("Exception in softap re-start " + e1);
18789575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        sendMessage(CMD_START_AP_FAILURE);
18799575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        return;
18809575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    }
18819575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                }
18829575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                if (DBG) log("Soft AP start successful");
18839575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                sendMessage(CMD_START_AP_SUCCESS);
1884ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff            }
18859575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff        }).start();
188631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    }
188731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
18880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    /********************************************************
18890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     * HSM states
18900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff     *******************************************************/
18910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
189264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DefaultState extends State {
18930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
18940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
18957f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
18960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
189755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
189855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
189955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
190055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
19017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("WifiP2pService connection failure, error=" + message.arg1);
190255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
190355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
190455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
19057f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("WifiP2pService channel lost, message.arg1 =" + message.arg1);
190655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    //TODO: Re-establish connection to state machine after a delay
190755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    //mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
190855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
190965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
191065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
191165eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
1912cdf8edeec2f5a063e94966449744c7f513578847Irfan Sheriff                    break;
19130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Synchronous call returns */
19140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
19150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
19160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
19174b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                case CMD_REMOVE_NETWORK:
19181406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                case CMD_SAVE_CONFIG:
1919d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, message.what, FAILURE);
19204b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville                    break;
1921e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                case CMD_GET_CONFIGURED_NETWORKS:
1922a3cbe75c93f96acdd3e0c4a5f6de5c50c2d6ea85Irfan Sheriff                    replyToMessage(message, message.what, (List<WifiConfiguration>) null);
1923e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    break;
19240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_RSSI_POLL:
19250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
192619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
1927fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                case CMD_ENABLE_BACKGROUND_SCAN:
1928fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mEnableBackgroundScan = (message.arg1 == 1);
1929fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    break;
1930262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
1931ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    if (message.arg1 == 1) {
1932ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, false);
1933ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    } else {
1934ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, true);
1935ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    }
1936262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                    break;
19370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Discard */
19380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
19390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
19400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
19410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
1942cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                case CMD_STOP_SUPPLICANT_FAILED:
19430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
19440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
1945e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                case CMD_DELAYED_STOP_DRIVER:
1946f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                case CMD_DRIVER_START_TIMED_OUT:
1947511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                case CMD_CAPTIVE_CHECK_COMPLETE:
19480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
19497dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_SUCCESS:
19507dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_FAILURE:
19510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
1952c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
1953c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
1954e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_START_SCAN:
1955e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_DISCONNECT:
1956e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_RECONNECT:
1957e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                case CMD_REASSOCIATE:
195855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
195955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
196055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
196155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
196255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
196355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
196455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
196555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.WPS_OVERLAP_EVENT:
19660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
19670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
19680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
19690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
1970ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
197136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
197219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
19738e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
197431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
197531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
19769575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                /* Handled by WifiApConfigStore */
19779575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_SET_AP_CONFIG:
19789575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_SET_AP_CONFIG_COMPLETED:
19799575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_REQUEST_AP_CONFIG:
19809575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case CMD_RESPONSE_AP_CONFIG:
198107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
198207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
1983027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                case CMD_NO_NETWORKS_PERIODIC_SCAN:
1984262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                    break;
19856bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                case DhcpStateMachine.CMD_ON_QUIT:
19866bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                    mDhcpStateMachine = null;
19876bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                    break;
1988ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                case CMD_SET_SUSPEND_OPT_ENABLED:
1989ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    if (message.arg1 == 1) {
1990ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        mSuspendWakeLock.release();
1991ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, true);
1992ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    } else {
1993ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, false);
1994ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    }
19950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
199655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.DRIVER_HUNG_EVENT:
199755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    setWifiEnabled(false);
199855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    setWifiEnabled(true);
199955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
2000d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.CONNECT_NETWORK:
2001d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
2002d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiManager.BUSY);
2003d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
2004d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.FORGET_NETWORK:
2005d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
2006d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiManager.BUSY);
2007d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
2008d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.SAVE_NETWORK:
2009d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
2010d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiManager.BUSY);
2011d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
2012d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.START_WPS:
2013d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, WifiManager.WPS_FAILED,
2014d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiManager.BUSY);
2015d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
201686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                case WifiManager.CANCEL_WPS:
201786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    replyToMessage(message, WifiManager.CANCEL_WPS_FAILED,
201886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            WifiManager.BUSY);
201986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    break;
2020d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.DISABLE_NETWORK:
2021d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
2022d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiManager.BUSY);
202302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
2024f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                case WifiManager.RSSI_PKTCNT_FETCH:
2025f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                    replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED,
2026f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                            WifiManager.BUSY);
20274c8982ad820007512e4e9cbb7f15925228d70761Irfan Sheriff                    break;
20283809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                case WifiP2pService.P2P_CONNECTION_CHANGED:
20293809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    NetworkInfo info = (NetworkInfo) message.obj;
20303809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    mP2pConnected.set(info.isConnected());
20313809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    break;
20329f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                case WifiP2pService.DISCONNECT_WIFI_REQUEST:
20339f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    mTemporarilyDisconnectWifi = (message.arg1 == 1);
20349f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    replyToMessage(message, WifiP2pService.DISCONNECT_WIFI_RESPONSE);
20359f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    break;
20360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
20377f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Error! unhandled message" + message);
20380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
20390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
20410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
204464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class InitialState extends State {
20450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        //TODO: could move logging into a common class
20470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20487f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
20490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [31-8] Reserved for future use
20500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // [7 - 0] HSM state change
20510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            // 50021 wifi_state_changed (custom|1|5)
20520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2054fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (mWifiNative.isDriverLoaded()) {
20550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverLoadedState);
20560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
20570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            else {
20580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mDriverUnloadedState);
20590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
206055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
206155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            //Connect to WifiP2pService
206255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
206355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
206455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20657960d9f888e31602e17b8856c77a3826bf8c841erepo sync            /* IPv6 is disabled at boot time and is controlled by framework
20667960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * to be enabled only as long as we are connected to an access point
20677960d9f888e31602e17b8856c77a3826bf8c841erepo sync             *
20687960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * This fixes issues, a few being:
20697960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * - IPv6 addresses and routes stick around after disconnection
20707960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * - When connected, the kernel is unaware and can fail to start IPv6 negotiation
20717960d9f888e31602e17b8856c77a3826bf8c841erepo sync             * - The kernel sometimes starts autoconfiguration when 802.1x is not complete
20727960d9f888e31602e17b8856c77a3826bf8c841erepo sync             */
20737960d9f888e31602e17b8856c77a3826bf8c841erepo sync            try {
20747960d9f888e31602e17b8856c77a3826bf8c841erepo sync                mNwService.disableIpv6(mInterfaceName);
20757960d9f888e31602e17b8856c77a3826bf8c841erepo sync            } catch (RemoteException re) {
20767f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to disable IPv6: " + re);
20777960d9f888e31602e17b8856c77a3826bf8c841erepo sync            } catch (IllegalStateException e) {
20787f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to disable IPv6: " + e);
20797960d9f888e31602e17b8856c77a3826bf8c841erepo sync            }
20800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
20810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
20820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
208364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverLoadingState extends State {
20840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
20850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
20867f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
20870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
20880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
20890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
20900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
20910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* TODO: add a timeout to fail when driver load is hung.
20920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             * Similarly for driver unload.
20930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff             */
20940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
20950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
20964f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
20970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    //enabling state
20980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    switch(message.arg1) {
20990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_STATE_ENABLING:
21000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiState(WIFI_STATE_ENABLING);
21010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
21020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        case WIFI_AP_STATE_ENABLING:
21030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            setWifiApState(WIFI_AP_STATE_ENABLING);
21040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            break;
21050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2107fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if(mWifiNative.loadDriver()) {
21087f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        if (DBG) log("Driver load successful");
21090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_SUCCESS);
21100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
21117f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to load driver!");
21120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
21130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_ENABLING:
21140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
21150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_ENABLING:
21170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
21180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
21190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
21200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_LOAD_DRIVER_FAILURE);
21210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
21224f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
21230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
21240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
21250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
21270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
21280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
21297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
21300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
21310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_SUCCESS:
21320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
21330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER_FAILURE:
21350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
21360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
21380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
21390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
21400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
21410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
21420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
21430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
21440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
21450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
21460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
2147ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
214836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
21490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
21500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
21510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
21520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
21540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
21550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
21560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
21570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
21580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
21590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
216064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverLoadedState 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_UNLOAD_DRIVER:
21710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadingState);
21720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
21730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
2174e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                    try {
2175e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                        mNwService.wifiFirmwareReload(mInterfaceName, "STA");
2176e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                    } catch (Exception e) {
21777f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to reload STA firmware " + e);
2178e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                        // continue
2179e36fcea8cdad6ed654079a34104795b2fbf5d2a2Irfan Sheriff                    }
21807329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                   try {
21817329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                       //A runtime crash can leave the interface up and
21827329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                       //this affects connectivity when supplicant starts up.
21837329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                       //Ensure interface is down before a supplicant start.
21847244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                        mNwService.setInterfaceDown(mInterfaceName);
21857329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                        //Set privacy extensions
21867329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff                        mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
21877244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                    } catch (RemoteException re) {
21887f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Unable to change interface settings: " + re);
21897244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                    } catch (IllegalStateException ie) {
21907f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Unable to change interface settings: " + ie);
21917244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff                    }
21927244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff
2193511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                    /* Stop a running supplicant after a runtime restart
2194511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                     * Avoids issues with drivers that do not handle interface down
2195511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                     * on a running supplicant properly.
2196511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                     */
2197511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                    if (DBG) log("Kill any running supplicant");
2198511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                    mWifiNative.killSupplicant(mP2pSupported);
2199511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff
22007d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if(mWifiNative.startSupplicant(mP2pSupported)) {
22017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        if (DBG) log("Supplicant start successful");
22020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mWifiMonitor.startMonitoring();
220396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mSupplicantStartingState);
22040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
22057f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to start supplicant!");
22060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
22070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
22107dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    transitionTo(mSoftApStartingState);
22110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
221964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverUnloadingState extends State {
22200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
22227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
22230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
22240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            final Message message = new Message();
22260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            message.copyFrom(getCurrentMessage());
22270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            new Thread(new Runnable() {
22280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                public void run() {
22297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log(getName() + message.toString() + "\n");
22304f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
2231fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if(mWifiNative.unloadDriver()) {
22327f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        if (DBG) log("Driver unload successful");
22330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
22340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
22360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
22370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
22380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(message.arg1);
22390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
22400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
22410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
22420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(message.arg1);
22430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
22440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
22450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
22467f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to unload driver!");
22470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
22480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        switch(message.arg1) {
22500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_DISABLED:
22510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_STATE_UNKNOWN:
22520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiState(WIFI_STATE_UNKNOWN);
22530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
22540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_DISABLED:
22550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            case WIFI_AP_STATE_FAILED:
22560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                setWifiApState(WIFI_AP_STATE_FAILED);
22570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                                break;
22580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
22590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
22604f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
22610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                }
22620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }).start();
22630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
22650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
22660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
22677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
22680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
22690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_SUCCESS:
22700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverUnloadedState);
22710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER_FAILURE:
22730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverFailedState);
22740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
22760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_UNLOAD_DRIVER:
22770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
22780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:
22790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
22800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
22810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
22820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
22830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
22840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
2285ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
228636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
22870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
22880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
22890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
22900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
22910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
22920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
22930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
22940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
22950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
22960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
22970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
229864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverUnloadedState extends State {
22990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
23020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23067f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
23070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
23080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_LOAD_DRIVER:
23097d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    transitionTo(mDriverLoadingState);
23100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
23110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
23120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
23130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
23140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
23150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
231864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverFailedState extends State {
23190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23217f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge(getName() + "\n");
23220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23267f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
23270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return NOT_HANDLED;
23280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
23300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
23310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
233264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SupplicantStartingState extends State {
23330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
23357f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
23360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
23370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
23384dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
23394dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        private void initializeWpsDetails() {
23404dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            String detail;
23414dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            detail = SystemProperties.get("ro.product.name", "");
23424dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setDeviceName(detail)) {
23434dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set device name " +  detail);
23444dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23454dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            detail = SystemProperties.get("ro.product.manufacturer", "");
23464dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setManufacturer(detail)) {
23474dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set manufacturer " + detail);
23484dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23494dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            detail = SystemProperties.get("ro.product.model", "");
23504dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setModelName(detail)) {
23514dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set model name " + detail);
23524dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23534dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            detail = SystemProperties.get("ro.product.model", "");
23544dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setModelNumber(detail)) {
23554dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set model number " + detail);
23564dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23574dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            detail = SystemProperties.get("ro.serialno", "");
23584dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setSerialNumber(detail)) {
23594dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set serial number " + detail);
23604dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23614dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setConfigMethods("physical_display virtual_push_button keypad")) {
23624dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set WPS config methods");
23634dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23644dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            if (!mWifiNative.setDeviceType(mPrimaryDeviceType)) {
23654dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                loge("Failed to set primary device type " + mPrimaryDeviceType);
23664dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff            }
23674dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        }
23684dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
23690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
23700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
23717f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
23720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
237355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
23747f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Supplicant connection established");
2375b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    setWifiState(WIFI_STATE_ENABLED);
237696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    mSupplicantRestartCount = 0;
2377b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    /* Reset the supplicant state to indicate the supplicant
2378b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                     * state is not known at this time */
2379b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
23800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Initialize data structures */
23810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastBssid = null;
23820a8bd60a8e064c8d310f0abd9503350633b05ecaIrfan Sheriff                    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
23830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mLastSignalLevel = -1;
23840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2385fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
2386fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiConfigStore.initialize();
23874dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff                    initializeWpsDetails();
23889e6222f4c126252c9950d072ab67d8b849d17643Irfan Sheriff
23890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(true);
23904f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    transitionTo(mDriverStartedState);
23910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
239255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
239396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
23947f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to setup control channel, restart supplicant");
2395511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                        mWifiNative.killSupplicant(mP2pSupported);
239696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
239796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
239896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    } else {
23997f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed " + mSupplicantRestartCount +
240096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                                " times to start supplicant, unload driver");
2401c4501f7710b8da1bc16f0670e4e7343db01f7146Ji-Hwan Lee                        mSupplicantRestartCount = 0;
240296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                        transitionTo(mDriverLoadedState);
2403b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
240496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    }
24050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
240668825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_LOAD_DRIVER:
240768825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_UNLOAD_DRIVER:
240868825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_START_SUPPLICANT:
240968825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_SUPPLICANT:
24100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
241168825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                case CMD_STOP_AP:
24120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
24130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
24140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
24150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
2416ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
241736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
24180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
24190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
24200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    deferMessage(message);
24210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
24230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
24240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
24250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
24260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
24280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
242964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SupplicantStartedState extends State {
24300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
24327f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
24330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
24340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            /* Initialize for connect mode operation at start */
24350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            mIsScanMode = false;
24366bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            /* Wifi is available as long as we have a connection to supplicant */
24376bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(true);
2438027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff
2439027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff            int defaultInterval = mContext.getResources().getInteger(
24403809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    R.integer.config_wifi_supplicant_scan_interval);
2441027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff
24426f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate            mSupplicantScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
24436f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate                    Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
2444027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    defaultInterval);
2445027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff
2446027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff            mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000);
24470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
24480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
24490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
24507f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
2451e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff            WifiConfiguration config;
24520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
24530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
245462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    if (mP2pSupported) {
245562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                        transitionTo(mWaitForP2pDisableState);
245662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    } else {
245762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                        transitionTo(mSupplicantStoppingState);
245862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    }
245968825ac32deb00991e18b5b40b455b68e9d78324Irfan Sheriff                    break;
246055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
24617f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Connection lost, restart supplicant");
2462511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                    mWifiNative.killSupplicant(mP2pSupported);
2463fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.closeSupplicantConnection();
24646bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff                    mNetworkInfo.setIsAvailable(false);
24650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
24660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendSupplicantConnectionChangedBroadcast(false);
2467b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
246862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    if (mP2pSupported) {
246962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                        transitionTo(mWaitForP2pDisableState);
247062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    } else {
247162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                        transitionTo(mDriverLoadedState);
247262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    }
247396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
24740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
247555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
2476fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    setScanResults(mWifiNative.scanResults());
24770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendScanResultsAvailableBroadcast();
2478fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mScanResultIsPending = false;
24790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_PING_SUPPLICANT:
2481fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    boolean ok = mWifiNative.ping();
2482d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
24830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ADD_OR_UPDATE_NETWORK:
24851406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff                    config = (WifiConfiguration) message.obj;
2486d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
2487fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                            mWifiConfigStore.addOrUpdateNetwork(config));
24880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REMOVE_NETWORK:
2490fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.removeNetwork(message.arg1);
2491d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
24920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_ENABLE_NETWORK:
2494fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
2495d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
24960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
24978e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                case CMD_ENABLE_ALL_NETWORKS:
24980f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                    long time =  android.os.SystemClock.elapsedRealtime();
24990f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                    if (time - mLastEnableAllNetworksTime > MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS) {
2500fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiConfigStore.enableAllNetworks();
25010f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                        mLastEnableAllNetworksTime = time;
25020f43161150903a008a5fd703078cdf446601160aIrfan Sheriff                    }
25038e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff                    break;
2504d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.DISABLE_NETWORK:
2505d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    if (mWifiConfigStore.disableNetwork(message.arg1,
2506d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiConfiguration.DISABLED_UNKNOWN_REASON) == true) {
2507d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.DISABLE_NETWORK_SUCCEEDED);
2508d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else {
2509d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
2510d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                WifiManager.ERROR);
2511d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
25120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_BLACKLIST_NETWORK:
2514fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.addToBlacklist((String)message.obj);
25150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_CLEAR_BLACKLIST:
2517fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.clearBlacklist();
25180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SAVE_CONFIG:
2520fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    ok = mWifiConfigStore.saveConfig();
2521d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
25221406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff
25230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    // Inform the backup manager about a data change
25240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    IBackupManager ibm = IBackupManager.Stub.asInterface(
25250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ServiceManager.getService(Context.BACKUP_SERVICE));
25260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (ibm != null) {
25270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        try {
25280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            ibm.dataChanged("com.android.providers.settings");
25290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        } catch (Exception e) {
25300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                            // Try again later
25310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        }
25320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
25330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2534a3cbe75c93f96acdd3e0c4a5f6de5c50c2d6ea85Irfan Sheriff                case CMD_GET_CONFIGURED_NETWORKS:
2535a3cbe75c93f96acdd3e0c4a5f6de5c50c2d6ea85Irfan Sheriff                    replyToMessage(message, message.what,
2536a3cbe75c93f96acdd3e0c4a5f6de5c50c2d6ea85Irfan Sheriff                            mWifiConfigStore.getConfiguredNetworks());
2537a3cbe75c93f96acdd3e0c4a5f6de5c50c2d6ea85Irfan Sheriff                    break;
25380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Cannot start soft AP while in client mode */
25390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
25407f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Failed to start soft AP with a running supplicant");
25410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_FAILED);
25420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
25430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
25440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    mIsScanMode = (message.arg1 == SCAN_ONLY_MODE);
25450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2546d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.SAVE_NETWORK:
2547e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    config = (WifiConfiguration) message.obj;
2548d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
2549d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
2550d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
2551d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else {
2552d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        loge("Failed to save network");
2553d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
2554d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                WifiManager.ERROR);
2555d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
2556e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
2557d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.FORGET_NETWORK:
2558d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    if (mWifiConfigStore.forgetNetwork(message.arg1)) {
2559d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.FORGET_NETWORK_SUCCEEDED);
2560d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else {
2561d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        loge("Failed to forget network");
2562d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
2563d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                WifiManager.ERROR);
2564d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
2565e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
25660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
25670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
25680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
25690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
25700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
25716bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff
25726bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        @Override
25736bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        public void exit() {
25746bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
25756bb7652b47b7c3068fa5e20a20263e651180c856Irfan Sheriff        }
25760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
25770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
257864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SupplicantStoppingState extends State {
257996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
258096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public void enter() {
25817f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
258296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
25834aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff
25844aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff            /* Send any reset commands to supplicant before shutting it down */
25854aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff            handleNetworkDisconnect();
25866bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff            if (mDhcpStateMachine != null) {
25876bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                mDhcpStateMachine.doQuit();
25886bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff            }
25894aa9bcd231d09eb62ea64799a2dfacf45a452049Irfan Sheriff
25907f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log("stopping supplicant");
2591fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (!mWifiNative.stopSupplicant()) {
25927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to stop supplicant");
25935cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            }
2594cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff
2595cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff            /* Send ourselves a delayed message to indicate failure after a wait time */
2596cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_STOP_SUPPLICANT_FAILED,
2597cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    ++mSupplicantStopFailureToken, 0), SUPPLICANT_RESTART_INTERVAL_MSECS);
2598cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff
25995cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            mNetworkInfo.setIsAvailable(false);
26005cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            setWifiState(WIFI_STATE_DISABLING);
26015cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            sendSupplicantConnectionChangedBroadcast(false);
26025cd8d4decea60fccb52614b15bd0ceaa9fecc384Irfan Sheriff            mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
260396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
260496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        @Override
260596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        public boolean processMessage(Message message) {
26067f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
260796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            switch(message.what) {
260855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
26097f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Supplicant connection received while stopping");
261096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
261155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
26127f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Supplicant connection lost");
2613cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    /* Socket connection can be lost when we do a graceful shutdown
2614cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                     * or when the driver is hung. Ensure supplicant is stopped here.
2615cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                     */
2616511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                    mWifiNative.killSupplicant(mP2pSupported);
2617fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.closeSupplicantConnection();
261896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    transitionTo(mDriverLoadedState);
261996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
2620cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                case CMD_STOP_SUPPLICANT_FAILED:
2621cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    if (message.arg1 == mSupplicantStopFailureToken) {
26227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Timed out on a supplicant stop, kill and proceed");
2623511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff                        mWifiNative.killSupplicant(mP2pSupported);
2624fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.closeSupplicantConnection();
2625cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                        transitionTo(mDriverLoadedState);
2626cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    }
2627cf54e4aafc0f4406567fc236b850e8dc507c7093Irfan Sheriff                    break;
262896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_LOAD_DRIVER:
262996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_UNLOAD_DRIVER:
263096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_SUPPLICANT:
263196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_SUPPLICANT:
263296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_AP:
263396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_AP:
263496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_DRIVER:
263596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_DRIVER:
263696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_MODE:
263796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_SCAN_TYPE:
263896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
263996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
264096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_START_PACKET_FILTERING:
264196071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
264296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    deferMessage(message);
264396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    break;
264496071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                default:
264596071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff                    return NOT_HANDLED;
264696071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            }
264796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff            return HANDLED;
264896071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff        }
264996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    }
265096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
265164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStartingState extends State {
2652f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff        private int mTries;
26530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
26557f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
26560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
2657f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff
2658f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff            mTries = 1;
2659f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff            /* Send ourselves a delayed message to start driver a second time */
2660f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_DRIVER_START_TIMED_OUT,
2661f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                        ++mDriverStartToken, 0), DRIVER_START_TIME_OUT_MSECS);
26620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
26630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
26640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
26657f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
26660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
266755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync               case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
26681523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    SupplicantState state = handleSupplicantStateChange(message);
26691523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    /* If suplicant is exiting out of INTERFACE_DISABLED state into
26701523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                     * a state that indicates driver has started, it is ready to
26711523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                     * receive driver commands
26721523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                     */
26731523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    if (SupplicantState.isDriverActive(state)) {
26741523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                        transitionTo(mDriverStartedState);
26751523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    }
26760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2677f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                case CMD_DRIVER_START_TIMED_OUT:
2678f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                    if (message.arg1 == mDriverStartToken) {
2679f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                        if (mTries >= 2) {
2680f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            loge("Failed to start driver after " + mTries);
2681f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            transitionTo(mDriverStoppedState);
2682f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                        } else {
2683f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            loge("Driver start failed, retrying");
2684f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            mWakeLock.acquire();
2685f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            mWifiNative.startDriver();
2686f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            mWakeLock.release();
2687f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff
2688f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            ++mTries;
2689f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            /* Send ourselves a delayed message to start driver again */
2690f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                            sendMessageDelayed(obtainMessage(CMD_DRIVER_START_TIMED_OUT,
2691f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                                        ++mDriverStartToken, 0), DRIVER_START_TIME_OUT_MSECS);
2692f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                        }
2693f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                    }
2694f91d4e7bdd6923b6f724b7956c0a87714e61fd13Irfan Sheriff                    break;
26950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands & connection events */
26960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
26970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
269855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
269955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
270055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
270155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.WPS_OVERLAP_EVENT:
27020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
2703ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
270436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
27050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
27060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
27070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
27080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
27090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
27100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
2711e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
27120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
27130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
27140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
27150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
27170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
27190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
272064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStartedState extends State {
27210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
27237f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
27240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
27250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
272603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = true;
2727e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff            mInDelayedStop = false;
272803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
27290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
273065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff            /**
273165eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
273265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * When this mode is on, some of the low-level scan parameters used by the
273365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             * driver are changed to reduce interference with bluetooth
273465eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff             */
2735fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
2736ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            /* set country code */
2737ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff            setCountryCode();
273836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            /* set frequency band of operation */
273936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff            setFrequencyBand();
27403a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            /* initialize network state */
27413a65de795d5bf8f575a38a2ad83d5e3e234ae4a6Irfan Sheriff            setNetworkDetailedState(DetailedState.DISCONNECTED);
27420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
2743b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            /* Remove any filtering on Multicast v6 at start */
2744fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.stopFilteringMulticastV6Packets();
2745b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
2746b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            /* Reset Multicast v4 filtering state */
2747b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            if (mFilteringMulticastV4Packets.get()) {
2748fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.startFilteringMulticastV4Packets();
2749b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            } else {
2750fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.stopFilteringMulticastV4Packets();
2751b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff            }
2752b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
27530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            if (mIsScanMode) {
2754fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
2755fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.disconnect();
27560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                transitionTo(mScanModeState);
27570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            } else {
2758fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.setScanResultHandling(CONNECT_MODE);
2759fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.reconnect();
2760576db76106e43129d3df256524c343d0768b2a39Irfan Sheriff                // Status pulls in the current supplicant state and network connection state
2761576db76106e43129d3df256524c343d0768b2a39Irfan Sheriff                // events over the monitor connection. This helps framework sync up with
2762576db76106e43129d3df256524c343d0768b2a39Irfan Sheriff                // current supplicant state
2763fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.status();
2764090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff                transitionTo(mDisconnectedState);
27650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
27667d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
27671c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            // We may have missed screen update at boot
27681c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            if (mScreenBroadcastReceived.get() == false) {
27691c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                PowerManager powerManager = (PowerManager)mContext.getSystemService(
27701c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                        Context.POWER_SERVICE);
27711c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                handleScreenStateChanged(powerManager.isScreenOn());
27721c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            } else {
27731c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                // Set the right suspend mode settings
27741c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                mWifiNative.setSuspendOptimizations(mSuspendOptNeedsDisabled == 0
27751c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff                        && mUserWantsSuspendOpt.get());
27761c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff            }
27779da603c2da67207869d7fde18817165fa95d3592Irfan Sheriff            mWifiNative.setPowerSave(true);
27781c045ec2b79c33eb29a24bff11567831ea90398bIrfan Sheriff
27797d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
27800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
27810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
27820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
27837f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
27840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
27857d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case CMD_SET_SCAN_TYPE:
27861f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    mSetScanActive = (message.arg1 == SCAN_ACTIVE);
2787fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setScanMode(mSetScanActive);
27880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
278919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
27901f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    boolean forceActive = (message.arg1 == SCAN_ACTIVE);
27911f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    if (forceActive && !mSetScanActive) {
2792fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanMode(forceActive);
27931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    }
2794fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.scan();
27951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    if (forceActive && !mSetScanActive) {
2796fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanMode(mSetScanActive);
27971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                    }
2798fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mScanResultIsPending = true;
279919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
2800ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
2801ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    String country = (String) message.obj;
28027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("set country code " + country);
2803fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (!mWifiNative.setCountryCode(country.toUpperCase())) {
28047f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to set country code " + country);
2805ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                    }
28060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
280736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
280836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    int band =  message.arg1;
28097f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("set frequency band " + band);
2810fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.setBand(band)) {
281136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                        mFrequencyBand.set(band);
2812cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        //Fetch the latest scan results when frequency band is set
2813cf34f47eddedbeab4ace8150d026e81a5d9485aeIrfan Sheriff                        startScan(true);
281436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    } else {
28157f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failed to set frequency band " + band);
281636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    }
281736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                    break;
281865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
281965eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    mBluetoothConnectionActive = (message.arg1 !=
282065eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                            BluetoothAdapter.STATE_DISCONNECTED);
2821fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
282265eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff                    break;
28230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
28244494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    int mode = message.arg1;
28254494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff
28264494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    /* Already doing a delayed stop && not in ecm state */
28274494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    if (mInDelayedStop && mode != IN_ECM_STATE) {
2828e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        if (DBG) log("Already in delayed stop");
2829e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        break;
2830e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    }
2831e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    mInDelayedStop = true;
2832e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    mDelayedStopCounter++;
2833e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (DBG) log("Delayed stop message " + mDelayedStopCounter);
28344494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff
28354494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    if (mode == IN_ECM_STATE) {
28364494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        /* send a shut down immediately */
28374494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        sendMessage(obtainMessage(CMD_DELAYED_STOP_DRIVER, mDelayedStopCounter, 0));
28384494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    } else {
28394494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                        /* send regular delayed shut down */
2840f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                        Intent driverStopIntent = new Intent(ACTION_DELAYED_DRIVER_STOP, null);
2841f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                        driverStopIntent.putExtra(DELAYED_STOP_COUNTER, mDelayedStopCounter);
2842f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                        mDriverStopIntent = PendingIntent.getBroadcast(mContext,
2843f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                                DRIVER_STOP_REQUEST, driverStopIntent,
2844f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                                PendingIntent.FLAG_UPDATE_CURRENT);
2845f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer
2846f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                        mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
2847f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                                + mDriverStopDelayMs, mDriverStopIntent);
28484494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff                    }
2849e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    break;
2850e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                case CMD_START_DRIVER:
2851e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (mInDelayedStop) {
2852e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        mInDelayedStop = false;
2853e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        mDelayedStopCounter++;
2854f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                        mAlarmManager.cancel(mDriverStopIntent);
2855e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        if (DBG) log("Delayed stop ignored due to start");
2856e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    }
2857e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    break;
2858e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                case CMD_DELAYED_STOP_DRIVER:
2859f48fb85a8c4f72ec08b98f15ec3d9c70c247de7dVishal Mahaveer                    if (DBG) log("delayed stop " + message.arg1 + " " + mDelayedStopCounter);
2860e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (message.arg1 != mDelayedStopCounter) break;
2861e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    if (getCurrentState() != mDisconnectedState) {
2862fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.disconnect();
2863e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                        handleNetworkDisconnect();
2864e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff                    }
28654f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.acquire();
2866fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.stopDriver();
28674f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    mWakeLock.release();
286862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    if (mP2pSupported) {
286962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                        transitionTo(mWaitForP2pDisableState);
287062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    } else {
287162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                        transitionTo(mDriverStoppingState);
287262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    }
28730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
2875b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    if (message.arg1 == MULTICAST_V6) {
2876fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.startFilteringMulticastV6Packets();
2877b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else if (message.arg1 == MULTICAST_V4) {
2878fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.startFilteringMulticastV4Packets();
2879b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else {
28807f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Illegal arugments to CMD_START_PACKET_FILTERING");
2881b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    }
28820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
28830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
2884b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    if (message.arg1 == MULTICAST_V6) {
2885fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.stopFilteringMulticastV6Packets();
2886b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else if (message.arg1 == MULTICAST_V4) {
2887fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.stopFilteringMulticastV4Packets();
2888b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    } else {
28897f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
2890b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff                    }
28910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
2892ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                case CMD_SET_SUSPEND_OPT_ENABLED:
2893ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    if (message.arg1 == 1) {
2894ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
2895ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        mSuspendWakeLock.release();
2896ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    } else {
2897ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
2898262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                    }
2899262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                    break;
2900262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                case CMD_SET_HIGH_PERF_MODE:
2901ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    if (message.arg1 == 1) {
2902ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, false);
2903ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                    } else {
2904ec7d1380d30088bdc5bf40def653749524f2b6c6Irfan Sheriff                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
2905262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                    }
2906262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff                    break;
29070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
29080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
29090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
29100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
29110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
29120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
29130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void exit() {
29147f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
291503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            mIsRunning = false;
291603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn            updateBatteryWorkSource(null);
291706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev            mScanResults = new ArrayList<ScanResult>();
291862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        }
291962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    }
29207d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
292162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff    class WaitForP2pDisableState extends State {
292262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        private State mTransitionToState;
292362fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        @Override
292462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        public void enter() {
292562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            if (DBG) log(getName() + "\n");
292662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
292762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            switch (getCurrentMessage().what) {
292862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
292962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    mTransitionToState = mDriverLoadedState;
293062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    break;
293162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_DELAYED_STOP_DRIVER:
293262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    mTransitionToState = mDriverStoppingState;
293362fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    break;
293462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_STOP_SUPPLICANT:
293562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    mTransitionToState = mSupplicantStoppingState;
293662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    break;
293762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                default:
293862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    mTransitionToState = mDriverStoppingState;
293962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    break;
294062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            }
294162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
294262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        }
294362fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        @Override
294462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff        public boolean processMessage(Message message) {
294562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
294662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            switch(message.what) {
294762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P_RSP:
294862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    transitionTo(mTransitionToState);
294962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    break;
295062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                /* Defer wifi start/shut and driver commands */
2951e6464af00033370730e530e4d5402cd049768014Irfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
295262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_LOAD_DRIVER:
295362fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_UNLOAD_DRIVER:
295462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_START_SUPPLICANT:
295562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_STOP_SUPPLICANT:
295662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_START_AP:
295762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_STOP_AP:
295862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_START_DRIVER:
295962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_STOP_DRIVER:
296062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_SET_SCAN_MODE:
296162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_SET_SCAN_TYPE:
296262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
296362fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
296462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_START_PACKET_FILTERING:
296562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
296662fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_START_SCAN:
296762fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_DISCONNECT:
296862fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_REASSOCIATE:
296962fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                case CMD_RECONNECT:
297062fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    deferMessage(message);
297162fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    break;
297262fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                default:
297362fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff                    return NOT_HANDLED;
297462fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            }
297562fa6de135269a7da135bb89b1eb047a4f11d343Irfan Sheriff            return HANDLED;
29760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
29770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
29780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
297964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStoppingState extends State {
29800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
29810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
29827f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
29830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
29840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
29850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
29860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
29877f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
29880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
298955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
29901523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    SupplicantState state = handleSupplicantStateChange(message);
29911523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    if (state == SupplicantState.INTERFACE_DISABLED) {
29921523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                        transitionTo(mDriverStoppedState);
29931523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff                    }
29940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
29950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Queue driver commands */
29960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_DRIVER:
29970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_DRIVER:
29980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_TYPE:
2999ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff                case CMD_SET_COUNTRY_CODE:
300036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff                case CMD_SET_FREQUENCY_BAND:
30010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_PACKET_FILTERING:
30020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_PACKET_FILTERING:
30030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SCAN:
30040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
30050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
30060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
3007e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff                    deferMessage(message);
30080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
30090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
30100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
30110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
30120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
30130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
30150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
301664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DriverStoppedState extends State {
30170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
30197f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
30200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
30210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
30247f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
30254f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            switch (message.what) {
302656379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
302756379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
302856379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    SupplicantState state = stateChangeResult.state;
302956379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // A WEXT bug means that we can be back to driver started state
303056379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    // unexpectedly
303156379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    if (SupplicantState.isDriverActive(state)) {
303256379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        transitionTo(mDriverStartedState);
303356379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    }
303456379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    break;
30353ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                case CMD_START_DRIVER:
30363ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                    mWakeLock.acquire();
3037fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.startDriver();
30383ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                    mWakeLock.release();
30393ac127ff477fa291f83f0906ce3c0981a9597acaIrfan Sheriff                    transitionTo(mDriverStartingState);
30404f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    break;
30414f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                default:
30424f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff                    return NOT_HANDLED;
30434f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            }
30444f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff            return HANDLED;
30450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
30470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
304864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class ScanModeState extends State {
30490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
30517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
30520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
30530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
30567f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
30570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
30580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
30590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
30600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        /* Ignore */
30610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        return HANDLED;
30620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } else {
3063fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanResultHandling(message.arg1);
3064fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.reconnect();
30650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = false;
30660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mDisconnectedState);
30670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
30680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
30690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
30700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
30710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
30720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
307355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
307455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
307555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
30760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
30770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
30780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
30790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
30800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
30810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
30830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
308464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class ConnectModeState extends State {
30850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
30877f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
30880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
30890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
30900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
30910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
30927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
30930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            StateChangeResult stateChangeResult;
30940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
309555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
309655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT);
30970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
309855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
309956379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    SupplicantState state = handleSupplicantStateChange(message);
3100b678320cfa16424e01494fb0ee97bc98c0988bf1Irfan Sheriff                    // A driver/firmware hang can now put the interface in a down state.
3101b678320cfa16424e01494fb0ee97bc98c0988bf1Irfan Sheriff                    // We detect the interface going down and recover from it
310256379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    if (!SupplicantState.isDriverActive(state)) {
310356379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
310456379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                            handleNetworkDisconnect();
310556379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        }
3106b678320cfa16424e01494fb0ee97bc98c0988bf1Irfan Sheriff                        log("Detected an interface down, restart driver");
310756379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                        transitionTo(mDriverStoppedState);
3108b678320cfa16424e01494fb0ee97bc98c0988bf1Irfan Sheriff                        sendMessage(CMD_START_DRIVER);
3109a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        break;
3110a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    }
3111a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff
3112a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
3113a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // when authentication times out after a successful connection,
3114a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // we can figure this from the supplicant state. If supplicant
3115a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // state is DISCONNECTED, but the mNetworkInfo says we are not
3116a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    // disconnected, we need to handle a disconnection
3117a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                    if (state == SupplicantState.DISCONNECTED &&
3118a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                            mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
3119a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        if (DBG) log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
3120a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        handleNetworkDisconnect();
3121a2a1078576187f1192e339c927478205a8bc937fIrfan Sheriff                        transitionTo(mDisconnectedState);
312256379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    }
312356379d23971baafa0e6987fe2b18d7a1ffea439dIrfan Sheriff                    break;
31249f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                case WifiP2pService.DISCONNECT_WIFI_REQUEST:
31259f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    if (message.arg1 == 1) {
31269f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        mWifiNative.disconnect();
31279f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        mTemporarilyDisconnectWifi = true;
31289f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    } else {
31299f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        mWifiNative.reconnect();
31309f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        mTemporarilyDisconnectWifi = false;
31319f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    }
31329f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    break;
31330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Do a redundant disconnect without transition */
31340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
3135fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.disconnect();
31360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_RECONNECT:
3138fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.reconnect();
31390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
31400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_REASSOCIATE:
3141fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.reassociate();
31420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
3143d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.CONNECT_NETWORK:
3144b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                    /* The connect message can contain a network id passed as arg1 on message or
3145b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                     * or a config passed as obj on message.
3146b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                     * For a new network, a config is passed to create and connect.
3147b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                     * For an existing network, a network id is passed
3148b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                     */
3149e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    int netId = message.arg1;
3150e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
315104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
3152b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                    /* Save the network config */
3153e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    if (config != null) {
3154b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
3155b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        netId = result.getNetworkId();
3156e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    }
3157e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff
3158b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                    if (mWifiConfigStore.selectNetwork(netId) &&
3159b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                            mWifiNative.reconnect()) {
3160b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        /* The state tracker handles enabling networks upon completion/failure */
3161b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        mSupplicantStateTracker.sendMessage(WifiManager.CONNECT_NETWORK);
3162d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
3163b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        /* Expect a disconnection from the old connection */
3164b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        transitionTo(mDisconnectingState);
3165d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else {
3166b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        loge("Failed to connect config: " + config + " netId: " + netId);
3167d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
3168d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                WifiManager.ERROR);
3169b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                        break;
3170d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
3171e04653cbd0e8303eba92088344312b827e6b0babIrfan Sheriff                    break;
3172d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.START_WPS:
3173d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    WpsInfo wpsInfo = (WpsInfo) message.obj;
3174d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    WpsResult result;
3175d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    switch (wpsInfo.setup) {
3176d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        case WpsInfo.PBC:
3177d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            result = mWifiConfigStore.startWpsPbc(wpsInfo);
3178d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            break;
3179d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        case WpsInfo.KEYPAD:
3180d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            result = mWifiConfigStore.startWpsWithPinFromAccessPoint(wpsInfo);
3181d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            break;
3182d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        case WpsInfo.DISPLAY:
3183d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            result = mWifiConfigStore.startWpsWithPinFromDevice(wpsInfo);
3184d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            break;
3185d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        default:
3186d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            result = new WpsResult(Status.FAILURE);
3187d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            Log.e(TAG, "Invalid setup for WPS");
3188d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            break;
3189d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
3190d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    if (result.status == Status.SUCCESS) {
3191d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.START_WPS_SUCCEEDED, result);
3192d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        transitionTo(mWpsRunningState);
3193d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else {
3194d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        Log.e(TAG, "Failed to start WPS with config " + wpsInfo.toString());
3195d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.ERROR);
3196d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
3197f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff                    break;
319855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
31990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Set the scan setting back to "connect" mode */
3200fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setScanResultHandling(CONNECT_MODE);
32010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Handle scan results */
32020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
320355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
32047f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Network connection established");
3205b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastNetworkId = message.arg1;
3206b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mLastBssid = (String) message.obj;
32070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3208b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setBSSID(mLastBssid);
3209b45e726bf5df9650e8a67a7c05bf2f41f414c07dIrfan Sheriff                    mWifiInfo.setNetworkId(mLastNetworkId);
32100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* send event to CM & network change broadcast */
3211be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
32120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
321307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    transitionTo(mObtainingIpState);
32140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
321555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
32167f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Network connection lost");
32170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    handleNetworkDisconnect();
32180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectedState);
32190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
32210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
32220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
32230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
32240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
32250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
32260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
322707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    class L2ConnectedState extends State {
32280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
32307f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
32310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
323219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            mRssiPollToken++;
323319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            if (mEnableRssiPolling) {
323407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                sendMessage(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0));
323519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff            }
32360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
323707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
32380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
32390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
32407f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
32410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
324231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
324331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handlePreDhcpSetup();
324431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
324531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  break;
324631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
324731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  handlePostDhcpSetup();
324831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
324907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                      if (DBG) log("DHCP successful");
325031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
325107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                      transitionTo(mVerifyingLinkState);
325231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
325307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                      if (DBG) log("DHCP failed");
325431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      handleFailedIpConfiguration();
325531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                      transitionTo(mDisconnectingState);
325631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  }
325731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff                  break;
32580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_DISCONNECT:
3259fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.disconnect();
32600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDisconnectingState);
32610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
32629f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                case WifiP2pService.DISCONNECT_WIFI_REQUEST:
32639f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    if (message.arg1 == 1) {
32649f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        mWifiNative.disconnect();
32659f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        mTemporarilyDisconnectWifi = true;
32669f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                        transitionTo(mDisconnectingState);
32679f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    }
32689f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    break;
32690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
32700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
32710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        sendMessage(CMD_DISCONNECT);
32720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
32730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
32740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
327519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_START_SCAN:
327619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    /* When the network is connected, re-scanning can trigger
327719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * a reconnection. Put it in scan-only mode during scan.
327819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * When scan results are received, the mode is switched
327919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     * back to CONNECT_MODE.
328019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                     */
3281fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
3282fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Have the parent state handle the rest */
3283fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    return NOT_HANDLED;
3284a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    /* Ignore connection to same network */
3285d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.CONNECT_NETWORK:
3286a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    int netId = message.arg1;
3287a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    if (mWifiInfo.getNetworkId() == netId) {
3288a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                        break;
3289a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    }
3290a2d5fbf569cb81d3d89bf61393c9ebd2c8a54aedIrfan Sheriff                    return NOT_HANDLED;
3291d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.SAVE_NETWORK:
3292be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
3293fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
3294be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
3295be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasIpChanged()) {
32967f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            log("Reconfiguring IP on connection");
329707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                            transitionTo(mObtainingIpState);
3298be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
3299be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        if (result.hasProxyChanged()) {
33007f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            log("Reconfiguring proxy on connection");
3301be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            configureLinkProperties();
3302be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                            sendLinkConfigurationChangedBroadcast();
3303be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                        }
3304be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    }
3305d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff
3306d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
3307d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
3308d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else {
3309d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        loge("Failed to save network");
3310d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
3311d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                                WifiManager.ERROR);
3312d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    }
3313be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff                    break;
33140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore */
331555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_CONNECTION_EVENT:
33160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
331719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_RSSI_POLL:
331819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (message.arg1 == mRssiPollToken) {
331919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Get Info and continue polling
332019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
332107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
332219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
332319d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    } else {
332419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // Polling has completed
332519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
332619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
332719d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                case CMD_ENABLE_RSSI_POLL:
332819d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mEnableRssiPolling = (message.arg1 == 1);
332919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    mRssiPollToken++;
333019d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    if (mEnableRssiPolling) {
333119d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        // first poll
333219d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                        fetchRssiAndLinkSpeedNative();
333307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
333419d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
333519d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    }
333619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
3337f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                case WifiManager.RSSI_PKTCNT_FETCH:
3338f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                    RssiPacketCountInfo info = new RssiPacketCountInfo();
33394c8982ad820007512e4e9cbb7f15925228d70761Irfan Sheriff                    fetchRssiAndLinkSpeedNative();
3340f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                    info.rssi = mWifiInfo.getRssi();
3341f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                    fetchPktcntNative(info);
3342f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng                    replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED, info);
33434c8982ad820007512e4e9cbb7f15925228d70761Irfan Sheriff                    break;
33440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
33450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
33460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
334707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
33480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
33490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
335007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
33519b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        @Override
33529b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        public void exit() {
33539b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            /* If a scan result is pending in connected state, the supplicant
33549b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff             * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit
33559b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff             */
33569b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            if (mScanResultIsPending) {
3357fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.setScanResultHandling(CONNECT_MODE);
33589b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff            }
33599b3710b253db932d560f2f08d62b6eb2d37e3c67Irfan Sheriff        }
33600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
33610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
336207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    class ObtainingIpState extends State {
336307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        @Override
336407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        public void enter() {
336507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            if (DBG) log(getName() + "\n");
336607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
336707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
336807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
336907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                //start DHCP
33706bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                if (mDhcpStateMachine == null) {
33716bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                    mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
33726bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                            mContext, WifiStateMachine.this, mInterfaceName);
33736bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff
33746bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff                }
337507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                mDhcpStateMachine.registerForPreDhcpNotification();
337607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
337707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            } else {
337807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                DhcpInfoInternal dhcpInfoInternal = mWifiConfigStore.getIpConfiguration(
337907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        mLastNetworkId);
338007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                InterfaceConfiguration ifcg = new InterfaceConfiguration();
338107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                ifcg.setLinkAddress(dhcpInfoInternal.makeLinkAddress());
338207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                ifcg.setInterfaceUp();
338307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                try {
338407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    mNwService.setInterfaceConfig(mInterfaceName, ifcg);
338507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    if (DBG) log("Static IP configuration succeeded");
338607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
338707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                } catch (RemoteException re) {
338807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    loge("Static IP configuration failed: " + re);
338907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    sendMessage(CMD_STATIC_IP_FAILURE);
339007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                } catch (IllegalStateException e) {
339107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    loge("Static IP configuration failed: " + e);
339207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    sendMessage(CMD_STATIC_IP_FAILURE);
339307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                }
339407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            }
339507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        }
339607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff      @Override
339707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff      public boolean processMessage(Message message) {
339807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff          if (DBG) log(getName() + message.toString() + "\n");
339907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff          switch(message.what) {
340007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            case CMD_STATIC_IP_SUCCESS:
340107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
340207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  transitionTo(mVerifyingLinkState);
340307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  break;
340407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff              case CMD_STATIC_IP_FAILURE:
340507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  handleFailedIpConfiguration();
340607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  transitionTo(mDisconnectingState);
340707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  break;
3408d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff             case WifiManager.SAVE_NETWORK:
340907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  deferMessage(message);
341007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  break;
341107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  /* Defer any power mode changes since we must keep active power mode at DHCP */
341207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff              case CMD_SET_HIGH_PERF_MODE:
341307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  deferMessage(message);
341407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  break;
341507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff              default:
341607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                  return NOT_HANDLED;
341707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff          }
341807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff          return HANDLED;
341907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff      }
342007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    }
342107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
342207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    class VerifyingLinkState extends State {
342307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        @Override
342407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        public void enter() {
342507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            if (DBG) log(getName() + "\n");
342607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
342707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            setNetworkDetailedState(DetailedState.VERIFYING_POOR_LINK);
342807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.VERIFYING_POOR_LINK);
342907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            sendNetworkStateChangeBroadcast(mLastBssid);
343007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        }
343107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        @Override
343207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        public boolean processMessage(Message message) {
343307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            switch (message.what) {
343407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
343507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    //stay here
343607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    break;
343707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
3438da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    transitionTo(mCaptivePortalCheckState);
3439da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    break;
3440da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                default:
3441da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    return NOT_HANDLED;
3442da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            }
3443da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            return HANDLED;
3444da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        }
3445da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    }
3446da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
3447da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    class CaptivePortalCheckState extends State {
3448da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        @Override
3449da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        public void enter() {
3450da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK);
3451da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CAPTIVE_PORTAL_CHECK);
3452da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            sendNetworkStateChangeBroadcast(mLastBssid);
3453da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        }
3454da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        @Override
3455da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        public boolean processMessage(Message message) {
3456da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            switch (message.what) {
3457da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                case CMD_CAPTIVE_CHECK_COMPLETE:
345807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    try {
345907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        mNwService.enableIpv6(mInterfaceName);
346007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    } catch (RemoteException re) {
346107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        loge("Failed to enable IPv6: " + re);
346207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    } catch (IllegalStateException e) {
346307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        loge("Failed to enable IPv6: " + e);
346407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    }
346507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    setNetworkDetailedState(DetailedState.CONNECTED);
346607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
346707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
346807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    transitionTo(mConnectedState);
346907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    break;
347007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                default:
347107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    return NOT_HANDLED;
347207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            }
347307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            return HANDLED;
347407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        }
347507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    }
347607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
347707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    class ConnectedState extends State {
347807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        @Override
347907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        public void enter() {
348007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            if (DBG) log(getName() + "\n");
348107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
348207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff       }
348307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        @Override
348407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        public boolean processMessage(Message message) {
348507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
348607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            switch (message.what) {
348707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff               case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
348807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    if (DBG) log("Watchdog reports poor link");
348907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    try {
349007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        mNwService.disableIpv6(mInterfaceName);
349107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    } catch (RemoteException re) {
349207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        loge("Failed to disable IPv6: " + re);
349307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    } catch (IllegalStateException e) {
349407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                        loge("Failed to disable IPv6: " + e);
349507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    }
349607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    /* Report a disconnect */
349707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    setNetworkDetailedState(DetailedState.DISCONNECTED);
349807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
349907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    sendNetworkStateChangeBroadcast(mLastBssid);
350007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
350107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    transitionTo(mVerifyingLinkState);
350207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    break;
350307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                default:
350407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff                    return NOT_HANDLED;
350507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            }
350607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            return HANDLED;
350707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        }
350807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        @Override
350907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        public void exit() {
351007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            /* Request a CS wakelock during transition to mobile */
351107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            checkAndSetConnectivityInstance();
351207573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff            mCm.requestNetworkTransitionWakelock(TAG);
351307573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff        }
351407573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff    }
351507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff
351664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DisconnectingState extends State {
35170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
35180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
35197f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
35200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
35210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
35220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
35230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
35247f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
35250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
35260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
35270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
35280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        deferMessage(message);
35290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
35300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
353155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
35322d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                    /* If we get a SUPPLICANT_STATE_CHANGE_EVENT before NETWORK_DISCONNECTION_EVENT
35332d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                     * we have missed the network disconnection, transition to mDisconnectedState
35342d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                     * and handle the rest of the events there
35352d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                     */
353619d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    deferMessage(message);
35372d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                    handleNetworkDisconnect();
35382d57d860c2ddf792f4afd6101c19a6d0cf01547cIrfan Sheriff                    transitionTo(mDisconnectedState);
353919d245b792e1d941fbba9b04ae20ce9d6e6e18f8Irfan Sheriff                    break;
35400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
35410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
35420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
35430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
35440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
35450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
35460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
354764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class DisconnectedState extends State {
3548fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff        private boolean mAlarmEnabled = false;
35492b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        /* This is set from the overlay config file or from a secure setting.
35502b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff         * A value of 0 disables scanning in the framework.
35512b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff         */
35522b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff        private long mFrameworkScanIntervalMs;
3553f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff
3554f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff        private void setScanAlarm(boolean enabled) {
3555f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            if (enabled == mAlarmEnabled) return;
3556f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            if (enabled) {
35572b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                if (mFrameworkScanIntervalMs > 0) {
35582b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
35592b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                            System.currentTimeMillis() + mFrameworkScanIntervalMs,
35602b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                            mFrameworkScanIntervalMs,
35612b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                            mScanIntent);
35622b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mAlarmEnabled = true;
35632b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                }
3564f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            } else {
3565f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                mAlarmManager.cancel(mScanIntent);
3566f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                mAlarmEnabled = false;
3567f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            }
3568f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff        }
3569f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff
35700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
35710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
35727f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
35730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
3574090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
35759f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            // We dont scan frequently if this is a temporary disconnect
35769f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            // due to p2p
35779f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (mTemporarilyDisconnectWifi) {
35789f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mWifiP2pChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_RESPONSE);
35799f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                return;
35809f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            }
35819f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff
35826f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate            mFrameworkScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
35836f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate                    Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
35842b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff                    mDefaultFrameworkScanIntervalMs);
3585fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            /*
3586fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff             * We initiate background scanning if it is enabled, otherwise we
3587fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff             * initiate an infrequent scan that wakes up the device to ensure
3588fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff             * a user connects to an access point on the move
3589090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff             */
3590fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            if (mEnableBackgroundScan) {
3591fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                /* If a regular scan result is pending, do not initiate background
3592fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * scan until the scan results are returned. This is needed because
3593fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * initiating a background scan will cancel the regular scan and
3594fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * scan results will not be returned until background scanning is
3595fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 * cleared
3596fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                 */
3597fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                if (!mScanResultIsPending) {
3598fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    mWifiNative.enableBackgroundScan(true);
3599fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                }
3600fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            } else {
3601f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                setScanAlarm(true);
3602fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            }
3603027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff
3604027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff            /**
3605027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff             * If we have no networks saved, the supplicant stops doing the periodic scan.
3606027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff             * The scans are useful to notify the user of the presence of an open network.
3607027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff             * Note that these are not wake up scans.
3608027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff             */
36093809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff            if (!mP2pConnected.get() && mWifiConfigStore.getConfiguredNetworks().size() == 0) {
3610027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
3611027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                            ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
3612027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff            }
36130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
36140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
36150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
36167f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
3617027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff            boolean ret = HANDLED;
36180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch (message.what) {
3619027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                case CMD_NO_NETWORKS_PERIODIC_SCAN:
36203809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    if (mP2pConnected.get()) break;
3621027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    if (message.arg1 == mPeriodicScanToken &&
3622027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                            mWifiConfigStore.getConfiguredNetworks().size() == 0) {
3623027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                        sendMessage(CMD_START_SCAN);
3624027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                        sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
3625027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                                    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
3626027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    }
3627027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    break;
3628027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                case WifiManager.FORGET_NETWORK:
3629027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                case CMD_REMOVE_NETWORK:
3630027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    // Set up a delayed message here. After the forget/remove is handled
3631027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    // the handled delayed message will determine if there is a need to
3632027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    // scan and continue
3633027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
3634027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                                ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
3635027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    ret = NOT_HANDLED;
3636027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    break;
36370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_SET_SCAN_MODE:
36380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    if (message.arg1 == SCAN_ONLY_MODE) {
3639fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.setScanResultHandling(message.arg1);
36400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        //Supplicant disconnect to prevent further connects
3641fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.disconnect();
36420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        mIsScanMode = true;
36430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                        transitionTo(mScanModeState);
36440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
36450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
3646fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                case CMD_ENABLE_BACKGROUND_SCAN:
3647fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    mEnableBackgroundScan = (message.arg1 == 1);
3648f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                    if (mEnableBackgroundScan) {
3649fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(true);
3650f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                        setScanAlarm(false);
3651f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                    } else {
3652fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(false);
3653f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                        setScanAlarm(true);
3654f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff                    }
3655fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    break;
36560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    /* Ignore network disconnect */
365755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
36580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
365955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
3660e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
3661e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
3662e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                    /* ConnectModeState does the rest of the handling */
3663027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    ret = NOT_HANDLED;
3664027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    break;
3665e1f9064e356a07a08222c8c4a588969b4c0a8c99Irfan Sheriff                case CMD_START_SCAN:
3666fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Disable background scan temporarily during a regular scan */
3667fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    if (mEnableBackgroundScan) {
3668fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(false);
3669fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    }
3670fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Handled in parent state */
3671027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    ret = NOT_HANDLED;
3672027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    break;
367355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SCAN_RESULTS_EVENT:
3674fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Re-enable background scan when a pending scan result is received */
3675fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    if (mEnableBackgroundScan && mScanResultIsPending) {
3676fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.enableBackgroundScan(true);
3677fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    }
3678fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff                    /* Handled in parent state */
3679027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    ret = NOT_HANDLED;
3680027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    break;
36813809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                case WifiP2pService.P2P_CONNECTION_CHANGED:
36823809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    NetworkInfo info = (NetworkInfo) message.obj;
36833809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    mP2pConnected.set(info.isConnected());
36843809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    if (mP2pConnected.get()) {
36853809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                        int defaultInterval = mContext.getResources().getInteger(
36863809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                                R.integer.config_wifi_scan_interval_p2p_connected);
36873809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                        long scanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
36883809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                                Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
36893809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                                defaultInterval);
36903809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                        mWifiNative.setScanInterval((int) scanIntervalMs/1000);
36913809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    } else if (mWifiConfigStore.getConfiguredNetworks().size() == 0) {
36923809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                        if (DBG) log("Turn on scanning after p2p disconnected");
36933809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                        sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
36943809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                                    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
36953809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                    }
36969f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                case CMD_RECONNECT:
36979f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                case CMD_REASSOCIATE:
36989f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    // Drop a third party reconnect/reassociate if we are
36999f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    // tempoarily disconnected for p2p
37009f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    if (mTemporarilyDisconnectWifi) ret = NOT_HANDLED;
37019f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                    break;
37020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
3703027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff                    ret = NOT_HANDLED;
37040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
3705027828bff7928a125c7150fe7cb4dcbcba113912Irfan Sheriff            return ret;
37060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
3707090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff
3708090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        @Override
3709090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        public void exit() {
3710fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            /* No need for a background scan upon exit from a disconnected state */
3711fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            if (mEnableBackgroundScan) {
3712fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.enableBackgroundScan(false);
3713fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff            }
3714f9e2a491176b086cd3c238b209e025cd68d76001Irfan Sheriff            setScanAlarm(false);
3715090813ac95b1bd5f60f67f70bb49b0886954de09Irfan Sheriff        }
37160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
37170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff
3718d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    class WpsRunningState extends State {
3719d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        //Tracks the source to provide a reply
3720d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        private Message mSourceMessage;
372102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
372202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public void enter() {
37237f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
372402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
3725d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff            mSourceMessage = Message.obtain(getCurrentMessage());
372602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
372702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        @Override
372802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        public boolean processMessage(Message message) {
37297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
373002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            switch (message.what) {
3731d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiMonitor.WPS_SUCCESS_EVENT:
3732d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(mSourceMessage, WifiManager.WPS_COMPLETED);
3733d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    mSourceMessage.recycle();
3734d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    mSourceMessage = null;
3735d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    transitionTo(mDisconnectedState);
3736d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
3737d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiMonitor.WPS_OVERLAP_EVENT:
3738d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED,
3739d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                            WifiManager.WPS_OVERLAP_ERROR);
3740d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    mSourceMessage.recycle();
3741d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    mSourceMessage = null;
3742d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    transitionTo(mDisconnectedState);
3743d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
3744d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiMonitor.WPS_FAIL_EVENT:
374586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    //arg1 has the reason for the failure
374686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED, message.arg1);
374786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    mSourceMessage.recycle();
374886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    mSourceMessage = null;
374986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    transitionTo(mDisconnectedState);
375086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    break;
3751d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiMonitor.WPS_TIMEOUT_EVENT:
375286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED,
375386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            WifiManager.WPS_TIMED_OUT);
3754d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    mSourceMessage.recycle();
3755d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    mSourceMessage = null;
3756d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    transitionTo(mDisconnectedState);
3757d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
3758d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.START_WPS:
3759d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.IN_PROGRESS);
3760d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    break;
376186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                case WifiManager.CANCEL_WPS:
376286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    if (mWifiNative.cancelWps()) {
376386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        replyToMessage(message, WifiManager.CANCEL_WPS_SUCCEDED);
376486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    } else {
376586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        replyToMessage(message, WifiManager.CANCEL_WPS_FAILED, WifiManager.ERROR);
376686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    }
376786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    transitionTo(mDisconnectedState);
376886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    break;
376902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                /* Defer all commands that can cause connections to a different network
377002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 * or put the state machine out of connect mode
377102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                 */
377202fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_STOP_DRIVER:
377302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_SET_SCAN_MODE:
3774d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiManager.CONNECT_NETWORK:
377502fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_ENABLE_NETWORK:
377602fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_RECONNECT:
377702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                case CMD_REASSOCIATE:
3778d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                case WifiMonitor.NETWORK_CONNECTION_EVENT: /* Handled after exiting WPS state */
377902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    deferMessage(message);
378002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
378155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
37827f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Network connection lost");
378302fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    handleNetworkDisconnect();
378402fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    break;
3785dfd42a9bbc143a46411bf74ad5fddb7da1b3b6e6Irfan Sheriff                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
37865770b2dcf6f28f1ea44146d5eb8c8a6b9cfc3fceArik Nemtsov                    // Disregard auth failure events during WPS connection. The
37875770b2dcf6f28f1ea44146d5eb8c8a6b9cfc3fceArik Nemtsov                    // EAP sequence is retried several times, and there might be
37885770b2dcf6f28f1ea44146d5eb8c8a6b9cfc3fceArik Nemtsov                    // failures (especially for wps pin). We will get a WPS_XXX
37895770b2dcf6f28f1ea44146d5eb8c8a6b9cfc3fceArik Nemtsov                    // event at the end of the sequence anyway.
37905770b2dcf6f28f1ea44146d5eb8c8a6b9cfc3fceArik Nemtsov                    if (DBG) log("Ignore auth failure during WPS connection");
37915770b2dcf6f28f1ea44146d5eb8c8a6b9cfc3fceArik Nemtsov                    break;
379286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
379386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    //Throw away supplicant state changes when WPS is running.
379486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    //We will start getting supplicant state changes once we get
379586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    //a WPS success or failure
379686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    break;
379702fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                default:
379802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff                    return NOT_HANDLED;
379902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            }
380002fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff            return HANDLED;
380102fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff        }
3802d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff
380386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        @Override
3804d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        public void exit() {
3805d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff            mWifiConfigStore.enableAllNetworks();
3806d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff            mWifiConfigStore.loadConfiguredNetworks();
3807d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        }
380802fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff    }
380902fb46a297c4f645f2a30b574151401dd0978521Irfan Sheriff
38107dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    class SoftApStartingState extends State {
38117dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        @Override
38127dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        public void enter() {
38137f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
38147dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
38157dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff
38169575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            final Message message = getCurrentMessage();
38179575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            if (message.what == CMD_START_AP) {
38189575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                final WifiConfiguration config = (WifiConfiguration) message.obj;
38197dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff
38209575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                if (config == null) {
38219575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
38229575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                } else {
38239575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
38249575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    startSoftApWithConfig(config);
38257dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                }
38269575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            } else {
38279575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                throw new RuntimeException("Illegal transition to SoftApStartingState: " + message);
38289575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff            }
38297dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        }
38307dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        @Override
38317dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        public boolean processMessage(Message message) {
38327f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
38337dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            switch(message.what) {
38347dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_LOAD_DRIVER:
38357dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_UNLOAD_DRIVER:
38367dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_SUPPLICANT:
38377dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_SUPPLICANT:
38387dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP:
38397dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_AP:
38407dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_DRIVER:
38417dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_DRIVER:
38427dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_SCAN_MODE:
38437dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_SCAN_TYPE:
38447dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
38457dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
38467dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_PACKET_FILTERING:
38477dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
3848c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
38497dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    deferMessage(message);
38507dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    break;
38519575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
38529575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    WifiConfiguration config = (WifiConfiguration) message.obj;
38539575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    if (config != null) {
38549575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        startSoftApWithConfig(config);
38559575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    } else {
38569575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        loge("Softap config is null!");
38579575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                        sendMessage(CMD_START_AP_FAILURE);
38589575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    }
38599575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff                    break;
38607dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_SUCCESS:
38617dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    setWifiApState(WIFI_AP_STATE_ENABLED);
38627dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    transitionTo(mSoftApStartedState);
38637dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    break;
38647dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                case CMD_START_AP_FAILURE:
38657dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    // initiate driver unload
38667dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
38677dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    break;
38687dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                default:
38697dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    return NOT_HANDLED;
38707dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            }
38717dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff            return HANDLED;
38727dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff        }
38737dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff    }
38747dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff
387564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class SoftApStartedState extends State {
38760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
38770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public void enter() {
38787f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
38790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
38800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
38810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        @Override
38820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        public boolean processMessage(Message message) {
38837f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
38840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            switch(message.what) {
38850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_STOP_AP:
38867f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    if (DBG) log("Stopping Soft AP");
38870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
3888c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3889c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    /* We have not tethered at this point, so we just shutdown soft Ap */
38900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    try {
3891cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        mNwService.stopAccessPoint(mInterfaceName);
38920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    } catch(Exception e) {
38937f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Exception in stopAccessPoint()");
38940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    }
38950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    transitionTo(mDriverLoadedState);
38960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
38970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_AP:
38987dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    // Ignore a start on a running access point
38990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
39007dd04132d370537a07d3ad0e0ee7c8ff75166876Irfan Sheriff                    /* Fail client mode operation when soft AP is enabled */
39010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                case CMD_START_SUPPLICANT:
39027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                   loge("Cannot start supplicant with a running soft AP");
39030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    setWifiState(WIFI_STATE_UNKNOWN);
39040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    break;
3905c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3906c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3907c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (startTethering(stateChange.available)) {
3908c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        transitionTo(mTetheringState);
3909e8daf2a7000e12dc0d62cb98b06ca849cf40564aIrfan Sheriff                    }
391023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                    break;
39110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                default:
39120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                    return NOT_HANDLED;
39130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            }
39140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff            return HANDLED;
39150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff        }
39160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff    }
391723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff
3918c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    class TetheringState extends State {
3919c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3920c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public void enter() {
3921c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + "\n");
3922c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
3923c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3924c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            /* Send ourselves a delayed message to shut down if tethering fails to notify */
3925c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
3926c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
3927c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3928c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3929c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public boolean processMessage(Message message) {
3930c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
3931c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            switch(message.what) {
3932c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3933c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3934c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (isWifiTethered(stateChange.active)) {
3935c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        transitionTo(mTetheredState);
3936c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
3937c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return HANDLED;
3938c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
3939c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (message.arg1 == mTetherToken) {
3940c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Failed to get tether update, shutdown soft access point");
3941c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        setWifiApEnabled(null, false);
3942c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
3943c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3944c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_LOAD_DRIVER:
3945c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_UNLOAD_DRIVER:
3946c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_SUPPLICANT:
3947c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_SUPPLICANT:
3948c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_AP:
3949c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_AP:
3950c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_DRIVER:
3951c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_DRIVER:
3952c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_MODE:
3953c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_TYPE:
3954c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
3955c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
3956c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_PACKET_FILTERING:
3957c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
3958c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    deferMessage(message);
3959c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
3960c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                default:
3961c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return NOT_HANDLED;
3962c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            }
3963c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            return HANDLED;
3964c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3965c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
3966c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
396723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    class TetheredState extends State {
396823eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        @Override
396923eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        public void enter() {
39707f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + "\n");
397123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
397223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
397323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        @Override
397423eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        public boolean processMessage(Message message) {
39757f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
397623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            switch(message.what) {
3977c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
3978c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
3979c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (!isWifiTethered(stateChange.active)) {
3980c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Tethering reports wifi as untethered!, shut down soft Ap");
3981c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        setWifiApEnabled(null, false);
3982c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
398323eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                    return HANDLED;
3984c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_AP:
3985c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (DBG) log("Untethering before stopping AP");
3986c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    setWifiApState(WIFI_AP_STATE_DISABLING);
3987c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    stopTethering();
3988c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    transitionTo(mSoftApStoppingState);
3989c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
399023eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                default:
399123eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff                    return NOT_HANDLED;
399223eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff            }
3993c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            return HANDLED;
3994c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
3995c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    }
3996c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
3997c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff    class SoftApStoppingState extends State {
3998c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
3999c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public void enter() {
4000c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + "\n");
4001c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
4002c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
4003c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            /* Send ourselves a delayed message to shut down if tethering fails to notify */
4004c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
4005c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
4006c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
4007c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        }
4008c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        @Override
4009c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff        public boolean processMessage(Message message) {
4010c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            if (DBG) log(getName() + message.toString() + "\n");
4011c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            switch(message.what) {
4012c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_STATE_CHANGE:
4013c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    TetherStateChange stateChange = (TetherStateChange) message.obj;
4014c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
4015c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    /* Wait till wifi is untethered */
4016c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (isWifiTethered(stateChange.active)) break;
4017c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff
4018c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    try {
4019c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        mNwService.stopAccessPoint(mInterfaceName);
4020c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    } catch(Exception e) {
4021c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Exception in stopAccessPoint()");
4022c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
4023c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    transitionTo(mDriverLoadedState);
4024c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
4025c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
4026c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    if (message.arg1 == mTetherToken) {
4027c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        loge("Failed to get tether update, force stop access point");
4028c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        try {
4029c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                            mNwService.stopAccessPoint(mInterfaceName);
4030c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        } catch(Exception e) {
4031c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                            loge("Exception in stopAccessPoint()");
4032c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        }
4033c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                        transitionTo(mDriverLoadedState);
4034c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    }
4035c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
4036c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_LOAD_DRIVER:
4037c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_UNLOAD_DRIVER:
4038c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_SUPPLICANT:
4039c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_SUPPLICANT:
4040c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_AP:
4041c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_AP:
4042c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_DRIVER:
4043c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_DRIVER:
4044c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_MODE:
4045c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_SCAN_TYPE:
4046c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_COUNTRY_CODE:
4047c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_SET_FREQUENCY_BAND:
4048c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_START_PACKET_FILTERING:
4049c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                case CMD_STOP_PACKET_FILTERING:
4050c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    deferMessage(message);
4051c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    break;
4052c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                default:
4053c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff                    return NOT_HANDLED;
4054c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            }
4055c74694d5e12b66b1b234d2c8d02a8f72f0e3cd66Irfan Sheriff            return HANDLED;
405623eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff        }
405723eb297c771bd996fe8559178feb1a07be43ad72Irfan Sheriff    }
40587f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
4059d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    //State machine initiated requests can have replyTo set to null indicating
4060d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    //there are no recepients, we ignore those reply actions
4061d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private void replyToMessage(Message msg, int what) {
4062d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        if (msg.replyTo == null) return;
4063d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        Message dstMsg = obtainMessageWithArg2(msg);
4064d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        dstMsg.what = what;
4065d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
4066d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    }
4067d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff
4068d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private void replyToMessage(Message msg, int what, int arg1) {
4069d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        if (msg.replyTo == null) return;
4070d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        Message dstMsg = obtainMessageWithArg2(msg);
4071d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        dstMsg.what = what;
4072d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        dstMsg.arg1 = arg1;
4073d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
4074d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    }
4075d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff
4076d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private void replyToMessage(Message msg, int what, Object obj) {
4077d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        if (msg.replyTo == null) return;
4078d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        Message dstMsg = obtainMessageWithArg2(msg);
4079d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        dstMsg.what = what;
4080d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        dstMsg.obj = obj;
4081d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
4082d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    }
4083d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff
4084d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /**
4085d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * arg2 on the source message has a unique id that needs to be retained in replies
4086d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * to match the request
4087d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     *
4088d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * see WifiManager for details
4089d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     */
4090d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private Message obtainMessageWithArg2(Message srcMsg) {
4091d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        Message msg = Message.obtain();
4092d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        msg.arg2 = srcMsg.arg2;
4093d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff        return msg;
4094d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    }
4095d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff
40967f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    private void log(String s) {
40977f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        Log.d(TAG, s);
40987f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    }
40997f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
41007f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    private void loge(String s) {
41017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        Log.e(TAG, s);
41027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    }
41030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff}
4104