1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/*
2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2010 The Android Open Source Project
3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License");
5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License.
6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at
7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *      http://www.apache.org/licenses/LICENSE-2.0
9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software
11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS,
12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and
14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License.
15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi;
18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
198639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
208639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
218639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
228639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
238639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
28155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
29155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * TODO:
30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Deprecate WIFI_STATE_UNKNOWN
31155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
328639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
33155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
34935a9c0c9e091829ac359a6d99ae3bd69fe9041bDianne Hackbornimport android.app.ActivityManager;
35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.app.AlarmManager;
36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.app.PendingIntent;
37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.app.backup.IBackupManager;
38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.bluetooth.BluetoothAdapter;
39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.BroadcastReceiver;
40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context;
41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Intent;
42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.IntentFilter;
43155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.pm.PackageManager;
44155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.database.ContentObserver;
45a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.ConnectivityManager;
46a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.DhcpResults;
47a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.DhcpStateMachine;
48a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.InterfaceConfiguration;
49a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.LinkAddress;
50a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.LinkProperties;
51a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.NetworkAgent;
52a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.NetworkCapabilities;
53a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.NetworkFactory;
54a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.NetworkInfo;
55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkInfo.DetailedState;
568639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.NetworkRequest;
57a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.NetworkUtils;
58a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.RouteInfo;
593b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colittiimport android.net.StaticIpConfiguration;
60a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.net.TrafficStats;
618639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.BatchedScanResult;
628639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.BatchedScanSettings;
638639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.RssiPacketCountInfo;
648639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.ScanResult;
658639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.ScanSettings;
6656d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalleimport android.net.wifi.SupplicantState;
678639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiChannel;
688639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiConfiguration;
698639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiConnectionStatistics;
708639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiEnterpriseConfig;
718639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiInfo;
728639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiLinkLayerStats;
738639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiManager;
748639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiSsid;
758639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WpsInfo;
768639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WpsResult;
77155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WpsResult.Status;
78f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mannimport android.net.wifi.p2p.IWifiP2pManager;
79a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.BatteryStats;
80a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.Bundle;
81a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.IBinder;
82a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.INetworkManagementService;
83a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.Looper;
84a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.Message;
85a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.Messenger;
86a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.PowerManager;
87b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalleimport android.os.Process;
88a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.RemoteException;
89a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.ServiceManager;
90a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.SystemClock;
91a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.SystemProperties;
92a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.UserHandle;
93a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpandeimport android.os.WorkSource;
94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.provider.Settings;
9533b575ca6bee66183929f9474b5a161432918604Vinit Deshpandeimport android.telephony.TelephonyManager;
96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.text.TextUtils;
97f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log;
988639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.util.LruCache;
99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.R;
101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.app.IBatteryStats;
102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.AsyncChannel;
103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.Protocol;
104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.State;
105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.StateMachine;
106d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colittiimport com.android.server.net.NetlinkTracker;
107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.server.wifi.p2p.WifiP2pServiceImpl;
108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1098639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.io.BufferedReader;
110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileDescriptor;
1118639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.io.FileNotFoundException;
1128639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.io.FileReader;
1138639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.io.IOException;
114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.PrintWriter;
1158639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.net.Inet4Address;
116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.net.InetAddress;
1178639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.ArrayList;
1188639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.HashSet;
1198639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.LinkedList;
1208639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.List;
1218639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.Locale;
1228639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.Queue;
123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.concurrent.atomic.AtomicBoolean;
1248639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport java.util.concurrent.atomic.AtomicInteger;
1252f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalleimport java.util.regex.Matcher;
126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.regex.Pattern;
127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Track the state of Wifi connectivity. All event handling is done here,
130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * and all changes in connectivity state are initiated here.
131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Wi-Fi now supports three modes of operation: Client, SoftAp and p2p
133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * In the current implementation, we support concurrent wifi p2p and wifi operation.
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * The WifiStateMachine handles SoftAp and Client operations while WifiP2pService
135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * handles p2p operation.
136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * @hide
138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepublic class WifiStateMachine extends StateMachine {
140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String NETWORKTYPE = "WIFI";
142ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson    private static final String NETWORKTYPE_UNTRUSTED = "WIFI_UT";
143ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    private static boolean DBG = false;
144ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    private static boolean VDBG = false;
1459f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    private static boolean VVDBG = false;
146ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    private static boolean mLogMessages = false;
147f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
148931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle    private static final int ONE_HOUR_MILLI = 1000 * 60 * 60;
149931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle
150eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande    private static final String GOOGLE_OUI = "DA-A1-19";
151042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
152117be607246604e875de62aa8cdd99700b77a2b4vandwalle    /* temporary debug flag - best network selection development */
153ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    private static boolean PDBG = false;
1542451dbcc4f9641df188326215b204b798eb70c46vandwalle
1552451dbcc4f9641df188326215b204b798eb70c46vandwalle    /* debug flag, indicating if handling of ASSOCIATION_REJECT ended up blacklisting
1562451dbcc4f9641df188326215b204b798eb70c46vandwalle     * the corresponding BSSID.
1572451dbcc4f9641df188326215b204b798eb70c46vandwalle     */
1582451dbcc4f9641df188326215b204b798eb70c46vandwalle    private boolean didBlackListBSSID = false;
1592451dbcc4f9641df188326215b204b798eb70c46vandwalle
160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    /**
161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     * Log with error attribute
162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     *
163f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     * @param s is string log
164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     */
165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    protected void loge(String s) {
166b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        Log.e(getName(), s);
167f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
168b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle    protected void log(String s) {;
169b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        Log.e(getName(), s);
170f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiMonitor mWifiMonitor;
173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiNative mWifiNative;
174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiConfigStore mWifiConfigStore;
175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private WifiAutoJoinController mWifiAutoJoinController;
176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private INetworkManagementService mNwService;
177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private ConnectivityManager mCm;
178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final boolean mP2pSupported;
180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mTemporarilyDisconnectWifi = false;
182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final String mPrimaryDeviceType;
183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Scan results handling */
185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private List<ScanResult> mScanResults = new ArrayList<ScanResult>();
186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Pattern scanResultPattern = Pattern.compile("\t+");
187e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    private static final int SCAN_RESULT_CACHE_SIZE = 160;
188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final LruCache<String, ScanResult> mScanResultCache;
1892f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    // For debug, number of known scan results that were found as part of last scan result event,
1902f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    // as well the number of scans results returned by the supplicant with that message
191be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    private int mNumScanResultsKnown;
1922f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    private int mNumScanResultsReturned;
193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Batch scan results */
195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final List<BatchedScanResult> mBatchedScanResults =
196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            new ArrayList<BatchedScanResult>();
197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mBatchedScanOwnerUid = UNKNOWN_SCAN_SOURCE;
198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mExpectedBatchedScans = 0;
199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private long mBatchedScanMinPollTime = 0;
200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
201f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private boolean mScreenOn = false;
202f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Chipset supports background scan */
204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final boolean mBackgroundScanSupported;
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mInterfaceName;
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tethering interface could be separate from wlan interface */
208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mTetherInterfaceName;
209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mLastSignalLevel = -1;
211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mLastBssid;
212931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle    private int mLastNetworkId; // The network Id we successfully joined
2137806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    private boolean linkDebouncing = false;
2147806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
2157806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    // Testing various network disconnect cases by sending lots of spurious
2167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    // disconnect to supplicant
2177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    private boolean testNetworkDisconnect = false;
2187806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mEnableRssiPolling = false;
220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mEnableBackgroundScan = false;
221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mRssiPollToken = 0;
222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* 3 operational states for STA operation: CONNECT_MODE, SCAN_ONLY_MODE, SCAN_ONLY_WIFI_OFF_MODE
223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    * In CONNECT_MODE, the STA can scan and connect to an access point
224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    * In SCAN_ONLY_MODE, the STA can only scan for access points
225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    * In SCAN_ONLY_WIFI_OFF_MODE, the STA can only scan for access points with wifi toggle being off
226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    */
227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mOperationalMode = CONNECT_MODE;
228a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private boolean mIsScanOngoing = false;
229a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private boolean mIsFullScanOngoing = false;
2309086afccf6938a49eb9a2cd248917c1cb0943942vandwalle    private boolean mSendScanResultsBroadcast = false;
2319086afccf6938a49eb9a2cd248917c1cb0943942vandwalle
232a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private final Queue<Message> mBufferedScanMsg = new LinkedList<Message>();
233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WorkSource mScanWorkSource = null;
234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int UNKNOWN_SCAN_SOURCE = -1;
2354dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    private static final int SCAN_ALARM_SOURCE = -2;
236b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle    private static final int ADD_OR_UPDATE_SOURCE = -3;
237005c1ef113192f898499a407dd266393a8d6b076vandwalle    private static final int SET_ALLOW_UNTRUSTED_SOURCE = -4;
23868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle    private static final int ENABLE_WIFI = -5;
2399086afccf6938a49eb9a2cd248917c1cb0943942vandwalle    public static final int DFS_RESTRICTED_SCAN_REQUEST = -6;
2404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
241a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private static final int SCAN_REQUEST_BUFFER_MAX_SIZE = 10;
242a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private static final String CUSTOMIZED_SCAN_SETTING = "customized_scan_settings";
243a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private static final String CUSTOMIZED_SCAN_WORKSOURCE = "customized_scan_worksource";
244ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static final String SCAN_REQUEST_TIME = "scan_request_time";
245ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle
246a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private static final String BATCHED_SETTING = "batched_settings";
247a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private static final String BATCHED_WORKSOURCE = "batched_worksource";
248a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks if state machine has received any screen state change broadcast yet.
250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * We can miss one of these at boot.
251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AtomicBoolean mScreenBroadcastReceived = new AtomicBoolean(false);
253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mBluetoothConnectionActive = false;
255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private PowerManager.WakeLock mSuspendWakeLock;
257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Interval in milliseconds between polling for RSSI
260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and linkspeed information
261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2657806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle     * Interval in milliseconds between receiving a disconnect event
2667806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle     * while connected to a good AP, and handling the disconnect proper
2677806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle     */
2687806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    private static final int LINK_FLAPPING_DEBOUNCE_MSEC = 7000;
2697806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
2707806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    /**
271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Delay between supplicant restarts upon failure to establish connection
272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;
274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Number of times we attempt to restart supplicant
277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SUPPLICANT_RESTART_TRIES = 5;
279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mSupplicantRestartCount = 0;
281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks sequence number on stop failure message */
282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mSupplicantStopFailureToken = 0;
283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Tether state change notification time out
286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks sequence number on a tether notification time out */
290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mTetherToken = 0;
291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Driver start time out.
294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DRIVER_START_TIME_OUT_MSECS = 10000;
296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks sequence number on a driver time out */
298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mDriverStartToken = 0;
299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The link properties of the wifi interface.
302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Do not modify this directly; use updateLinkProperties instead.
303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private LinkProperties mLinkProperties;
305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks sequence number on a periodic scan message */
307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mPeriodicScanToken = 0;
308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // Wakelock held during wifi start/stop and driver load/unload
310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private PowerManager.WakeLock mWakeLock;
311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Context mContext;
313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final Object mDhcpResultsLock = new Object();
315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private DhcpResults mDhcpResults;
316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiInfo mWifiInfo;
317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private NetworkInfo mNetworkInfo;
3183831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt    private NetworkCapabilities mNetworkCapabilities;
319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private SupplicantStateTracker mSupplicantStateTracker;
320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private DhcpStateMachine mDhcpStateMachine;
321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDhcpActive = false;
322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
323200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    private int mWifiLinkLayerStatsSupported = 4; // Temporary disable
32427355a942653264388e909a4276196ee63e57811vandwalle
3259c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt    private final AtomicInteger mCountryCodeSequence = new AtomicInteger();
3269c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt
3270d616ef3bf635dff8722e064c0be842676390ed8vandwalle    // Whether the state machine goes thru the Disconnecting->Disconnected->ObtainingIpAddress
328b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    private int mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE;
3294dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
3300d616ef3bf635dff8722e064c0be842676390ed8vandwalle    // Roaming failure count
3310d616ef3bf635dff8722e064c0be842676390ed8vandwalle    private int mRoamFailCount = 0;
3320d616ef3bf635dff8722e064c0be842676390ed8vandwalle
333e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    // This is the BSSID we are trying to associate to, it can be set to "any"
334e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    // if we havent selected a BSSID for joining.
335005c1ef113192f898499a407dd266393a8d6b076vandwalle    // if we havent selected a BSSID for joining.
336e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    // The BSSID we are associated to is found in mWifiInfo
337b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    private String mTargetRoamBSSID = "any";
338b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
33985f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle    private long mLastDriverRoamAttempt = 0;
34085f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle
34140ff222cec1bd05879edb53abc75c6deead734cavandwalle    private WifiConfiguration targetWificonfiguration = null;
34240ff222cec1bd05879edb53abc75c6deead734cavandwalle
343be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    // Used as debug to indicate which configuration last was saved
344be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    private WifiConfiguration lastSavedConfigurationAttempt = null;
345be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
346be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    // Used as debug to indicate which configuration last was removed
347be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    private WifiConfiguration lastForgetConfigurationAttempt = null;
348be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
349b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    boolean isRoaming() {
350b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle        return mAutoRoaming == WifiAutoJoinController.AUTO_JOIN_ROAMING
351b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                || mAutoRoaming == WifiAutoJoinController.AUTO_JOIN_EXTENDED_ROAMING;
352b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    }
353b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
354b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    public void autoRoamSetBSSID(int netId, String bssid) {
355b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle        autoRoamSetBSSID(mWifiConfigStore.getWifiConfiguration(netId), bssid);
356b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    }
357b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
3589f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    public boolean autoRoamSetBSSID(WifiConfiguration config, String bssid) {
3599f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        boolean ret = true;
3609f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (mTargetRoamBSSID == null) mTargetRoamBSSID = "any";
3619f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (bssid == null) bssid = "any";
3629f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (config == null) return false; // Nothing to do
3639f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
3649f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (mTargetRoamBSSID != null && bssid == mTargetRoamBSSID && bssid == config.BSSID) {
3659f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            return false; // We didnt change anything
3669f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
367e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        if (!mTargetRoamBSSID.equals("any") && bssid.equals("any")) {
3689f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            // Changing to ANY
3699f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            if (!mWifiConfigStore.roamOnAny) {
3709f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                ret =  false; // Nothing to do
3719f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            }
3729f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
3732f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        if (VDBG) {
3742f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle           loge("autoRoamSetBSSID " + bssid
3752f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                   + " key=" + config.configKey());
376b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle        }
3772f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        config.autoJoinBSSID = bssid;
3782f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        mTargetRoamBSSID = bssid;
3792f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        mWifiConfigStore.saveWifiConfigBSSID(config);
380e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        return ret;
381b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    }
3824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
383d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti    /**
384d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti     * Subset of link properties coming from netlink.
385d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti     * Currently includes IPv4 and IPv6 addresses. In the future will also include IPv6 DNS servers
386d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti     * and domains obtained from router advertisements (RFC 6106).
387d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti     */
388d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti    private NetlinkTracker mNetlinkTracker;
389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AlarmManager mAlarmManager;
391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private PendingIntent mScanIntent;
392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private PendingIntent mDriverStopIntent;
393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private PendingIntent mBatchedScanIntervalIntent;
394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks current frequency mode */
396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks if we are filtering Multicast v4 packets. Default is to filter. */
399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AtomicBoolean mFilteringMulticastV4Packets = new AtomicBoolean(true);
400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // Channel for sending replies.
402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mReplyChannel = new AsyncChannel();
403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
404f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    private WifiP2pServiceImpl mWifiP2pServiceImpl;
405446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
406446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    // Used to initiate a connection with WifiP2pService
407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mWifiP2pChannel;
408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mWifiApConfigChannel;
409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4100af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti    private int mConnectionRequests = 0;
4117d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt    private WifiNetworkFactory mNetworkFactory;
412ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson    private UntrustedWifiNetworkFactory mUntrustedNetworkFactory;
4137d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt    private WifiNetworkAgent mNetworkAgent;
4143831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt
415c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    // Keep track of various statistics, for retrieval by System Apps, i.e. under @SystemApi
416c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    // We should really persist that into the networkHistory.txt file, and read it back when
417c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    // WifiStateMachine starts up
418c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    private WifiConnectionStatistics mWifiConnectionStatistics = new WifiConnectionStatistics();
419c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle
4203831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt    // Used to filter out requests we couldn't possibly satisfy.
4213831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt    private final NetworkCapabilities mNetworkCapabilitiesFilter = new NetworkCapabilities();
4223831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt
423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* The base for wifi message types */
424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int BASE = Protocol.BASE_WIFI;
425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Start the supplicant */
426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_SUPPLICANT                 = BASE + 11;
427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Stop the supplicant */
428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STOP_SUPPLICANT                  = BASE + 12;
429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Start the driver */
430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_DRIVER                     = BASE + 13;
431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Stop the driver */
432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STOP_DRIVER                      = BASE + 14;
433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Indicates Static IP succeeded */
434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STATIC_IP_SUCCESS                = BASE + 15;
435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Indicates Static IP failed */
436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STATIC_IP_FAILURE                = BASE + 16;
437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Indicates supplicant stop failed */
438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STOP_SUPPLICANT_FAILED           = BASE + 17;
439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Delayed stop to avoid shutting down driver too quick*/
440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_DELAYED_STOP_DRIVER              = BASE + 18;
441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* A delayed message sent to start driver when it fail to come up */
442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_DRIVER_START_TIMED_OUT           = BASE + 19;
443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Start the soft access point */
445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_AP                         = BASE + 21;
446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Indicates soft ap start succeeded */
447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_AP_SUCCESS                 = BASE + 22;
448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Indicates soft ap start failed */
449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_AP_FAILURE                 = BASE + 23;
450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Stop the soft access point */
451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STOP_AP                          = BASE + 24;
452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set the soft access point configuration */
453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_AP_CONFIG                    = BASE + 25;
454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Soft access point configuration set completed */
455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_AP_CONFIG_COMPLETED          = BASE + 26;
456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Request the soft access point configuration */
457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_REQUEST_AP_CONFIG                = BASE + 27;
458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Response to access point configuration request */
459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_RESPONSE_AP_CONFIG               = BASE + 28;
460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Invoked when getting a tether state change notification */
461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_TETHER_STATE_CHANGE              = BASE + 29;
462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* A delayed message sent to indicate tether state change failed to arrive */
463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_TETHER_NOTIFICATION_TIMED_OUT    = BASE + 30;
464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 31;
466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Supplicant commands */
468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Is supplicant alive ? */
469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_PING_SUPPLICANT                  = BASE + 51;
470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Add/update a network configuration */
471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_ADD_OR_UPDATE_NETWORK            = BASE + 52;
472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Delete a network */
473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_REMOVE_NETWORK                   = BASE + 53;
474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Enable a network. The device will attempt a connection to the given network. */
475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_ENABLE_NETWORK                   = BASE + 54;
476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Enable all networks */
477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_ENABLE_ALL_NETWORKS              = BASE + 55;
478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Blacklist network. De-prioritizes the given BSSID for connection. */
479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_BLACKLIST_NETWORK                = BASE + 56;
480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Clear the blacklist network list */
481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_CLEAR_BLACKLIST                  = BASE + 57;
482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Save configuration */
483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SAVE_CONFIG                      = BASE + 58;
484a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    /* Get configured networks */
485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_GET_CONFIGURED_NETWORKS          = BASE + 59;
486a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    /* Get available frequencies */
487a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    static final int CMD_GET_CAPABILITY_FREQ              = BASE + 60;
488a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    /* Get adaptors */
489048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande    static final int CMD_GET_SUPPORTED_FEATURES           = BASE + 61;
4909878c61bbd81176561991be025af44efc67332feWenchao Tong    /* Get configured networks with real preSharedKey */
4919878c61bbd81176561991be025af44efc67332feWenchao Tong    static final int CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS = BASE + 62;
492200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    /* Get Link Layer Stats thru HAL */
493200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    static final int CMD_GET_LINK_LAYER_STATS             = BASE + 63;
494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Supplicant commands after driver start*/
495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Initiate a scan */
496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_SCAN                       = BASE + 71;
497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set operational mode. CONNECT, SCAN ONLY, SCAN_ONLY with Wi-Fi off mode */
498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_OPERATIONAL_MODE             = BASE + 72;
499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Disconnect from a network */
500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_DISCONNECT                       = BASE + 73;
501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Reconnect to a network */
502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_RECONNECT                        = BASE + 74;
503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Reassociate to a network */
504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_REASSOCIATE                      = BASE + 75;
505c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    /* Get Connection Statistis */
506c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    static final int CMD_GET_CONNECTION_STATISTICS        = BASE + 76;
507c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle
508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Controls suspend mode optimizations
509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * When high perf mode is enabled, suspend mode optimizations are disabled
511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * When high perf mode is disabled, suspend mode optimizations are enabled
513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Suspend mode optimizations include:
515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * - packet filtering
516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * - turn off roaming
517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * - DTIM wake up settings
518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_HIGH_PERF_MODE               = BASE + 77;
520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set the country code */
521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_COUNTRY_CODE                 = BASE + 80;
522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Enables RSSI poll */
523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_ENABLE_RSSI_POLL                 = BASE + 82;
524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* RSSI poll */
525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_RSSI_POLL                        = BASE + 83;
526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set up packet filtering */
527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_START_PACKET_FILTERING           = BASE + 84;
528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Clear packet filter */
529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_STOP_PACKET_FILTERING            = BASE + 85;
530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Enable suspend mode optimizations in the driver */
531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_SUSPEND_OPT_ENABLED          = BASE + 86;
5327806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    /* Delayed NETWORK_DISCONNECT */
5337806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    static final int CMD_DELAYED_NETWORK_DISCONNECT       = BASE + 87;
534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* When there are no saved networks, we do a periodic scan to notify user of
535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * an open network */
536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_NO_NETWORKS_PERIODIC_SCAN        = BASE + 88;
5377806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    /* Test network Disconnection NETWORK_DISCONNECT */
5387806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    static final int CMD_TEST_NETWORK_DISCONNECT          = BASE + 89;
5397806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    private int testNetworkDisconnectCounter = 0;
540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* arg1 values to CMD_STOP_PACKET_FILTERING and CMD_START_PACKET_FILTERING */
542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int MULTICAST_V6  = 1;
543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int MULTICAST_V4  = 0;
544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande   /* Set the frequency band */
546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_SET_FREQUENCY_BAND               = BASE + 90;
547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Enable TDLS on a specific MAC address */
548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_ENABLE_TDLS                      = BASE + 92;
5490d616ef3bf635dff8722e064c0be842676390ed8vandwalle    /* DHCP/IP configuration watchdog */
5507806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    static final int CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER    = BASE + 93;
5517806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
5527806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    /**
5530d616ef3bf635dff8722e064c0be842676390ed8vandwalle     * Make this timer 40 seconds, which is about the normal DHCP timeout.
5547806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle     * In no valid case, the WiFiStateMachine should remain stuck in ObtainingIpAddress
5557806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle     * for more than 30 seconds.
5567806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle     */
5570d616ef3bf635dff8722e064c0be842676390ed8vandwalle    static final int OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC = 40000;
558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5597806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    int obtainingIpWatchdogCount = 0;
5600d616ef3bf635dff8722e064c0be842676390ed8vandwalle
561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Commands from/to the SupplicantStateTracker */
562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Reset the supplicant state tracker */
563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_RESET_SUPPLICANT_STATE           = BASE + 111;
564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5650d616ef3bf635dff8722e064c0be842676390ed8vandwalle
5660d616ef3bf635dff8722e064c0be842676390ed8vandwalle    /**
5670d616ef3bf635dff8722e064c0be842676390ed8vandwalle     * Watchdog for protecting against b/16823537
5680d616ef3bf635dff8722e064c0be842676390ed8vandwalle     * Leave time for 4-ways handshake to succeed
5690d616ef3bf635dff8722e064c0be842676390ed8vandwalle     */
5700d616ef3bf635dff8722e064c0be842676390ed8vandwalle    static final int ROAM_GUARD_TIMER_MSEC = 15000;
5710d616ef3bf635dff8722e064c0be842676390ed8vandwalle
5720d616ef3bf635dff8722e064c0be842676390ed8vandwalle    int roamWatchdogCount = 0;
573be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    /* Roam state watchdog */
5740d616ef3bf635dff8722e064c0be842676390ed8vandwalle    static final int CMD_ROAM_WATCHDOG_TIMER    = BASE + 94;
57582199a285f4a45a46b44eb8253999aa918534753vandwalle    /* Screen change intent handling */
57682199a285f4a45a46b44eb8253999aa918534753vandwalle    static final int CMD_SCREEN_STATE_CHANGED              = BASE + 95;
5770d616ef3bf635dff8722e064c0be842676390ed8vandwalle
578be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    int disconnectingWatchdogCount = 0;
579be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    static final int DISCONNECTING_GUARD_TIMER_MSEC = 5000;
580be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
581be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    /* Disconnecting state watchdog */
5822f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    static final int CMD_DISCONNECTING_WATCHDOG_TIMER     = BASE + 96;
583be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
5842ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle    /* Disable an ephemeral network */
5852ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle    static final int CMD_DISABLE_EPHEMERAL_NETWORK = BASE + 98;
5862ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle
587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* P2p commands */
588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* We are ok with no response here since we wont do much with it anyway */
589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_ENABLE_P2P                = BASE + 131;
590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* In order to shut down supplicant cleanly, we wait till p2p has
591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * been disabled */
592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_DISABLE_P2P_REQ           = BASE + 132;
593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_DISABLE_P2P_RSP           = BASE + 133;
594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_BOOT_COMPLETED            = BASE + 134;
596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* change the batch scan settings.
598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * arg1 = responsible UID
599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * arg2 = csph (channel scans per hour)
600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * obj = bundle with the new settings and the optional worksource
601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_SET_BATCHED_SCAN          = BASE + 135;
603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_START_NEXT_BATCHED_SCAN   = BASE + 136;
604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CMD_POLL_BATCHED_SCAN         = BASE + 137;
605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
60614be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    /* We now have a valid IP configuration. */
60714be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    static final int CMD_IP_CONFIGURATION_SUCCESSFUL      = BASE + 138;
60814be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    /* We no longer have a valid IP configuration. */
60914be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    static final int CMD_IP_CONFIGURATION_LOST            = BASE + 139;
610d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti    /* Link configuration (IP address, DNS, ...) changes notified via netlink */
611badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    static final int CMD_UPDATE_LINKPROPERTIES            = BASE + 140;
612d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti
613e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle    /* Supplicant is trying to associate to a given BSSID */
614e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle    static final int CMD_TARGET_BSSID                     = BASE + 141;
615b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle
616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Reload all networks and reconnect */
617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static final int CMD_RELOAD_TLS_AND_RECONNECT         = BASE + 142;
618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
619f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    static final int CMD_AUTO_CONNECT                     = BASE + 143;
620f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
621e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    static final int network_status_unwanted_disconnect = 0;
622e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    static final int network_status_unwanted_disable_autojoin = 1;
623e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
62427355a942653264388e909a4276196ee63e57811vandwalle    static final int CMD_UNWANTED_NETWORK                 = BASE + 144;
62527355a942653264388e909a4276196ee63e57811vandwalle
6264dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    static final int CMD_AUTO_ROAM                        = BASE + 145;
6274dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
628be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle    static final int CMD_AUTO_SAVE_NETWORK                = BASE + 146;
629be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
6309f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    static final int CMD_ASSOCIATED_BSSID                = BASE + 147;
6314dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
632d30127db46224e45554f8964209221bba8ad41d9vandwalle    static final int CMD_NETWORK_STATUS                  = BASE + 148;
633d30127db46224e45554f8964209221bba8ad41d9vandwalle
634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Wifi state machine modes of operation */
635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* CONNECT_MODE - connect to any 'known' AP when it becomes available */
636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int CONNECT_MODE                   = 1;
637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* SCAN_ONLY_MODE - don't connect to any APs; scan, but only while apps hold lock */
638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int SCAN_ONLY_MODE                 = 2;
639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* SCAN_ONLY_WITH_WIFI_OFF - scan, but don't connect to any APs */
640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int SCAN_ONLY_WITH_WIFI_OFF_MODE   = 3;
641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SUCCESS = 1;
643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int FAILURE = -1;
644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks if suspend optimizations need to be disabled by DHCP,
646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * screen or due to high perf mode.
647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * When any of them needs to disable it, we keep the suspend optimizations
648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * disabled
649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mSuspendOptNeedsDisabled = 0;
651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SUSPEND_DUE_TO_DHCP       = 1;
653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SUSPEND_DUE_TO_HIGH_PERF  = 1<<1;
654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SUSPEND_DUE_TO_SCREEN     = 1<<2;
655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Tracks if user has enabled suspend optimizations through settings */
657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AtomicBoolean mUserWantsSuspendOpt = new AtomicBoolean(true);
658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Default framework scan interval in milliseconds. This is used in the scenario in which
661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * wifi chipset does not support background scanning to set up a
662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * periodic wake up scan so that the device can connect to a new access
663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * point on the move. {@link Settings.Global#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * override this.
665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final int mDefaultFrameworkScanIntervalMs;
667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
66866f8e08b668ebdc4c9b180f90e71cbb4f3e1c37fvandwalle    private int mDisconnectedScanPeriodMs = 10000;
669f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
670f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    /**
671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Supplicant scan interval in milliseconds.
672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Comes from {@link Settings.Global#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} or
673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * from the default config if the setting is not set
674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private long mSupplicantScanIntervalMs;
676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
678b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle     * timeStamp of last full band scan we perfoemed for autojoin while connected with screen lit
679b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle     */
680b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    private long lastFullBandConnectedTimeMilli;
681b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
682b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    /**
68340ff222cec1bd05879edb53abc75c6deead734cavandwalle     * time interval to the next full band scan we will perform for
68440ff222cec1bd05879edb53abc75c6deead734cavandwalle     * autojoin while connected with screen lit
685b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle     */
686b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    private long fullBandConnectedTimeIntervalMilli;
687b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
688b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    /**
68940ff222cec1bd05879edb53abc75c6deead734cavandwalle     * max time interval to the next full band scan we will perform for
69040ff222cec1bd05879edb53abc75c6deead734cavandwalle     * autojoin while connected with screen lit
691b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle     * Max time is 5 minutes
692b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle     */
693b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    private static final long  maxFullBandConnectedTimeIntervalMilli = 1000 * 60 * 5;
694b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
695b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle    /**
696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Minimum time interval between enabling all networks.
697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * A device can end up repeatedly connecting to a bad network on screen on/off toggle
698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * due to enabling every time. We add a threshold to avoid this.
699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS = 10 * 60 * 1000; /* 10 minutes */
701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private long mLastEnableAllNetworksTime;
702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
703dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle    int mRunningBeaconCount = 0;
704dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle
705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Starting and shutting down driver too quick causes problems leading to driver
707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * being in a bad state. Delay driver stop.
708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final int mDriverStopDelayMs;
710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mDelayedStopCounter;
711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mInDelayedStop = false;
712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // sometimes telephony gives us this data before boot is complete and we can't store it
714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // until after, so the write is deferred
715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private volatile String mPersistedCountryCode;
716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // Supplicant doesn't like setting the same country code multiple times (it may drop
718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // currently connected network), so we save the country code here to avoid redundency
719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mLastSetCountryCode;
720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Default parent state */
722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDefaultState = new DefaultState();
723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Temporary initial state */
724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mInitialState = new InitialState();
725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Driver loaded, waiting for supplicant to start */
726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mSupplicantStartingState = new SupplicantStartingState();
727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Driver loaded and supplicant ready */
728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mSupplicantStartedState = new SupplicantStartedState();
729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Waiting for supplicant to stop and monitor to exit */
730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mSupplicantStoppingState = new SupplicantStoppingState();
731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Driver start issued, waiting for completed event */
732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDriverStartingState = new DriverStartingState();
733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Driver started */
734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDriverStartedState = new DriverStartedState();
735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Wait until p2p is disabled
736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * This is a special state which is entered right after we exit out of DriverStartedState
737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * before transitioning to another state.
738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mWaitForP2pDisableState = new WaitForP2pDisableState();
740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Driver stopping */
741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDriverStoppingState = new DriverStoppingState();
742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Driver stopped */
743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDriverStoppedState = new DriverStoppedState();
744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Scan for networks, no connection will be established */
745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mScanModeState = new ScanModeState();
746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Connecting to an access point */
747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mConnectModeState = new ConnectModeState();
748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Connected at 802.11 (L2) level */
749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mL2ConnectedState = new L2ConnectedState();
750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* fetching IP after connection to access point (assoc+auth complete) */
751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mObtainingIpState = new ObtainingIpState();
752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Waiting for link quality verification to be complete */
753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mVerifyingLinkState = new VerifyingLinkState();
754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Connected with IP addr */
755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mConnectedState = new ConnectedState();
7564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    /* Roaming */
7574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    private State mRoamingState = new RoamingState();
758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* disconnect issued, waiting for network disconnect confirmation */
759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDisconnectingState = new DisconnectingState();
760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Network is not connected, supplicant assoc+auth is not complete */
761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDisconnectedState = new DisconnectedState();
762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Waiting for WPS to be completed*/
763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mWpsRunningState = new WpsRunningState();
764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Soft ap is starting up */
766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mSoftApStartingState = new SoftApStartingState();
767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Soft ap is running */
768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mSoftApStartedState = new SoftApStartedState();
769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Soft ap is running and we are waiting for tether notification */
770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mTetheringState = new TetheringState();
771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Soft ap is running and we are tethered through connectivity service */
772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mTetheredState = new TetheredState();
773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Waiting for untether confirmation before stopping soft Ap */
774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mUntetheringState = new UntetheringState();
775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private class TetherStateChange {
777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ArrayList<String> available;
778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ArrayList<String> active;
779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            available = av;
781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            active = ac;
782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
78533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    public static class SimAuthRequestData {
78633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        int networkId;
787dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        int protocol;
78833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String ssid;
789dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        String[] challenges;
79033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
79133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
79233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    public static class SimAuthResponseData {
79333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        int id;
79433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String Kc1;
79533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String SRES1;
79633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String Kc2;
79733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String SRES2;
79833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String Kc3;
79933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        String SRES3;
80033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_STATE_DISABLING},
805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_STATE_ENABLED},
806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_STATE_ENABLING},
807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int SCAN_REQUEST = 0;
823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String ACTION_START_SCAN =
824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        "com.android.server.WifiManager.action.START_SCAN";
825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String DELAYED_STOP_COUNTER = "DelayedStopCounter";
827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DRIVER_STOP_REQUEST = 0;
828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String ACTION_DELAYED_DRIVER_STOP =
829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP";
830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String ACTION_REFRESH_BATCHED_SCAN =
832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            "com.android.server.WifiManager.action.REFRESH_BATCHED_SCAN";
833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Keep track of whether WIFI is running.
835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mIsRunning = false;
837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Keep track of whether we last told the battery stats we had started.
840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mReportedRunning = false;
842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Most recently set source of starting WIFI.
845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final WorkSource mRunningWifiUids = new WorkSource();
847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The last reported UIDs that were responsible for starting WIFI.
850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final WorkSource mLastRunningWifiUids = new WorkSource();
852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final IBatteryStats mBatteryStats;
854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private BatchedScanSettings mBatchedScanSettings = null;
856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Track the worksource/cost of the current settings and track what's been noted
859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * to the battery stats, so we can mark the end of the previous when changing.
860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WorkSource mBatchedScanWorkSource = null;
862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mBatchedScanCsph = 0;
863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WorkSource mNotedBatchedScanWorkSource = null;
864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int mNotedBatchedScanCsph = 0;
865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8663c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt    private String mTcpBufferSizes = null;
8673c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt
86882199a285f4a45a46b44eb8253999aa918534753vandwalle    // Used for debug and stats gathering
86982199a285f4a45a46b44eb8253999aa918534753vandwalle    private static int sScanAlarmIntentCount = 0;
87082199a285f4a45a46b44eb8253999aa918534753vandwalle
8718242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    final static int frameworkMinScanIntervalSaneValue = 10000;
8728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
873931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle    public WifiStateMachine(Context context, String wlanInterface,
874931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            WifiTrafficPoller trafficPoller){
875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        super("WifiStateMachine");
876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext = context;
877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mInterfaceName = wlanInterface;
878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                BatteryStats.SERVICE_NAME));
881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNwService = INetworkManagementService.Stub.asInterface(b);
884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                PackageManager.FEATURE_WIFI_DIRECT);
887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative = new WifiNative(mInterfaceName);
889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
890f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        mWifiAutoJoinController = new WifiAutoJoinController(context, this,
891c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                mWifiConfigStore, mWifiConnectionStatistics, mWifiNative);
892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiMonitor = new WifiMonitor(this, mWifiNative);
893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo = new WifiInfo();
894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,
895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                getHandler());
896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mLinkProperties = new LinkProperties();
897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
898511a412adce5a46c41e61f90c0df6de5fb4e491cYuhao Zheng        IBinder s1 = ServiceManager.getService(Context.WIFI_P2P_SERVICE);
899511a412adce5a46c41e61f90c0df6de5fb4e491cYuhao Zheng        mWifiP2pServiceImpl = (WifiP2pServiceImpl)IWifiP2pManager.Stub.asInterface(s1);
900511a412adce5a46c41e61f90c0df6de5fb4e491cYuhao Zheng
901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNetworkInfo.setIsAvailable(false);
902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mLastBssid = null;
903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mLastSignalLevel = -1;
905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
906d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti        mNetlinkTracker = new NetlinkTracker(mInterfaceName, new NetlinkTracker.Callback() {
907d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti            public void update() {
908badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                sendMessage(CMD_UPDATE_LINKPROPERTIES);
909d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti            }
910d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti        });
911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
912d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti            mNwService.registerObserver(mNetlinkTracker);
913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (RemoteException e) {
914d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti            loge("Couldn't register netlink tracker: " + e.toString());
915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
918cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande        mScanIntent = getPrivateBroadcast(ACTION_START_SCAN, SCAN_REQUEST);
919cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande        mBatchedScanIntervalIntent = getPrivateBroadcast(ACTION_REFRESH_BATCHED_SCAN, 0);
920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
9218242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        // Make sure the interval is not configured less than 10 seconds
9228242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        int period = mContext.getResources().getInteger(
923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                R.integer.config_wifi_framework_scan_interval);
9248242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        if (period < frameworkMinScanIntervalSaneValue) {
9258242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            period = frameworkMinScanIntervalSaneValue;
9268242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        }
9278242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        mDefaultFrameworkScanIntervalMs = period;
928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDriverStopDelayMs = mContext.getResources().getInteger(
929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                R.integer.config_wifi_driver_stop_delay);
930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBackgroundScanSupported = mContext.getResources().getBoolean(
932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                R.bool.config_wifi_background_scan_support);
933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPrimaryDeviceType = mContext.getResources().getString(
935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                R.string.config_wifi_p2p_device_type);
936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mUserWantsSuspendOpt.set(Settings.Global.getInt(mContext.getContentResolver(),
938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
9403831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt        mNetworkCapabilitiesFilter.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
941937be0625eb1daa1b9d5a0991a3fe6ab2f4804c7Robert Greenwalt        mNetworkCapabilitiesFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
942937be0625eb1daa1b9d5a0991a3fe6ab2f4804c7Robert Greenwalt        mNetworkCapabilitiesFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
9433831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt        mNetworkCapabilitiesFilter.setLinkUpstreamBandwidthKbps(1024 * 1024);
9443831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt        mNetworkCapabilitiesFilter.setLinkDownstreamBandwidthKbps(1024 * 1024);
9453831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt        // TODO - needs to be a bit more dynamic
9463831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt        mNetworkCapabilities = new NetworkCapabilities(mNetworkCapabilitiesFilter);
9473831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt
948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.registerReceiver(
949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            new BroadcastReceiver() {
950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                @Override
951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                public void onReceive(Context context, Intent intent) {
952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ArrayList<String> available = intent.getStringArrayListExtra(
953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ConnectivityManager.EXTRA_AVAILABLE_TETHER);
954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ArrayList<String> active = intent.getStringArrayListExtra(
955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ConnectivityManager.EXTRA_ACTIVE_TETHER);
956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.registerReceiver(
961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new BroadcastReceiver() {
962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    @Override
963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    public void onReceive(Context context, Intent intent) {
9648242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        sScanAlarmIntentCount++; // Used for debug only
9658242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        startScan(SCAN_ALARM_SOURCE, mDelayedScanCounter.incrementAndGet(), null, null);
966f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        if (VDBG)
9678242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            loge("WiFiStateMachine SCAN ALARM -> " + mDelayedScanCounter.get());
968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                },
970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new IntentFilter(ACTION_START_SCAN));
971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        IntentFilter filter = new IntentFilter();
973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        filter.addAction(Intent.ACTION_SCREEN_ON);
974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        filter.addAction(Intent.ACTION_SCREEN_OFF);
975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        filter.addAction(ACTION_REFRESH_BATCHED_SCAN);
976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.registerReceiver(
977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new BroadcastReceiver() {
978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    @Override
979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    public void onReceive(Context context, Intent intent) {
980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        String action = intent.getAction();
981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (action.equals(Intent.ACTION_SCREEN_ON)) {
98382199a285f4a45a46b44eb8253999aa918534753vandwalle                            sendMessage(CMD_SCREEN_STATE_CHANGED, 1);
984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
98582199a285f4a45a46b44eb8253999aa918534753vandwalle                            sendMessage(CMD_SCREEN_STATE_CHANGED, 0);
986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else if (action.equals(ACTION_REFRESH_BATCHED_SCAN)) {
987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            startNextBatchedScanAsync();
988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }, filter);
991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.registerReceiver(
993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new BroadcastReceiver() {
994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    @Override
995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    public void onReceive(Context context, Intent intent) {
996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                       int counter = intent.getIntExtra(DELAYED_STOP_COUNTER, 0);
997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                       sendMessage(CMD_DELAYED_STOP_DRIVER, counter, 0);
998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                },
1000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new IntentFilter(ACTION_DELAYED_DRIVER_STOP));
1001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
1003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED), false,
1004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new ContentObserver(getHandler()) {
1005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    @Override
1006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    public void onChange(boolean selfChange) {
1007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mUserWantsSuspendOpt.set(Settings.Global.getInt(mContext.getContentResolver(),
1008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
1009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                });
1011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.registerReceiver(
1013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new BroadcastReceiver() {
1014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    @Override
1015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    public void onReceive(Context context, Intent intent) {
1016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_BOOT_COMPLETED);
1017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                },
1019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
1020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mScanResultCache = new LruCache<String, ScanResult>(SCAN_RESULT_CACHE_SIZE);
1022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
1024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getName());
1025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mSuspendWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WifiSuspend");
1027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mSuspendWakeLock.setReferenceCounted(false);
1028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
10293c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt        mTcpBufferSizes = mContext.getResources().getString(
10303c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt                com.android.internal.R.string.config_wifi_tcp_buffers);
10313c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt
1032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addState(mDefaultState);
1033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mInitialState, mDefaultState);
1034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mSupplicantStartingState, mDefaultState);
1035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mSupplicantStartedState, mDefaultState);
1036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mDriverStartingState, mSupplicantStartedState);
1037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mDriverStartedState, mSupplicantStartedState);
1038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mScanModeState, mDriverStartedState);
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mConnectModeState, mDriverStartedState);
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mL2ConnectedState, mConnectModeState);
1041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            addState(mObtainingIpState, mL2ConnectedState);
1042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            addState(mVerifyingLinkState, mL2ConnectedState);
1043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            addState(mConnectedState, mL2ConnectedState);
10444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            addState(mRoamingState, mL2ConnectedState);
1045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mDisconnectingState, mConnectModeState);
1046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mDisconnectedState, mConnectModeState);
1047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mWpsRunningState, mConnectModeState);
1048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mWaitForP2pDisableState, mSupplicantStartedState);
1049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mDriverStoppingState, mSupplicantStartedState);
1050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mDriverStoppedState, mSupplicantStartedState);
1051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mSupplicantStoppingState, mDefaultState);
1052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mSoftApStartingState, mDefaultState);
1053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mSoftApStartedState, mDefaultState);
1054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mTetheringState, mSoftApStartedState);
1055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mTetheredState, mSoftApStartedState);
1056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mUntetheringState, mSoftApStartedState);
1057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setInitialState(mInitialState);
1059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1060935a9c0c9e091829ac359a6d99ae3bd69fe9041bDianne Hackborn        setLogRecSize(ActivityManager.isLowRamDeviceStatic() ? 100 : 3000);
1061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setLogOnlyTransitions(false);
1062f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (VDBG) setDbg(true);
1063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //start the state machine
1065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        start();
1066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
1068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
1070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1073cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande
1074cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande    PendingIntent getPrivateBroadcast(String action, int requestCode) {
1075cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande        Intent intent = new Intent(action, null);
1076f5a84fcd66298ee6e96b781d2645422a1571ac07Vinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1077cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande        intent.setPackage(this.getClass().getPackage().getName());
1078cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande        return PendingIntent.getBroadcast(mContext, requestCode, intent, 0);
1079cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande    }
1080cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande
1081ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    private int mVerboseLoggingLevel = 0;
1082ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
1083ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    int getVerboseLoggingLevel() {
1084ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        return mVerboseLoggingLevel;
1085ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
1086ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
1087ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    void enableVerboseLogging(int verbose) {
1088ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        mVerboseLoggingLevel = verbose;
1089ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        if (verbose > 0) {
1090ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            DBG = true;
1091ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            VDBG = true;
1092ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            PDBG = true;
1093ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            mLogMessages = true;
1094ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle            mWifiNative.setSupplicantLogLevel("DEBUG");
1095ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        } else {
1096ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            DBG = false;
1097ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            VDBG = false;
1098ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            PDBG = false;
1099ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            mLogMessages = false;
1100ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle            mWifiNative.setSupplicantLogLevel("INFO");
1101ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        }
11020888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        mWifiAutoJoinController.enableVerboseLogging(verbose);
11030888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        mWifiMonitor.enableVerboseLogging(verbose);
11040888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        mWifiNative.enableVerboseLogging(verbose);
11050888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        mWifiConfigStore.enableVerboseLogging(verbose);
11060888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        mSupplicantStateTracker.enableVerboseLogging(verbose);
1107ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
1108ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
1109c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    private int mAggressiveHandover = 0;
1110c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
1111c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    int getAggressiveHandover() {
1112c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        return mAggressiveHandover;
1113c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    }
1114c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
1115c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    void enableAggressiveHandover(int enabled) {
1116c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        mAggressiveHandover = enabled;
1117c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    }
1118c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
1119c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    public void setAllowScansWithTraffic(int enabled) {
11209f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        mWifiConfigStore.alwaysEnableScansWhileAssociated = enabled;
1121c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    }
1122c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
1123c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    public int getAllowScansWithTraffic() {
11249f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        return mWifiConfigStore.alwaysEnableScansWhileAssociated;
1125c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle    }
1126c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
1127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    /*
1128f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     *
1129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     * Framework scan control
1130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     */
1131f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
1132f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private boolean mAlarmEnabled = false;
1133f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    /* This is set from the overlay config file or from a secure setting.
1134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     * A value of 0 disables scanning in the framework.
1135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     */
1136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private long mFrameworkScanIntervalMs = 10000;
1137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
11388242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private AtomicInteger mDelayedScanCounter = new AtomicInteger();
11398242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
11408242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private void setScanAlarm(boolean enabled) {
1141f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (PDBG) {
11429f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            loge("setScanAlarm " + enabled
11438242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    + " period " + mDefaultFrameworkScanIntervalMs
11448242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    + " mBackgroundScanSupported " + mBackgroundScanSupported);
11458242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        }
11468242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        if (mBackgroundScanSupported == false) {
11478242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // Scan alarm is only used for background scans if they are not
11488242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // offloaded to the wifi chipset, hence enable the scan alarm
11498242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // gicing us RTC_WAKEUP of backgroundScan is NOT supported
11508242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            enabled = true;
1151f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
11528242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
1153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (enabled == mAlarmEnabled) return;
1154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (enabled) {
11557c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande            /* Set RTC_WAKEUP alarms if PNO is not supported - because no one is */
11567c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande            /* going to wake up the host processor to look for access points */
11578242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            mAlarmManager.set(AlarmManager.RTC_WAKEUP,
11588242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    System.currentTimeMillis() + mDefaultFrameworkScanIntervalMs,
115966f8e08b668ebdc4c9b180f90e71cbb4f3e1c37fvandwalle                    mScanIntent);
116066f8e08b668ebdc4c9b180f90e71cbb4f3e1c37fvandwalle            mAlarmEnabled = true;
1161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        } else {
1162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            mAlarmManager.cancel(mScanIntent);
1163f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            mAlarmEnabled = false;
1164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
1165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
1166f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
11678242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private void cancelDelayedScan() {
11688242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        mDelayedScanCounter.incrementAndGet();
11698242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        loge("cancelDelayedScan -> " + mDelayedScanCounter);
11708242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    }
11718242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
11728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private boolean checkAndRestartDelayedScan(int counter, boolean restart, int milli,
11738242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                   ScanSettings settings, WorkSource workSource) {
11748242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        if (counter != mDelayedScanCounter.get()) {
11758242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            return false;
11768242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        }
11778242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        if (restart)
11788242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            startDelayedScan(milli, settings, workSource);
11798242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        return true;
11808242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    }
11818242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
11828242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private void startDelayedScan(int milli, ScanSettings settings, WorkSource workSource) {
11838242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        if (milli <= 0) return;
11848242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        /**
11858242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         * The cases where the scan alarm should be run are :
11868242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         * - DisconnectedState && screenOn => used delayed timer
11878242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         * - DisconnectedState && !screenOn && mBackgroundScanSupported => PNO
11888242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         * - DisconnectedState && !screenOn && !mBackgroundScanSupported => used RTC_WAKEUP Alarm
11898242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         * - ConnectedState && screenOn => used delayed timer
11908242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         */
11918242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
11928242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        mDelayedScanCounter.incrementAndGet();
11938242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        if (mScreenOn &&
11948242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                (getCurrentState() == mDisconnectedState
11958242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                || getCurrentState() == mConnectedState)) {
11968242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            Bundle bundle = new Bundle();
11978242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, settings);
11988242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource);
11998242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            bundle.putLong(SCAN_REQUEST_TIME, System.currentTimeMillis());
12008242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            sendMessageDelayed(CMD_START_SCAN, SCAN_ALARM_SOURCE,
12018242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    mDelayedScanCounter.get(), bundle, milli);
12028242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            if (DBG) loge("startDelayedScan send -> " + mDelayedScanCounter + " milli " + milli);
12038242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        } else if (mBackgroundScanSupported == false
12048242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                && !mScreenOn && getCurrentState() == mDisconnectedState) {
12058242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            setScanAlarm(true);
12068242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            if (DBG) loge("startDelayedScan start scan alarm -> "
12078242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    + mDelayedScanCounter + " milli " + milli);
12088242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        } else {
12098242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            if (DBG) loge("startDelayedScan unhandled -> "
12108242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    + mDelayedScanCounter + " milli " + milli);
12118242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        }
12128242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    }
12138242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
1214eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande    private boolean setRandomMacOui() {
1215eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        String oui = mContext.getResources().getString(
1216eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande                R.string.config_wifi_random_mac_oui, GOOGLE_OUI);
1217eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        String[] ouiParts = oui.split("-");
1218eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        byte[] ouiBytes = new byte[3];
1219eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        ouiBytes[0] = (byte) (Integer.parseInt(ouiParts[0], 16) & 0xFF);
1220eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        ouiBytes[1] = (byte) (Integer.parseInt(ouiParts[1], 16) & 0xFF);
1221eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        ouiBytes[2] = (byte) (Integer.parseInt(ouiParts[2], 16) & 0xFF);
1222eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande
1223eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        logd("Setting OUI to " + oui);
1224eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande        return mWifiNative.setScanningMacOui(ouiBytes);
1225eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande    }
1226eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande
1227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /*********************************************************
1228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Methods exposed for public use
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     ********************************************************/
1230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public Messenger getMessenger() {
1232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return new Messenger(getHandler());
1233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
12349ae6b45c038fa74a9e7285ef4834551dd93da332Yuhao Zheng
1235511a412adce5a46c41e61f90c0df6de5fb4e491cYuhao Zheng    public WifiMonitor getWifiMonitor() {
12369ae6b45c038fa74a9e7285ef4834551dd93da332Yuhao Zheng        return mWifiMonitor;
12379ae6b45c038fa74a9e7285ef4834551dd93da332Yuhao Zheng    }
12389ae6b45c038fa74a9e7285ef4834551dd93da332Yuhao Zheng
1239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
1241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean syncPingSupplicant(AsyncChannel channel) {
1243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
1244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean result = (resultMsg.arg1 != FAILURE);
1245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
1246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
1247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1249a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    public List<WifiChannel> syncGetChannelList(AsyncChannel channel) {
1250a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CAPABILITY_FREQ);
1251a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        List<WifiChannel> list = null;
1252a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        if (resultMsg.obj != null) {
1253a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            list = new ArrayList<WifiChannel>();
1254a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            String freqs = (String) resultMsg.obj;
1255a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            String[] lines = freqs.split("\n");
1256a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            for (String line : lines)
1257a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                if (line.contains("MHz")) {
1258a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    // line format: " 52 = 5260 MHz (NO_IBSS) (DFS)"
1259a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    WifiChannel c = new WifiChannel();
1260a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    String[] prop = line.split(" ");
1261a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    if (prop.length < 5) continue;
1262a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    try {
1263a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                        c.channelNum = Integer.parseInt(prop[1]);
1264a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                        c.freqMHz = Integer.parseInt(prop[3]);
1265a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    } catch (NumberFormatException e) { }
1266a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    c.isDFS = line.contains("(DFS)");
1267a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    list.add(c);
1268a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                } else if (line.contains("Mode[B] Channels:")) {
1269a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    // B channels are the same as G channels, skipped
1270a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    break;
1271a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                }
1272a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        }
1273a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        resultMsg.recycle();
1274a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        return (list != null && list.size() > 0) ? list : null;
1275a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    }
1276a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1277005c1ef113192f898499a407dd266393a8d6b076vandwalle    /**
1278005c1ef113192f898499a407dd266393a8d6b076vandwalle     * When settings allowing making use of untrusted networks change, trigger a scan
1279005c1ef113192f898499a407dd266393a8d6b076vandwalle     * so as to kick of autojoin.
1280005c1ef113192f898499a407dd266393a8d6b076vandwalle     */
1281005c1ef113192f898499a407dd266393a8d6b076vandwalle    public void startScanForUntrustedSettingChange() {
1282d406991cea796c4b75e484bd0d47a85a0f8a4daeJeff Davidson        startScan(SET_ALLOW_UNTRUSTED_SOURCE, 0, null, null);
1283005c1ef113192f898499a407dd266393a8d6b076vandwalle    }
1284a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1286a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng     * Initiate a wifi scan. If workSource is not null, blame is given to it, otherwise blame is
1287a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng     * given to callingUid.
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1289a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng     * @param callingUid The uid initiating the wifi scan. Blame will be given here unless
1290a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng     *                   workSource is specified.
1291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param workSource If not null, blame is given to workSource.
1292a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng     * @param settings Scan settings, see {@link ScanSettings}.
1293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1294ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    public void startScan(int callingUid, int scanCounter,
1295ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                          ScanSettings settings, WorkSource workSource) {
1296a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        Bundle bundle = new Bundle();
1297a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, settings);
1298a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource);
1299ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        bundle.putLong(SCAN_REQUEST_TIME, System.currentTimeMillis());
1300ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        sendMessage(CMD_START_SCAN, callingUid, scanCounter, bundle);
1301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * start or stop batched scanning using the given settings
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid, int csph,
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WorkSource workSource) {
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Bundle bundle = new Bundle();
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        bundle.putParcelable(BATCHED_SETTING, settings);
1310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        bundle.putParcelable(BATCHED_WORKSOURCE, workSource);
1311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_SET_BATCHED_SCAN, callingUid, csph, bundle);
1312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public List<BatchedScanResult> syncGetBatchedScanResultsList() {
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mBatchedScanResults) {
1316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            List<BatchedScanResult> batchedScanList =
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    new ArrayList<BatchedScanResult>(mBatchedScanResults.size());
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for(BatchedScanResult result: mBatchedScanResults) {
1319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                batchedScanList.add(new BatchedScanResult(result));
1320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return batchedScanList;
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void requestBatchedScanPoll() {
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_POLL_BATCHED_SCAN);
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void startBatchedScan() {
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mBatchedScanSettings == null) return;
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mDhcpActive) {
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) log("not starting Batched Scans due to DHCP");
1334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // first grab any existing data
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        retrieveBatchedScanData();
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1340f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (PDBG) loge("try  starting Batched Scans due to DHCP");
1341f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
1342f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mAlarmManager.cancel(mBatchedScanIntervalIntent);
1344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
1346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
1347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mExpectedBatchedScans = Integer.parseInt(scansExpected);
1348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setNextBatchedAlarm(mExpectedBatchedScans);
1349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mExpectedBatchedScans > 0) noteBatchedScanStart();
1350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (NumberFormatException e) {
1351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            stopBatchedScan();
1352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Exception parsing WifiNative.setBatchedScanSettings response " + e);
1353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // called from BroadcastListener
1357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void startNextBatchedScanAsync() {
1358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_START_NEXT_BATCHED_SCAN);
1359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void startNextBatchedScan() {
1362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // first grab any existing data
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        retrieveBatchedScanData();
1364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setNextBatchedAlarm(mExpectedBatchedScans);
1366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleBatchedScanPollRequest() {
1369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) {
1370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            log("handleBatchedScanPoll Request - mBatchedScanMinPollTime=" +
1371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mBatchedScanMinPollTime + " , mBatchedScanSettings=" +
1372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mBatchedScanSettings);
1373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // if there is no appropriate PollTime that's because we either aren't
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // batching or we've already set a time for a poll request
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mBatchedScanMinPollTime == 0) return;
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mBatchedScanSettings == null) return;
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        long now = System.currentTimeMillis();
1380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (now > mBatchedScanMinPollTime) {
1382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // do the poll and reset our timers
1383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            startNextBatchedScan();
1384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, mBatchedScanMinPollTime,
1386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mBatchedScanIntervalIntent);
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mBatchedScanMinPollTime = 0;
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // return true if new/different
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean recordBatchedScanSettings(int responsibleUid, int csph, Bundle bundle) {
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        BatchedScanSettings settings = bundle.getParcelable(BATCHED_SETTING);
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WorkSource responsibleWorkSource = bundle.getParcelable(BATCHED_WORKSOURCE);
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) {
1397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            log("set batched scan to " + settings + " for uid=" + responsibleUid +
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ", worksource=" + responsibleWorkSource);
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (settings != null) {
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (settings.equals(mBatchedScanSettings)) return false;
1402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mBatchedScanSettings == null) return false;
1404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBatchedScanSettings = settings;
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (responsibleWorkSource == null) responsibleWorkSource = new WorkSource(responsibleUid);
1407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBatchedScanWorkSource = responsibleWorkSource;
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBatchedScanCsph = csph;
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void stopBatchedScan() {
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mAlarmManager.cancel(mBatchedScanIntervalIntent);
1414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        retrieveBatchedScanData();
1415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setBatchedScanSettings(null);
1416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        noteBatchedScanStop();
1417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setNextBatchedAlarm(int scansExpected) {
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mBatchedScanSettings == null || scansExpected < 1) return;
1422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBatchedScanMinPollTime = System.currentTimeMillis() +
1424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatchedScanSettings.scanIntervalSec * 1000;
1425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mBatchedScanSettings.maxScansPerBatch < scansExpected) {
1427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            scansExpected = mBatchedScanSettings.maxScansPerBatch;
1428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int secToFull = mBatchedScanSettings.scanIntervalSec;
1431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        secToFull *= scansExpected;
1432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int debugPeriod = SystemProperties.getInt("wifi.batchedScan.pollPeriod", 0);
1434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (debugPeriod > 0) secToFull = debugPeriod;
1435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // set the alarm to do the next poll.  We set it a little short as we'd rather
1437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // wake up wearly than miss a scan due to buffer overflow
1438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
1439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                + ((secToFull - (mBatchedScanSettings.scanIntervalSec / 2)) * 1000),
1440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatchedScanIntervalIntent);
1441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start reading new scan data
1445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Data comes in as:
1446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * "scancount=5\n"
1447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * "nextcount=5\n"
1448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   "apcount=3\n"
1449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   "trunc\n" (optional)
1450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "bssid=...\n"
1451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "ssid=...\n"
1452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "freq=...\n" (in Mhz)
1453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "level=...\n"
1454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "dist=...\n" (in cm)
1455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "distsd=...\n" (standard deviation, in cm)
1456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "===="
1457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "bssid=...\n"
1458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     etc
1459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "===="
1460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "bssid=...\n"
1461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     etc
1462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "%%%%"
1463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   "apcount=2\n"
1464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "bssid=...\n"
1465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     etc
1466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *     "%%%%
1467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   etc
1468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   "----"
1469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final static boolean DEBUG_PARSE = false;
1471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void retrieveBatchedScanData() {
1472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String rawData = mWifiNative.getBatchedScanResults();
1473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DEBUG_PARSE) log("rawData = " + rawData);
1474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mBatchedScanMinPollTime = 0;
1475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (rawData == null || rawData.equalsIgnoreCase("OK")) {
1476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Unexpected BatchedScanResults :" + rawData);
1477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
1478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int scanCount = 0;
1481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final String END_OF_BATCHES = "----";
1482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final String SCANCOUNT = "scancount=";
1483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final String TRUNCATED = "trunc";
1484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final String AGE = "age=";
1485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final String DIST = "dist=";
1486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final String DISTSD = "distSd=";
1487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String splitData[] = rawData.split("\n");
1489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int n = 0;
1490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (splitData[n].startsWith(SCANCOUNT)) {
1491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
1492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                scanCount = Integer.parseInt(splitData[n++].substring(SCANCOUNT.length()));
1493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (NumberFormatException e) {
1494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("scancount parseInt Exception from " + splitData[n]);
1495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else log("scancount not found");
1497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (scanCount == 0) {
1498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("scanCount==0 - aborting");
1499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
1500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiManager.BATCHED_SCAN_RESULTS_AVAILABLE_ACTION);
1503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mBatchedScanResults) {
1506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mBatchedScanResults.clear();
1507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            BatchedScanResult batchedScanResult = new BatchedScanResult();
1508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String bssid = null;
1510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiSsid wifiSsid = null;
1511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int level = 0;
1512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int freq = 0;
1513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int dist, distSd;
1514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            long tsf = 0;
1515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dist = distSd = ScanResult.UNSPECIFIED;
1516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final long now = SystemClock.elapsedRealtime();
1517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final int bssidStrLen = BSSID_STR.length();
1518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            while (true) {
1520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                while (n < splitData.length) {
1521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DEBUG_PARSE) logd("parsing " + splitData[n]);
1522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (splitData[n].equals(END_OF_BATCHES)) {
1523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (n+1 != splitData.length) {
1524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("didn't consume " + (splitData.length-n));
1525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mBatchedScanResults.size() > 0) {
1527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
1528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        logd("retrieveBatchedScanResults X");
1530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return;
1531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if ((splitData[n].equals(END_STR)) || splitData[n].equals(DELIMITER_STR)) {
1533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (bssid != null) {
1534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            batchedScanResult.scanResults.add(new ScanResult(
1535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    wifiSsid, bssid, "", level, freq, tsf, dist, distSd));
1536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            wifiSsid = null;
1537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            bssid = null;
1538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            level = 0;
1539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            freq = 0;
1540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            tsf = 0;
1541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            dist = distSd = ScanResult.UNSPECIFIED;
1542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (splitData[n].equals(END_STR)) {
1544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (batchedScanResult.scanResults.size() != 0) {
1545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mBatchedScanResults.add(batchedScanResult);
1546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                batchedScanResult = new BatchedScanResult();
1547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            } else {
1548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                logd("Found empty batch");
1549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
1550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].equals(TRUNCATED)) {
1552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        batchedScanResult.truncated = true;
1553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(BSSID_STR)) {
1554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        bssid = new String(splitData[n].getBytes(), bssidStrLen,
1555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                splitData[n].length() - bssidStrLen);
1556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(FREQ_STR)) {
1557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            freq = Integer.parseInt(splitData[n].substring(FREQ_STR.length()));
1559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (NumberFormatException e) {
1560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Invalid freqency: " + splitData[n]);
1561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            freq = 0;
1562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(AGE)) {
1564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            tsf = now - Long.parseLong(splitData[n].substring(AGE.length()));
1566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            tsf *= 1000; // convert mS -> uS
1567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (NumberFormatException e) {
1568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Invalid timestamp: " + splitData[n]);
1569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            tsf = 0;
1570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(SSID_STR)) {
1572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        wifiSsid = WifiSsid.createFromAsciiEncoded(
1573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                splitData[n].substring(SSID_STR.length()));
1574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(LEVEL_STR)) {
1575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            level = Integer.parseInt(splitData[n].substring(LEVEL_STR.length()));
1577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (level > 0) level -= 256;
1578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (NumberFormatException e) {
1579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Invalid level: " + splitData[n]);
1580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            level = 0;
1581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(DIST)) {
1583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            dist = Integer.parseInt(splitData[n].substring(DIST.length()));
1585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (NumberFormatException e) {
1586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Invalid distance: " + splitData[n]);
1587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            dist = ScanResult.UNSPECIFIED;
1588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (splitData[n].startsWith(DISTSD)) {
1590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            distSd = Integer.parseInt(splitData[n].substring(DISTSD.length()));
1592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (NumberFormatException e) {
1593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Invalid distanceSd: " + splitData[n]);
1594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            distSd = ScanResult.UNSPECIFIED;
1595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unable to parse batched scan result line: " + splitData[n]);
1598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    n++;
1600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                rawData = mWifiNative.getBatchedScanResults();
1602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DEBUG_PARSE) log("reading more data:\n" + rawData);
1603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (rawData == null) {
1604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unexpected null BatchedScanResults");
1605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return;
1606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                splitData = rawData.split("\n");
1608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (splitData.length == 0 || splitData[0].equals("ok")) {
1609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("batch scan results just ended!");
1610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mBatchedScanResults.size() > 0) {
1611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return;
1614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                n = 0;
1616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
16200eebae7334d6129f7ca1344e4b20199794994358vandwalle    private long mDisconnectedTimeStamp = 0;
16210eebae7334d6129f7ca1344e4b20199794994358vandwalle
16220eebae7334d6129f7ca1344e4b20199794994358vandwalle    public long getDisconnectedTimeMilli() {
16230eebae7334d6129f7ca1344e4b20199794994358vandwalle        if (getCurrentState() == mDisconnectedState
16240eebae7334d6129f7ca1344e4b20199794994358vandwalle                && mDisconnectedTimeStamp != 0) {
16250eebae7334d6129f7ca1344e4b20199794994358vandwalle            long now_ms = System.currentTimeMillis();
16260eebae7334d6129f7ca1344e4b20199794994358vandwalle            return now_ms - mDisconnectedTimeStamp;
16270eebae7334d6129f7ca1344e4b20199794994358vandwalle        }
16280eebae7334d6129f7ca1344e4b20199794994358vandwalle        return 0;
16290eebae7334d6129f7ca1344e4b20199794994358vandwalle    }
16300eebae7334d6129f7ca1344e4b20199794994358vandwalle
1631ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    // Keeping track of scan requests
1632b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle    private long lastStartScanTimeStamp = 0;
1633b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle    private long lastScanDuration = 0;
1634ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    // Last connect attempt is used to prevent scan requests:
1635ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    //  - for a period of 10 seconds after attempting to connect
1636b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle    private long lastConnectAttempt = 0;
1637b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle    private String lastScanFreqs = null;
1638b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle
1639ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    // For debugging, keep track of last message status handling
1640ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    // TODO, find an equivalent mechanism as part of parent class
16412f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    private static int MESSAGE_HANDLING_STATUS_PROCESSED = 2;
1642ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_OK = 1;
1643ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_UNKNOWN = 0;
1644ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_REFUSED = -1;
1645ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_FAIL = -2;
16468242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private static int MESSAGE_HANDLING_STATUS_OBSOLETE = -3;
1647ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_DEFERRED = -4;
1648ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_DISCARD = -5;
1649ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_LOOPED = -6;
1650ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private static int MESSAGE_HANDLING_STATUS_HANDLING_ERROR = -7;
1651ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle
1652ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private int messageHandlingStatus = 0;
1653ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle
1654b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle    //TODO: this is used only to track connection attempts, however the link state and packet per
1655b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle    //TODO: second logic should be folded into that
16568242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle    private boolean checkOrDeferScanAllowed(Message msg) {
1657b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        long now = System.currentTimeMillis();
1658b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        if (lastConnectAttempt != 0 && (now - lastConnectAttempt) < 10000) {
16598242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            Message dmsg = Message.obtain(msg);
16608242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            sendMessageDelayed(dmsg, 11000 - (now - lastConnectAttempt));
1661b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            return false;
1662b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        }
1663b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        return true;
1664b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle    }
1665b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle
16660eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mOnTime = 0;
16670eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mTxTime = 0;
16680eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mRxTime = 0;
16697b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mOnTimeStartScan = 0;
16707b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mTxTimeStartScan = 0;
16717b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mRxTimeStartScan = 0;
16720eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mOnTimeScan = 0;
16730eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mTxTimeScan = 0;
16740eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mRxTimeScan = 0;
16750eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mOnTimeThisScan = 0;
16760eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mTxTimeThisScan = 0;
16770eebae7334d6129f7ca1344e4b20199794994358vandwalle    private int mRxTimeThisScan = 0;
16780eebae7334d6129f7ca1344e4b20199794994358vandwalle
16797b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mOnTimeScreenStateChange = 0;
16807b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mOnTimeAtLastReport = 0;
16817b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private long lastOntimeReportTimeStamp = 0;
16827b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private long lastScreenStateChangeTimeStamp = 0;
16837b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mOnTimeLastReport = 0;
16847b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mTxTimeLastReport = 0;
16857b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private int mRxTimeLastReport = 0;
16867b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
16877b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    private long lastLinkLayerStatsUpdate = 0;
16887b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
16897b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    String reportOnTime() {
16907b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        long now = System.currentTimeMillis();
16917b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        StringBuilder sb = new StringBuilder();
16927b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        // Report stats since last report
16937b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        int on = mOnTime - mOnTimeLastReport;
16947b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        mOnTimeLastReport = mOnTime;
16957b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        int tx = mTxTime - mTxTimeLastReport;
16967b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        mTxTimeLastReport = mTxTime;
16977b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        int rx = mRxTime - mRxTimeLastReport;
16987b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        mRxTimeLastReport = mRxTime;
16997b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        int period = (int)(now - lastOntimeReportTimeStamp);
17007b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        lastOntimeReportTimeStamp = now;
17017b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format("[on:%d tx:%d rx:%d period:%d]", on, tx, rx, period));
17027b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        // Report stats since Screen State Changed
17037b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        on = mOnTime - mOnTimeScreenStateChange;
17047b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        period = (int)(now - lastScreenStateChangeTimeStamp);
17057b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(" from screen [on:%d period:%d]", on, period));
17067b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        return sb.toString();
17070eebae7334d6129f7ca1344e4b20199794994358vandwalle    }
17080eebae7334d6129f7ca1344e4b20199794994358vandwalle
17097b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    WifiLinkLayerStats getWifiLinkLayerStats(boolean dbg) {
17107b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        WifiLinkLayerStats stats = null;
17110eebae7334d6129f7ca1344e4b20199794994358vandwalle        if (mWifiLinkLayerStatsSupported > 0) {
17120eebae7334d6129f7ca1344e4b20199794994358vandwalle            String name = "wlan0";
17137b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            stats = mWifiNative.getWifiLinkLayerStats(name);
17140eebae7334d6129f7ca1344e4b20199794994358vandwalle            if (name != null && stats == null && mWifiLinkLayerStatsSupported > 0) {
17150eebae7334d6129f7ca1344e4b20199794994358vandwalle                mWifiLinkLayerStatsSupported -= 1;
17160eebae7334d6129f7ca1344e4b20199794994358vandwalle            } else if (stats != null) {
17177b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                lastLinkLayerStatsUpdate = System.currentTimeMillis();
17180eebae7334d6129f7ca1344e4b20199794994358vandwalle                mOnTime = stats.on_time;
17190eebae7334d6129f7ca1344e4b20199794994358vandwalle                mTxTime = stats.tx_time;
17200eebae7334d6129f7ca1344e4b20199794994358vandwalle                mRxTime = stats.rx_time;
1721dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                mRunningBeaconCount = stats.beacon_rx;
17227b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (dbg) {
17237b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    loge(stats.toString());
17247b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                }
17250eebae7334d6129f7ca1344e4b20199794994358vandwalle            }
17260eebae7334d6129f7ca1344e4b20199794994358vandwalle        }
1727efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle        if (stats == null || mWifiLinkLayerStatsSupported <= 0) {
1728efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle            long mTxPkts = TrafficStats.getTxPackets(mInterfaceName);
1729efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle            long mRxPkts = TrafficStats.getRxPackets(mInterfaceName);
1730efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle            mWifiInfo.updatePacketRates(mTxPkts, mRxPkts);
1731efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle        } else {
1732efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle            mWifiInfo.updatePacketRates(stats);
1733efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle        }
17347b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        return stats;
17357b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    }
17367b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
17377b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    void startRadioScanStats() {
17387b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        WifiLinkLayerStats stats = getWifiLinkLayerStats(false);
17397b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (stats != null) {
17407b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mOnTimeStartScan = stats.on_time;
17417b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mTxTimeStartScan = stats.tx_time;
17427b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mRxTimeStartScan = stats.rx_time;
17437b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mOnTime = stats.on_time;
17447b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mTxTime = stats.tx_time;
17457b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mRxTime = stats.rx_time;
17467b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        }
17477b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    }
17487b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
17497b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    void closeRadioScanStats() {
17507b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        WifiLinkLayerStats stats = getWifiLinkLayerStats(false);
17517b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (stats != null) {
17527b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mOnTimeThisScan = stats.on_time - mOnTimeStartScan;
17537b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mTxTimeThisScan = stats.tx_time - mTxTimeStartScan;
17547b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mRxTimeThisScan = stats.rx_time - mRxTimeStartScan;
17557b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mOnTimeScan += mOnTimeThisScan;
17567b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mTxTimeScan += mTxTimeThisScan;
17577b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mRxTimeScan += mRxTimeThisScan;
17587b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        }
17590eebae7334d6129f7ca1344e4b20199794994358vandwalle    }
17600eebae7334d6129f7ca1344e4b20199794994358vandwalle
1761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // If workSource is not null, blame is given to it, otherwise blame is given to callingUid.
1762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void noteScanStart(int callingUid, WorkSource workSource) {
1763b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        long now = System.currentTimeMillis();
1764b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        lastStartScanTimeStamp = now;
1765b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        lastScanDuration = 0;
1766f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) {
1767b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            String ts = String.format("[%,d ms]", now);
1768f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (workSource != null) {
1769f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                loge(ts + " noteScanStart" + workSource.toString()
1770f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        + " uid " + Integer.toString(callingUid));
1771f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            } else {
17728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                loge(ts + " noteScanstart no scan source"
17738242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        + " uid " + Integer.toString(callingUid));
1774f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
1775f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
17767b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        startRadioScanStats();
1777b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        if (mScanWorkSource == null && ((callingUid != UNKNOWN_SCAN_SOURCE
1778b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                && callingUid != SCAN_ALARM_SOURCE)
17794dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                || workSource != null)) {
1780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mScanWorkSource = workSource != null ? workSource : new WorkSource(callingUid);
1781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
1782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiScanStartedFromSource(mScanWorkSource);
1783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException e) {
1784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                log(e.toString());
1785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void noteScanEnd() {
1790b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle        long now = System.currentTimeMillis();
1791b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        if (lastStartScanTimeStamp != 0) {
1792b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            lastScanDuration = now - lastStartScanTimeStamp;
1793b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        }
1794b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        lastStartScanTimeStamp = 0;
1795f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) {
1796b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            String ts = String.format("[%,d ms]", now);
1797f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (mScanWorkSource != null)
17988242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                loge(ts + " noteScanEnd " + mScanWorkSource.toString()
17998242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        + " onTime=" + mOnTimeThisScan);
1800f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            else
18018242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                loge(ts + " noteScanEnd no scan source"
18028242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        + " onTime=" + mOnTimeThisScan);
1803f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
1804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mScanWorkSource != null) {
1805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
1806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiScanStoppedFromSource(mScanWorkSource);
1807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException e) {
1808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                log(e.toString());
1809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } finally {
1810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mScanWorkSource = null;
1811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void noteBatchedScanStart() {
1816f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (PDBG) loge("noteBatchedScanstart()");
1817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // note the end of a previous scan set
1818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mNotedBatchedScanWorkSource != null &&
1819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                (mNotedBatchedScanWorkSource.equals(mBatchedScanWorkSource) == false ||
1820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 mNotedBatchedScanCsph != mBatchedScanCsph)) {
1821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
1822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiBatchedScanStoppedFromSource(mNotedBatchedScanWorkSource);
1823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException e) {
1824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                log(e.toString());
1825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } finally {
1826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mNotedBatchedScanWorkSource = null;
1827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mNotedBatchedScanCsph = 0;
1828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // note the start of the new
1831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
1832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mBatteryStats.noteWifiBatchedScanStartedFromSource(mBatchedScanWorkSource,
1833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mBatchedScanCsph);
1834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNotedBatchedScanWorkSource = mBatchedScanWorkSource;
1835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNotedBatchedScanCsph = mBatchedScanCsph;
1836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (RemoteException e) {
1837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            log(e.toString());
1838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void noteBatchedScanStop() {
1842f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (PDBG) loge("noteBatchedScanstop()");
1843f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
1844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mNotedBatchedScanWorkSource != null) {
1845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
1846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiBatchedScanStoppedFromSource(mNotedBatchedScanWorkSource);
1847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException e) {
1848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                log(e.toString());
1849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } finally {
1850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mNotedBatchedScanWorkSource = null;
1851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mNotedBatchedScanCsph = 0;
1852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1856a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private void handleScanRequest(int type, Message message) {
185712ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle        ScanSettings settings = null;
185812ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle        WorkSource workSource = null;
185912ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle
1860a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        // unbundle parameters
1861a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        Bundle bundle = (Bundle) message.obj;
186212ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle
186312ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle        if (bundle != null) {
186412ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle            settings = bundle.getParcelable(CUSTOMIZED_SCAN_SETTING);
186512ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle            workSource = bundle.getParcelable(CUSTOMIZED_SCAN_WORKSOURCE);
186612ecdb7b85152b47a5469f0942f3e9d811d6d90bvandwalle        }
1867a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1868a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        // parse scan settings
1869a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        String freqs = null;
1870a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        if (settings != null && settings.channelSet != null) {
1871a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            StringBuilder sb = new StringBuilder();
1872a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            boolean first = true;
1873a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            for (WifiChannel channel : settings.channelSet) {
1874a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                if (!first) sb.append(','); else first = false;
1875a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                sb.append(channel.freqMHz);
1876a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            }
1877a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            freqs = sb.toString();
1878a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        }
1879a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1880a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        // call wifi native to start the scan
1881a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        if (startScanNative(type, freqs)) {
1882a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            // only count battery consumption if scan request is accepted
1883a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            noteScanStart(message.arg1, workSource);
1884a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            // a full scan covers everything, clearing scan request buffer
1885a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            if (freqs == null)
1886a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                mBufferedScanMsg.clear();
1887ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK;
18889086afccf6938a49eb9a2cd248917c1cb0943942vandwalle            if (workSource != null) {
18899086afccf6938a49eb9a2cd248917c1cb0943942vandwalle                // External worksource was passed along the scan request,
18909086afccf6938a49eb9a2cd248917c1cb0943942vandwalle                // hence always send a broadcast
18919086afccf6938a49eb9a2cd248917c1cb0943942vandwalle                mSendScanResultsBroadcast = true;
18929086afccf6938a49eb9a2cd248917c1cb0943942vandwalle            }
1893a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            return;
1894a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        }
1895a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1896a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        // if reach here, scan request is rejected
1897a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1898a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        if (!mIsScanOngoing) {
1899a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            // if rejection is NOT due to ongoing scan (e.g. bad scan parameters),
1900ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle
1901a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            // discard this request and pop up the next one
1902ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            if (mBufferedScanMsg.size() > 0) {
1903a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                sendMessage(mBufferedScanMsg.remove());
1904ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            }
1905ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
1906a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        } else if (!mIsFullScanOngoing) {
1907a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            // if rejection is due to an ongoing scan, and the ongoing one is NOT a full scan,
1908a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            // buffer the scan request to make sure specified channels will be scanned eventually
1909a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            if (freqs == null)
1910a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                mBufferedScanMsg.clear();
1911a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            if (mBufferedScanMsg.size() < SCAN_REQUEST_BUFFER_MAX_SIZE) {
1912ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                Message msg = obtainMessage(CMD_START_SCAN,
1913ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        message.arg1, message.arg2, bundle);
1914a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                mBufferedScanMsg.add(msg);
1915a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            } else {
1916a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                // if too many requests in buffer, combine them into a single full scan
1917a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                bundle = new Bundle();
1918a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, null);
1919a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource);
1920ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                Message msg = obtainMessage(CMD_START_SCAN, message.arg1, message.arg2, bundle);
1921a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                mBufferedScanMsg.clear();
1922a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                mBufferedScanMsg.add(msg);
1923a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            }
1924ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            messageHandlingStatus = MESSAGE_HANDLING_STATUS_LOOPED;
1925ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        } else {
1926ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            // mIsScanOngoing and mIsFullScanOngoing
1927ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
1928a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        }
1929a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    }
1930a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1931a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng
1932a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    /** return true iff scan request is accepted */
1933a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng    private boolean startScanNative(int type, String freqs) {
1934a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        if (mWifiNative.scan(type, freqs)) {
1935a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            mIsScanOngoing = true;
1936a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            mIsFullScanOngoing = (freqs == null);
1937b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            lastScanFreqs = freqs;
1938a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            return true;
1939a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        }
1940a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng        return false;
1941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
1945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setSupplicantRunning(boolean enable) {
1947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enable) {
1948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessage(CMD_START_SUPPLICANT);
1949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessage(CMD_STOP_SUPPLICANT);
1951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
1956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) {
1958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enable) {
1959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessage(CMD_START_AP, wifiConfig);
1960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessage(CMD_STOP_AP);
1962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setWifiApConfiguration(WifiConfiguration config) {
1966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
1967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public WifiConfiguration syncGetWifiApConfiguration() {
1970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = mWifiApConfigChannel.sendMessageSynchronously(CMD_REQUEST_AP_CONFIG);
1971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiConfiguration ret = (WifiConfiguration) resultMsg.obj;
1972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
1973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return ret;
1974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
1978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int syncGetWifiState() {
1980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mWifiState.get();
1981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
1985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String syncGetWifiStateByName() {
1987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (mWifiState.get()) {
1988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_STATE_DISABLING:
1989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "disabling";
1990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_STATE_DISABLED:
1991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "disabled";
1992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_STATE_ENABLING:
1993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "enabling";
1994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_STATE_ENABLED:
1995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "enabled";
1996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_STATE_UNKNOWN:
1997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "unknown state";
1998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
1999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "[invalid state]";
2000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
2005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int syncGetWifiApState() {
2007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mWifiApState.get();
2008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
2012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String syncGetWifiApStateByName() {
2014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (mWifiApState.get()) {
2015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_AP_STATE_DISABLING:
2016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "disabling";
2017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_AP_STATE_DISABLED:
2018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "disabled";
2019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_AP_STATE_ENABLING:
2020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "enabling";
2021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_AP_STATE_ENABLED:
2022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "enabled";
2023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WIFI_AP_STATE_FAILED:
2024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "failed";
2025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
2026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return "[invalid state]";
2027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Get status information for the current connection, if any.
2032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return a {@link WifiInfo} object containing information about the current connection
2033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public WifiInfo syncRequestConnectionInfo() {
2036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mWifiInfo;
2037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public DhcpResults syncGetDhcpResults() {
2040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mDhcpResultsLock) {
2041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return new DhcpResults(mDhcpResults);
2042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
2047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setDriverStart(boolean enable) {
2049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enable) {
2050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessage(CMD_START_DRIVER);
2051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
2052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessage(CMD_STOP_DRIVER);
2053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
2058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setOperationalMode(int mode) {
2060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) log("setting operational mode to " + String.valueOf(mode));
2061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0);
2062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: doc
2066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public List<ScanResult> syncGetScanResultsList() {
2068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mScanResultCache) {
2069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            List<ScanResult> scanList = new ArrayList<ScanResult>();
2070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for(ScanResult result: mScanResults) {
2071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                scanList.add(new ScanResult(result));
2072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return scanList;
2074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
20772ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle    public void disableEphemeralNetwork(String SSID) {
20782ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle        if (SSID != null) {
20792ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle            sendMessage(CMD_DISABLE_EPHEMERAL_NETWORK, SSID);
20802ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle        }
20812ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle    }
20822ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle
2083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2084e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle     * Get unsynchronized pointer to scan result list
2085e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle     * Can be called only from AutoJoinController which runs in the WifiStateMachine context
2086e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle     */
2087e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    public List<ScanResult> getScanResultsListNoCopyUnsync() {
2088e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        return mScanResults;
2089e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    }
2090e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
2091e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    /**
2092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Disconnect from Access Point
2093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void disconnectCommand() {
2095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_DISCONNECT);
2096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2098f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle    public void disconnectCommand(int uid, int reason) {
2099f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle        sendMessage(CMD_DISCONNECT, uid, reason);
2100f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle    }
2101f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle
2102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Initiate a reconnection to AP
2104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void reconnectCommand() {
2106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_RECONNECT);
2107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Initiate a re-association to AP
2111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void reassociateCommand() {
2113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_REASSOCIATE);
2114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Reload networks and then reconnect; helps load correct data for TLS networks
2118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void reloadTlsNetworksAndReconnect() {
2121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_RELOAD_TLS_AND_RECONNECT);
2122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Add a network synchronously
2126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return network id of the new network
2128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
2130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
2131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int result = resultMsg.arg1;
2132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
2133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
2134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2136a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    /**
2137a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande     * Get configured networks synchronously
2138a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande     * @param channel
2139a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande     * @return
2140a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande     */
2141a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande
214282199a285f4a45a46b44eb8253999aa918534753vandwalle    public List<WifiConfiguration> syncGetConfiguredNetworks(int uuid, AsyncChannel channel) {
214382199a285f4a45a46b44eb8253999aa918534753vandwalle        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONFIGURED_NETWORKS, uuid);
2144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
2145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
2146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
2147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
21499878c61bbd81176561991be025af44efc67332feWenchao Tong    public List<WifiConfiguration> syncGetPrivilegedConfiguredNetwork(AsyncChannel channel) {
21509878c61bbd81176561991be025af44efc67332feWenchao Tong        Message resultMsg = channel.sendMessageSynchronously(
21519878c61bbd81176561991be025af44efc67332feWenchao Tong                CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS);
21529878c61bbd81176561991be025af44efc67332feWenchao Tong        List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
21539878c61bbd81176561991be025af44efc67332feWenchao Tong        resultMsg.recycle();
21549878c61bbd81176561991be025af44efc67332feWenchao Tong        return result;
21559878c61bbd81176561991be025af44efc67332feWenchao Tong    }
21569878c61bbd81176561991be025af44efc67332feWenchao Tong
2157c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle
2158c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    /**
2159c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle     * Get connection statistics synchronously
2160c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle     * @param channel
2161c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle     * @return
2162c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle     */
2163c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle
2164c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    public WifiConnectionStatistics syncGetConnectionStatistics(AsyncChannel channel) {
2165c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONNECTION_STATISTICS);
2166c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle        WifiConnectionStatistics result = (WifiConnectionStatistics) resultMsg.obj;
2167c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle        resultMsg.recycle();
2168c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle        return result;
2169c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle    }
2170c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle
2171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2172a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande     * Get adaptors synchronously
2173a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande     */
2174a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande
2175048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande    public int syncGetSupportedFeatures(AsyncChannel channel) {
2176048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_SUPPORTED_FEATURES);
2177048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande        int supportedFeatureSet = resultMsg.arg1;
2178a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande        resultMsg.recycle();
2179048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande        return supportedFeatureSet;
2180a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2181a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande
2182a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    /**
2183200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle     * Get link layers stats for adapter synchronously
2184200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle     */
2185048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande    public WifiLinkLayerStats syncGetLinkLayerStats(AsyncChannel channel) {
2186048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_LINK_LAYER_STATS);
2187200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        WifiLinkLayerStats result = (WifiLinkLayerStats) resultMsg.obj;
2188200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        resultMsg.recycle();
2189200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        return result;
2190200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    }
2191200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle
2192200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    /**
2193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Delete a network
2194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param networkId id of the network to be removed
2196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
2198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
2199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean result = (resultMsg.arg1 != FAILURE);
2200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
2201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
2202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable a network
2206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param netId network id of the network
2208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param disableOthers true, if all other networks have to be disabled
2209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeds, {@code false} otherwise
2210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
2212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
2213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                disableOthers ? 1 : 0);
2214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean result = (resultMsg.arg1 != FAILURE);
2215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
2216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
2217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Disable a network
2221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param netId network id of the network
2223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeds, {@code false} otherwise
2224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
2226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(WifiManager.DISABLE_NETWORK, netId);
2227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean result = (resultMsg.arg1 != WifiManager.DISABLE_NETWORK_FAILED);
2228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
2229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
2230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
22333f7ef65ab71619040032aee96b5599849881d6fdAndres Morales     * Retrieves a WPS-NFC configuration token for the specified network
22343f7ef65ab71619040032aee96b5599849881d6fdAndres Morales     * @return a hex string representation of the WPS-NFC configuration token
22353f7ef65ab71619040032aee96b5599849881d6fdAndres Morales     */
22363f7ef65ab71619040032aee96b5599849881d6fdAndres Morales    public String syncGetWpsNfcConfigurationToken(int netId) {
22373f7ef65ab71619040032aee96b5599849881d6fdAndres Morales        return mWifiNative.getNfcWpsConfigurationToken(netId);
22383f7ef65ab71619040032aee96b5599849881d6fdAndres Morales    }
22393f7ef65ab71619040032aee96b5599849881d6fdAndres Morales
2240cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande    void enableBackgroundScan(boolean enable) {
2241cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande        if (enable) {
2242cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande            mWifiConfigStore.enableAllNetworks();
2243cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande        }
2244cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande        mWifiNative.enableBackgroundScan(enable);
2245cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande    }
2246cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande
22473f7ef65ab71619040032aee96b5599849881d6fdAndres Morales    /**
2248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Blacklist a BSSID. This will avoid the AP if there are
2249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * alternate APs to connect
2250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param bssid BSSID of the network
2252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void addToBlacklist(String bssid) {
2254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_BLACKLIST_NETWORK, bssid);
2255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Clear the blacklist list
2259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void clearBlacklist() {
2262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_CLEAR_BLACKLIST);
2263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void enableRssiPolling(boolean enabled) {
2266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       sendMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0);
2267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void enableAllNetworks() {
2270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_ENABLE_ALL_NETWORKS);
2271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering Multicast v4 packets
2275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void startFilteringMulticastV4Packets() {
2277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mFilteringMulticastV4Packets.set(true);
2278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_START_PACKET_FILTERING, MULTICAST_V4, 0);
2279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering Multicast v4 packets
2283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void stopFilteringMulticastV4Packets() {
2285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mFilteringMulticastV4Packets.set(false);
2286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V4, 0);
2287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering Multicast v4 packets
2291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void startFilteringMulticastV6Packets() {
2293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_START_PACKET_FILTERING, MULTICAST_V6, 0);
2294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering Multicast v4 packets
2298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void stopFilteringMulticastV6Packets() {
2300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V6, 0);
2301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Set high performance mode of operation.
2305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enabling would set active power mode and disable suspend optimizations;
2306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * disabling would set auto power mode and enable suspend optimizations
2307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param enable true if enable, false otherwise
2308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setHighPerfModeEnabled(boolean enable) {
2310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0);
2311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Set the country code
2315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param countryCode following ISO 3166 format
2316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param persist {@code true} if the setting should be remembered.
2317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setCountryCode(String countryCode, boolean persist) {
2319f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde        // If it's a good country code, apply after the current
2320f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde        // wifi connection is terminated; ignore resetting of code
2321f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde        // for now (it is unclear what the chipset should do when
2322f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde        // country code is reset)
23239c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt        int countryCodeSequence = mCountryCodeSequence.incrementAndGet();
23249c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt        if (TextUtils.isEmpty(countryCode)) {
2325f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde            log("Ignoring resetting of country code");
23269c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt        } else {
23279c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt            sendMessage(CMD_SET_COUNTRY_CODE, countryCodeSequence, persist ? 1 : 0, countryCode);
2328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Set the operational frequency band
2333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param band
2334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param persist {@code true} if the setting should be remembered.
2335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setFrequencyBand(int band, boolean persist) {
2337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (persist) {
2338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Settings.Global.putInt(mContext.getContentResolver(),
2339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Settings.Global.WIFI_FREQUENCY_BAND,
2340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    band);
2341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_SET_FREQUENCY_BAND, band, 0);
2343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable TDLS for a specific MAC address
2347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void enableTdls(String remoteMacAddress, boolean enable) {
2349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int enabler = enable ? 1 : 0;
2350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_ENABLE_TDLS, enabler, 0, remoteMacAddress);
2351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Returns the operational frequency band
2355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int getFrequencyBand() {
2357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mFrequencyBand.get();
2358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Returns the wifi configuration file
2362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String getConfigFile() {
2364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mWifiConfigStore.getConfigFile();
2365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Send a message indicating bluetooth adapter connection state changed
2369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void sendBluetoothAdapterStateChange(int state) {
2371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0);
2372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Save configuration on supplicant
2376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeds, {@code false} otherwise
2378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: deprecate this
2380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean syncSaveConfig(AsyncChannel channel) {
2382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
2383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean result = (resultMsg.arg1 != FAILURE);
2384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resultMsg.recycle();
2385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return result;
2386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void updateBatteryWorkSource(WorkSource newSource) {
2389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mRunningWifiUids) {
2390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
2391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (newSource != null) {
2392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mRunningWifiUids.set(newSource);
2393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (mIsRunning) {
2395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mReportedRunning) {
2396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // If the work source has changed since last time, need
2397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // to remove old work from battery stats.
2398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
2399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
2400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    mRunningWifiUids);
2401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mLastRunningWifiUids.set(mRunningWifiUids);
2402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Now being started, report it.
2405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
2406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mLastRunningWifiUids.set(mRunningWifiUids);
2407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mReportedRunning = true;
2408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
2410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mReportedRunning) {
2411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Last reported we were running, time to stop.
2412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
2413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mLastRunningWifiUids.clear();
2414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mReportedRunning = false;
2415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWakeLock.setWorkSource(newSource);
2418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException ignore) {
2419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        super.dump(fd, pw, args);
2426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mSupplicantStateTracker.dump(fd, pw, args);
2427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mLinkProperties " + mLinkProperties);
2428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mWifiInfo " + mWifiInfo);
2429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mDhcpResults " + mDhcpResults);
2430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mNetworkInfo " + mNetworkInfo);
2431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mLastSignalLevel " + mLastSignalLevel);
2432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mLastBssid " + mLastBssid);
2433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mLastNetworkId " + mLastNetworkId);
2434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mOperationalMode " + mOperationalMode);
2435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mUserWantsSuspendOpt " + mUserWantsSuspendOpt);
2436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
243799d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        pw.println("Supplicant status " + mWifiNative.status(true));
2438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mEnableBackgroundScan " + mEnableBackgroundScan);
2439f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde        pw.println("mLastSetCountryCode " + mLastSetCountryCode);
2440f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde        pw.println("mPersistedCountryCode " + mPersistedCountryCode);
24410af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti        mNetworkFactory.dump(fd, pw, args);
2442ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        mUntrustedNetworkFactory.dump(fd, pw, args);
2443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println();
2444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiConfigStore.dump(fd, pw, args);
2445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /*********************************************************
2448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Internal private functions
2449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     ********************************************************/
2450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2451f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private void logStateAndMessage(Message message, String state) {
2452ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        messageHandlingStatus = 0;
2453f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (mLogMessages) {
2454f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            //long now = SystemClock.elapsedRealtimeNanos();
2455f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            //String ts = String.format("[%,d us]", now/1000);
2456f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
2457b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            loge( " " + state + " " + getLogRecString(message));
2458f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
2459f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
2460f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
2461b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle    /**
2462b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle     * helper, prints the milli time since boot wi and w/o suspended time
2463b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle     */
2464b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle    String printTime() {
2465b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle        StringBuilder sb = new StringBuilder();
2466b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle        sb.append(" rt=").append(SystemClock.uptimeMillis());
2467b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle        sb.append("/").append(SystemClock.elapsedRealtime());
2468b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle        return sb.toString();
2469b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle    }
2470b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle
2471b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle    /**
2472b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle     * Return the additional string to be logged by LogRec, default
2473b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle     *
2474b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle     * @param msg that was processed
2475b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle     * @return information to be logged as a String
2476b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle     */
2477b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle    protected String getLogRecString(Message msg) {
2478b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        WifiConfiguration config;
2479ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        Long now;
24807b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        String report;
24818242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        String key;
2482b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        StringBuilder sb = new StringBuilder();
2483b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        if (mScreenOn) {
2484b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            sb.append("!");
2485b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        }
2486ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        if (messageHandlingStatus != MESSAGE_HANDLING_STATUS_UNKNOWN) {
2487ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            sb.append("(").append(messageHandlingStatus).append(")");
2488ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        }
2489b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        sb.append(smToString(msg));
24907b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (msg.sendingUid > 0 && msg.sendingUid != Process.WIFI_UID) {
24912f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            sb.append(" uid=" + msg.sendingUid);
24922f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        }
2493b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        switch (msg.what) {
2494b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_START_SCAN:
2495ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                now = System.currentTimeMillis();
2496b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2497b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2498b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2499b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2500ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                sb.append(" ic=");
250182199a285f4a45a46b44eb8253999aa918534753vandwalle                sb.append(Integer.toString(sScanAlarmIntentCount));
2502ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                if (msg.obj != null) {
2503ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    Bundle bundle = (Bundle)msg.obj;
2504ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    Long request = bundle.getLong(SCAN_REQUEST_TIME, 0);
2505ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    if (request != 0) {
2506ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        sb.append(" proc(ms):").append(now - request);
2507ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    }
2508ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                }
2509b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (mIsScanOngoing) sb.append(" onGoing");
2510b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (mIsFullScanOngoing) sb.append(" full");
2511b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (lastStartScanTimeStamp != 0) {
2512b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" started:").append(lastStartScanTimeStamp);
2513ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    sb.append(",").append(now - lastStartScanTimeStamp);
2514b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2515b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (lastScanDuration != 0) {
2516b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" dur:").append(lastScanDuration);
2517b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
25188242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                sb.append(" cnt=").append(mDelayedScanCounter);
2519b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" rssi=").append(mWifiInfo.getRssi());
2520b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" f=").append(mWifiInfo.getFrequency());
2521b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" sc=").append(mWifiInfo.score);
2522b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" link=").append(mWifiInfo.getLinkSpeed());
2523b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" tx=%.1f,", mWifiInfo.txSuccessRate));
2524b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" %.1f,", mWifiInfo.txRetriesRate));
2525b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" %.1f ", mWifiInfo.txBadRate));
2526b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" rx=%.1f", mWifiInfo.rxSuccessRate));
2527e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                if (lastScanFreqs != null) {
2528e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                    sb.append(" list=").append(lastScanFreqs);
2529e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                } else {
2530e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                    sb.append(" fiv=").append(fullBandConnectedTimeIntervalMilli);
2531e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                }
25327b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                report = reportOnTime();
25337b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (report != null) {
25347b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" ").append(report);
25357b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                }
2536b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2537b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
2538b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2539b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2540b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2541b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2542b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2543b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
2544b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (stateChangeResult != null) {
2545b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(stateChangeResult.toString());
2546b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2547b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2548be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case WifiManager.SAVE_NETWORK:
2549be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case WifiStateMachine.CMD_AUTO_SAVE_NETWORK:
2550be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2551be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg1));
2552be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2553be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg2));
2554be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                if (lastSavedConfigurationAttempt != null) {
2555be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" ").append(lastSavedConfigurationAttempt.configKey());
2556be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" nid=").append(lastSavedConfigurationAttempt.networkId);
2557be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastSavedConfigurationAttempt.hiddenSSID) {
2558be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" hidden");
2559be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2560b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    if (lastSavedConfigurationAttempt.preSharedKey != null
2561b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                            && !lastSavedConfigurationAttempt.preSharedKey.equals("*")) {
2562be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" hasPSK");
2563be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2564be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastSavedConfigurationAttempt.ephemeral) {
2565be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" ephemeral");
2566be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2567be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastSavedConfigurationAttempt.selfAdded) {
2568be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" selfAdded");
2569be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2570be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" cuid=").append(lastSavedConfigurationAttempt.creatorUid);
2571be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" suid=").append(lastSavedConfigurationAttempt.lastUpdateUid);
2572be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                }
2573be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                break;
2574be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case WifiManager.FORGET_NETWORK:
2575be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2576be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg1));
2577be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2578be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg2));
2579be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                if (lastForgetConfigurationAttempt != null) {
2580be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" ").append(lastForgetConfigurationAttempt.configKey());
2581be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" nid=").append(lastForgetConfigurationAttempt.networkId);
2582be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastForgetConfigurationAttempt.hiddenSSID) {
2583be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" hidden");
2584be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2585be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastForgetConfigurationAttempt.preSharedKey != null) {
2586be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" hasPSK");
2587be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2588be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastForgetConfigurationAttempt.ephemeral) {
2589be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" ephemeral");
2590be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2591be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (lastForgetConfigurationAttempt.selfAdded) {
2592be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" selfAdded");
2593be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2594be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" cuid=").append(lastForgetConfigurationAttempt.creatorUid);
2595be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" suid=").append(lastForgetConfigurationAttempt.lastUpdateUid);
2596be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" ajst=").append(lastForgetConfigurationAttempt.autoJoinStatus);
2597be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                }
2598be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                break;
259940ff222cec1bd05879edb53abc75c6deead734cavandwalle            case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
260040ff222cec1bd05879edb53abc75c6deead734cavandwalle                sb.append(" ");
260140ff222cec1bd05879edb53abc75c6deead734cavandwalle                sb.append(Integer.toString(msg.arg1));
260240ff222cec1bd05879edb53abc75c6deead734cavandwalle                sb.append(" ");
260340ff222cec1bd05879edb53abc75c6deead734cavandwalle                sb.append(Integer.toString(msg.arg2));
260440ff222cec1bd05879edb53abc75c6deead734cavandwalle                String bssid = (String)msg.obj;
260540ff222cec1bd05879edb53abc75c6deead734cavandwalle                if (bssid != null && bssid.length()>0) {
260640ff222cec1bd05879edb53abc75c6deead734cavandwalle                    sb.append(" ");
260740ff222cec1bd05879edb53abc75c6deead734cavandwalle                    sb.append(bssid);
260840ff222cec1bd05879edb53abc75c6deead734cavandwalle                }
26092451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(" blacklist=" + Boolean.toString(didBlackListBSSID));
2610b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
261140ff222cec1bd05879edb53abc75c6deead734cavandwalle                break;
2612b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiMonitor.SCAN_RESULTS_EVENT:
2613b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2614b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2615b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2616b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2617b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (mScanResults != null) {
2618be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" found=");
2619b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(mScanResults.size());
2620b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2621be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" known=").append(mNumScanResultsKnown);
26222f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                sb.append(" got=").append(mNumScanResultsReturned);
2623b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (lastScanDuration != 0) {
2624b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" dur:").append(lastScanDuration);
2625b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
26260eebae7334d6129f7ca1344e4b20199794994358vandwalle                if (mOnTime != 0) {
26277b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" on:").append(mOnTimeThisScan).append(",").append(mOnTimeScan);
26287b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(",").append(mOnTime);
26290eebae7334d6129f7ca1344e4b20199794994358vandwalle                }
26300eebae7334d6129f7ca1344e4b20199794994358vandwalle                if (mTxTime != 0) {
26317b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" tx:").append(mTxTimeThisScan).append(",").append(mTxTimeScan);
26327b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(",").append(mTxTime);
26330eebae7334d6129f7ca1344e4b20199794994358vandwalle                }
26340eebae7334d6129f7ca1344e4b20199794994358vandwalle                if (mRxTime != 0) {
26357b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" rx:").append(mRxTimeThisScan).append(",").append(mRxTimeScan);
26367b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(",").append(mRxTime);
26370eebae7334d6129f7ca1344e4b20199794994358vandwalle                }
2638dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                sb.append(String.format(" bcn=%d", mRunningBeaconCount));
26398242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                sb.append(String.format(" con=%d", mConnectionRequests));
26408242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                key = mWifiConfigStore.getLastSelectedConfiguration();
26418242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                if (key != null) {
26428242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    sb.append(" last=").append(key);
26438242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                }
2644b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2645b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiMonitor.NETWORK_CONNECTION_EVENT:
2646b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2647b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2648b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2649b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2650b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" ").append(mLastBssid);
2651b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" nid=").append(mLastNetworkId);
2652b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                config = getCurrentWifiConfiguration();
2653b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (config != null) {
2654b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" ").append(config.configKey());
2655b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2656b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
26578242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                key = mWifiConfigStore.getLastSelectedConfiguration();
26588242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                if (key != null) {
26598242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    sb.append(" last=").append(key);
26608242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                }
2661b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2662e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle            case CMD_TARGET_BSSID:
26639f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            case CMD_ASSOCIATED_BSSID:
2664e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                sb.append(" ");
2665e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                sb.append(Integer.toString(msg.arg1));
2666e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                sb.append(" ");
2667e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                sb.append(Integer.toString(msg.arg2));
2668e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                if (msg.obj != null) {
2669e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                    sb.append(" BSSID=").append((String)msg.obj);
2670e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                }
2671e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                if (mTargetRoamBSSID != null) {
2672e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                    sb.append(" Target=").append(mTargetRoamBSSID);
2673e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                }
2674e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                sb.append(" roam=").append(Integer.toString(mAutoRoaming));
2675b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2676e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                break;
2677b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
2678b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (msg.obj != null) {
2679b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" ").append((String)msg.obj);
2680b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2681b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" nid=").append(msg.arg1);
2682b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" reason=").append(msg.arg2);
26837806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                if (mLastBssid != null) {
26847806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    sb.append(" lastbssid=").append(mLastBssid);
26857806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                }
26867806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                if (mWifiInfo.getFrequency() != -1) {
26877806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    sb.append(" freq=").append(mWifiInfo.getFrequency());
26887806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    sb.append(" rssi=").append(mWifiInfo.getRssi());
26897806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                }
26907806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                if (linkDebouncing) {
26917806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    sb.append(" debounce");
26927806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                }
2693b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2694b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2695b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiMonitor.SSID_TEMP_DISABLED:
2696b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiMonitor.SSID_REENABLED:
2697b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" nid=").append(msg.arg1);
2698b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (msg.obj != null) {
2699b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" ").append((String)msg.obj);
2700b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2701be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                config = getCurrentWifiConfiguration();
2702be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                if (config != null) {
2703be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" cur=").append(config.configKey());
2704be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" ajst=").append(config.autoJoinStatus);
2705be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (config.selfAdded) {
2706be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" selfAdded");
2707be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2708be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (config.status != 0) {
2709be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" st=").append(config.status);
2710be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" rs=").append(config.disableReason);
2711be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2712be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (config.lastConnected != 0) {
2713ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        now = System.currentTimeMillis();
2714be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" lastconn=").append(now - config.lastConnected).append("(ms)");
2715be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2716be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (mLastBssid != null) {
2717be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" lastbssid=").append(mLastBssid);
2718be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2719be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (mWifiInfo.getFrequency() != -1) {
2720be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" freq=").append(mWifiInfo.getFrequency());
2721be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" rssi=").append(mWifiInfo.getRssi());
2722be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        sb.append(" bssid=").append(mWifiInfo.getBSSID());
2723be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
2724be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                }
2725b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2726b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2727b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_RSSI_POLL:
2728b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_UNWANTED_NETWORK:
2729326120045502363422cf5c52a467163d4bcb703avandwalle            case WifiManager.RSSI_PKTCNT_FETCH:
2730b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2731b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2732b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2733b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2734b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                if (mWifiInfo.getSSID() != null)
27357b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (mWifiInfo.getSSID() != null)
2736b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    sb.append(" ").append(mWifiInfo.getSSID());
2737b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                if (mWifiInfo.getBSSID() != null)
2738b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    sb.append(" ").append(mWifiInfo.getBSSID());
2739b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" rssi=").append(mWifiInfo.getRssi());
2740b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" f=").append(mWifiInfo.getFrequency());
2741b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" sc=").append(mWifiInfo.score);
2742b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(" link=").append(mWifiInfo.getLinkSpeed());
2743b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" tx=%.1f,", mWifiInfo.txSuccessRate));
2744b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" %.1f,", mWifiInfo.txRetriesRate));
2745b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" %.1f ", mWifiInfo.txBadRate));
2746b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                sb.append(String.format(" rx=%.1f", mWifiInfo.rxSuccessRate));
2747dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                sb.append(String.format(" bcn=%d", mRunningBeaconCount));
27487b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                report = reportOnTime();
27497b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (report != null) {
27507b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" ").append(report);
27517b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                }
27527b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (wifiScoringReport != null) {
27537b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(wifiScoringReport);
27547b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                }
2755b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2756b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_AUTO_CONNECT:
2757b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case WifiManager.CONNECT_NETWORK:
2758b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2759b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2760b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2761b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2762b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                config = (WifiConfiguration) msg.obj;
2763b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (config != null) {
2764b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" ").append(config.configKey());
2765b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    if (config.visibility != null) {
2766f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle                        sb.append(" ").append(config.visibility.toString());
2767b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    }
2768b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
27698c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                if (mTargetRoamBSSID != null) {
27708c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    sb.append(" ").append(mTargetRoamBSSID);
27718c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                }
27728c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                sb.append(" roam=").append(Integer.toString(mAutoRoaming));
2773b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2774dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                config = getCurrentWifiConfiguration();
2775dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                if (config != null) {
2776f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle                    sb.append(config.configKey());
2777dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                    if (config.visibility != null) {
2778f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle                        sb.append(" ").append(config.visibility.toString());
2779dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                    }
2780dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                }
2781b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2782b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_AUTO_ROAM:
2783b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2784b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2785b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2786b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2787b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                ScanResult result = (ScanResult)msg.obj;
2788b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (result != null) {
27899e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                    now = System.currentTimeMillis();
27900d616ef3bf635dff8722e064c0be842676390ed8vandwalle                    sb.append(" bssid=").append(result.BSSID);
2791b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" rssi=").append(result.level);
2792b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    sb.append(" freq=").append(result.frequency);
27939e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                    if (result.seen > 0 && result.seen < now) {
27949e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                        sb.append(" seen=").append(now - result.seen);
27959e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                    } else {
27969e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                        // Somehow the timestamp for this scan result is inconsistent
27979e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                        sb.append(" !seen=").append(result.seen);
27989e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                    }
2799b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
28008c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                if (mTargetRoamBSSID != null) {
28018c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    sb.append(" ").append(mTargetRoamBSSID);
28028c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                }
28038c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                sb.append(" roam=").append(Integer.toString(mAutoRoaming));
28040d616ef3bf635dff8722e064c0be842676390ed8vandwalle                sb.append(" fail count=").append(Integer.toString(mRoamFailCount));
2805b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2806b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
28079f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            case CMD_ADD_OR_UPDATE_NETWORK:
28089f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                sb.append(" ");
28099f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                sb.append(Integer.toString(msg.arg1));
28109f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                sb.append(" ");
28119f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                sb.append(Integer.toString(msg.arg2));
28129f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                if (msg.obj != null) {
28139f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    config = (WifiConfiguration)msg.obj;
28149f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    sb.append(" ").append(config.configKey());
2815b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    sb.append(" prio=").append(config.priority);
2816b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    sb.append(" status=").append(config.status);
2817b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    if (config.BSSID != null) {
2818b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        sb.append(" ").append(config.BSSID);
2819b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    }
2820b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    WifiConfiguration curConfig = getCurrentWifiConfiguration();
2821b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    if (curConfig != null) {
2822b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        if (curConfig.configKey().equals(config.configKey())) {
2823b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                            sb.append(" is current");
2824b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        } else {
2825b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                            sb.append(" current=").append(curConfig.configKey());
2826b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                            sb.append(" prio=").append(curConfig.priority);
2827b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                            sb.append(" status=").append(curConfig.status);
2828b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        }
2829b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    }
28309f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                }
28319f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                break;
2832b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle            case WifiManager.DISABLE_NETWORK:
2833b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_ENABLE_NETWORK:
2834b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2835b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2836b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2837b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
28388242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                key = mWifiConfigStore.getLastSelectedConfiguration();
2839b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                if (key != null) {
28409f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    sb.append(" last=").append(key);
28419f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                }
28429f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                config = mWifiConfigStore.getWifiConfiguration(msg.arg1);
28439f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                if (config != null && (key == null || !config.configKey().equals(key))) {
2844b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    sb.append(" target=").append(key);
2845b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                }
2846b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2847931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case CMD_GET_CONFIGURED_NETWORKS:
2848931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                sb.append(" ");
2849931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                sb.append(Integer.toString(msg.arg1));
2850931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                sb.append(" ");
2851931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                sb.append(Integer.toString(msg.arg2));
2852931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                sb.append(" num=").append(mWifiConfigStore.getConfiguredNetworksSize());
2853931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
2854a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle            case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
2855a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(" ");
2856a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(Integer.toString(msg.arg1));
2857a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(" ");
2858a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(Integer.toString(msg.arg2));
2859a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(" txpkts=").append(mWifiInfo.txSuccess);
2860a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(",").append(mWifiInfo.txBad);
2861a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                sb.append(",").append(mWifiInfo.txRetries);
2862a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                break;
28632451dbcc4f9641df188326215b204b798eb70c46vandwalle            case DhcpStateMachine.CMD_POST_DHCP_ACTION:
28642451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(" ");
28652451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(Integer.toString(msg.arg1));
28662451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(" ");
28672451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(Integer.toString(msg.arg2));
28682451dbcc4f9641df188326215b204b798eb70c46vandwalle                if (msg.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
28692451dbcc4f9641df188326215b204b798eb70c46vandwalle                    sb.append(" OK ");
28702451dbcc4f9641df188326215b204b798eb70c46vandwalle                } else if (msg.arg1 == DhcpStateMachine.DHCP_FAILURE) {
28712451dbcc4f9641df188326215b204b798eb70c46vandwalle                    sb.append(" FAIL ");
28722451dbcc4f9641df188326215b204b798eb70c46vandwalle                }
287382d20190c3ec3a080d928a581c40311c66345cc8vandwalle                if (mLinkProperties != null) {
287482d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    if (mLinkProperties.hasIPv4Address()) {
287582d20190c3ec3a080d928a581c40311c66345cc8vandwalle                        sb.append(" v4");
287682d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    }
287782d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    if (mLinkProperties.hasGlobalIPv6Address()) {
287882d20190c3ec3a080d928a581c40311c66345cc8vandwalle                        sb.append(" v6");
287982d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    }
288082d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    if (mLinkProperties.hasIPv4DefaultRoute()) {
288182d20190c3ec3a080d928a581c40311c66345cc8vandwalle                        sb.append(" v4r");
288282d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    }
288382d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    if (mLinkProperties.hasIPv6DefaultRoute()) {
288482d20190c3ec3a080d928a581c40311c66345cc8vandwalle                        sb.append(" v6r");
288582d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    }
288682d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    if (mLinkProperties.hasIPv4DnsServer()) {
288782d20190c3ec3a080d928a581c40311c66345cc8vandwalle                        sb.append(" v4dns");
288882d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    }
288982d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    if (mLinkProperties.hasIPv6DnsServer()) {
289082d20190c3ec3a080d928a581c40311c66345cc8vandwalle                        sb.append(" v6dns");
289182d20190c3ec3a080d928a581c40311c66345cc8vandwalle                    }
289282d20190c3ec3a080d928a581c40311c66345cc8vandwalle                }
28932451dbcc4f9641df188326215b204b798eb70c46vandwalle                break;
28942451dbcc4f9641df188326215b204b798eb70c46vandwalle            case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
28952451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(" ");
28962451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(Integer.toString(msg.arg1));
28972451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(" ");
28982451dbcc4f9641df188326215b204b798eb70c46vandwalle                sb.append(Integer.toString(msg.arg2));
28992451dbcc4f9641df188326215b204b798eb70c46vandwalle                if (msg.obj != null) {
29002451dbcc4f9641df188326215b204b798eb70c46vandwalle                    NetworkInfo info = (NetworkInfo)msg.obj;
29012451dbcc4f9641df188326215b204b798eb70c46vandwalle                    NetworkInfo.State state = info.getState();
29022451dbcc4f9641df188326215b204b798eb70c46vandwalle                    NetworkInfo.DetailedState detailedState = info.getDetailedState();
29032451dbcc4f9641df188326215b204b798eb70c46vandwalle                    if (state != null) {
29042451dbcc4f9641df188326215b204b798eb70c46vandwalle                        sb.append(" st=").append(state);
29052451dbcc4f9641df188326215b204b798eb70c46vandwalle                    }
29062451dbcc4f9641df188326215b204b798eb70c46vandwalle                    if (detailedState != null) {
29072451dbcc4f9641df188326215b204b798eb70c46vandwalle                        sb.append("/").append(detailedState);
29082451dbcc4f9641df188326215b204b798eb70c46vandwalle                    }
29092451dbcc4f9641df188326215b204b798eb70c46vandwalle                }
29102451dbcc4f9641df188326215b204b798eb70c46vandwalle                break;
2911c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            case CMD_IP_CONFIGURATION_LOST:
2912c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                int count = -1;
2913c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                WifiConfiguration c = getCurrentWifiConfiguration();
2914e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                if (c != null) count = c.numIpConfigFailures;
2915c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(" ");
2916c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(Integer.toString(msg.arg1));
2917c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(" ");
2918c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(Integer.toString(msg.arg2));
2919c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(" failures: ");
2920c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(Integer.toString(count));
2921c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append("/");
2922c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                sb.append(Integer.toString(mWifiConfigStore.getMaxDhcpRetries()));
2923e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                if (mWifiInfo.getBSSID() != null) {
2924a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    sb.append(" ").append(mWifiInfo.getBSSID());
2925e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                }
2926a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                if (c != null) {
2927a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    if (c.scanResultCache != null) {
2928a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                        for (ScanResult r : c.scanResultCache.values()) {
2929a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                            if (r.BSSID.equals(mWifiInfo.getBSSID())) {
2930a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                                sb.append(" ipfail=").append(r.numIpConfigFailures);
2931a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                                sb.append(",st=").append(r.autoJoinStatus);
2932a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                            }
2933e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                        }
2934e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                    }
2935a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    sb.append(" -> ajst=").append(c.autoJoinStatus);
2936a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    sb.append(" ").append(c.disableReason);
2937a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    sb.append(" txpkts=").append(mWifiInfo.txSuccess);
2938a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    sb.append(",").append(mWifiInfo.txBad);
2939a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                    sb.append(",").append(mWifiInfo.txRetries);
2940e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                }
2941b5120326b58f35217dcedc5f19e8cf3eb42b28d0vandwalle                sb.append(printTime());
2942dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle                sb.append(String.format(" bcn=%d", mRunningBeaconCount));
2943c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                break;
29447806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            case CMD_UPDATE_LINKPROPERTIES:
29457806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                sb.append(" ");
29467806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                sb.append(Integer.toString(msg.arg1));
29477806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                sb.append(" ");
29487806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                sb.append(Integer.toString(msg.arg2));
29497806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                if (mLinkProperties != null) {
29507806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (mLinkProperties.hasIPv4Address()) {
29517806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sb.append(" v4");
29527806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
29537806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (mLinkProperties.hasGlobalIPv6Address()) {
29547806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sb.append(" v6");
29557806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
29567806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (mLinkProperties.hasIPv4DefaultRoute()) {
29577806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sb.append(" v4r");
29587806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
29597806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (mLinkProperties.hasIPv6DefaultRoute()) {
29607806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sb.append(" v6r");
29617806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
29627806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (mLinkProperties.hasIPv4DnsServer()) {
29637806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sb.append(" v4dns");
29647806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
29657806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (mLinkProperties.hasIPv6DnsServer()) {
29667806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sb.append(" v6dns");
29677806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
29687806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                }
29697806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                break;
2970be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case CMD_SET_COUNTRY_CODE:
2971be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2972be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg1));
2973be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2974be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg2));
2975be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                if (msg.obj != null) {
2976be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    sb.append(" ").append((String)msg.obj);
2977be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                }
2978be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                break;
2979be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case CMD_ROAM_WATCHDOG_TIMER:
2980be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2981be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg1));
2982be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2983be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg2));
2984be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" cur=").append(roamWatchdogCount);
2985be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                break;
2986be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case CMD_DISCONNECTING_WATCHDOG_TIMER:
2987be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2988be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg1));
2989be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" ");
2990be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(Integer.toString(msg.arg2));
2991be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                sb.append(" cur=").append(disconnectingWatchdogCount);
2992be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                break;
2993b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            default:
2994b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2995b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg1));
2996b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(" ");
2997b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                sb.append(Integer.toString(msg.arg2));
2998b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
2999b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        }
3000b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle
3001b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle        return sb.toString();
3002b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle    }
3003b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle
30047c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande    private void handleScreenStateChanged(boolean screenOn, boolean startBackgroundScanIfNeeded) {
3005f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        mScreenOn = screenOn;
3006f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (PDBG) {
3007f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            loge(" handleScreenStateChanged Enter: screenOn=" + screenOn
3008f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    + " mUserWantsSuspendOpt=" + mUserWantsSuspendOpt
3009f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    + " state " + getCurrentState().getName()
3010f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    + " suppState:" + mSupplicantStateTracker.getSupplicantStateName());
3011f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
3012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enableRssiPolling(screenOn);
3013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (screenOn) enableAllNetworks();
3014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mUserWantsSuspendOpt.get()) {
3015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (screenOn) {
3016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 0, 0);
3017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
30187b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                // Allow 2s for suspend optimizations to be set
3019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mSuspendWakeLock.acquire(2000);
3020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 1, 0);
3021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mScreenBroadcastReceived.set(true);
3024f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
30257b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        getWifiLinkLayerStats(false);
30267b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        mOnTimeScreenStateChange = mOnTime;
30277b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate;
30288242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        mEnableBackgroundScan = false;
30298242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        cancelDelayedScan();
30307b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
3031f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (screenOn) {
30328242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            setScanAlarm(false);
3033e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle            clearBlacklist();
3034e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle
30350eebae7334d6129f7ca1344e4b20199794994358vandwalle            fullBandConnectedTimeIntervalMilli = mWifiConfigStore.associatedPartialScanPeriodMilli;
30368242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // In either Disconnectedstate or ConnectedState,
30378242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // start the scan alarm so as to enable autojoin
30382f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            if (getCurrentState() == mConnectedState
303970468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    && mWifiConfigStore.enableAutoJoinScanWhenAssociated) {
30408242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                // Scan after 500ms
30418242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                startDelayedScan(500, null, null);
3042e67ec726c07410073575473c0f50dc737629f5davandwalle            } else if (getCurrentState() == mDisconnectedState) {
30439f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // Scan after 200ms
30448242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                startDelayedScan(200, null, null);
30458242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            }
30468242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        } else if (startBackgroundScanIfNeeded) {
30478242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // Screen Off and Disconnected and chipset doesn't support scan offload
30488242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            //              => start scan alarm
30498242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            // Screen Off and Disconnected and chipset does support scan offload
30508242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            //              => will use scan offload (i.e. background scan)
30518242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            if (!mBackgroundScanSupported) {
30528242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                setScanAlarm(true);
30538242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            } else {
30548242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                mEnableBackgroundScan = true;
3055f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
30567c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande        }
30577c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande        if (DBG) logd("backgroundScan enabled=" + mEnableBackgroundScan
30587c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                + " startBackgroundScanIfNeeded:" + startBackgroundScanIfNeeded);
30597c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande        if (startBackgroundScanIfNeeded) {
3060cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande            // to scan for them in background, we need all networks enabled
3061cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande            enableBackgroundScan(mEnableBackgroundScan);
30627c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande        }
3063f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) log("handleScreenStateChanged Exit: " + screenOn);
3064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void checkAndSetConnectivityInstance() {
3067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mCm == null) {
3068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
3069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean startTethering(ArrayList<String> available) {
3073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean wifiAvailable = false;
3075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        checkAndSetConnectivityInstance();
3077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
3079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String intf : available) {
3081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String regex : wifiRegexs) {
3082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (intf.matches(regex)) {
3083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    InterfaceConfiguration ifcg = null;
3085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
3086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ifcg = mNwService.getInterfaceConfig(intf);
3087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (ifcg != null) {
3088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            /* IP/netmask: 192.168.43.1/255.255.255.0 */
3089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ifcg.setLinkAddress(new LinkAddress(
3090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
3091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ifcg.setInterfaceUp();
3092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNwService.setInterfaceConfig(intf, ifcg);
3094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
3095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (Exception e) {
3096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Error configuring interface " + intf + ", :" + e);
3097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return false;
3098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
3101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Error tethering on " + intf);
3102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return false;
3103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTetherInterfaceName = intf;
3105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return true;
3106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // We found no interfaces to tether
3110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
3111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void stopTethering() {
3114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        checkAndSetConnectivityInstance();
3116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Clear the interface config to allow dhcp correctly configure new
3118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande           ip settings */
3119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        InterfaceConfiguration ifcg = null;
3120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
3121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg = mNwService.getInterfaceConfig(mTetherInterfaceName);
3122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (ifcg != null) {
3123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                ifcg.setLinkAddress(
3124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
3125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mNwService.setInterfaceConfig(mTetherInterfaceName, ifcg);
3126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
3128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Error resetting interface " + mTetherInterfaceName + ", :" + e);
3129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
3132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Untether initiate failed!");
3133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean isWifiTethered(ArrayList<String> active) {
3137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        checkAndSetConnectivityInstance();
3139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
3141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String intf : active) {
3142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String regex : wifiRegexs) {
3143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (intf.matches(regex)) {
3144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return true;
3145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // We found no interfaces that are tethered
3149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
3150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Set the country code from the system setting value, if any.
3154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setCountryCode() {
3156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
3157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_COUNTRY_CODE);
3158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (countryCode != null && !countryCode.isEmpty()) {
3159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setCountryCode(countryCode, false);
3160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
3161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //use driver default
3162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Set the frequency band from the system setting value, if any.
3167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setFrequencyBand() {
3169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int band = Settings.Global.getInt(mContext.getContentResolver(),
3170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
3171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setFrequencyBand(band, false);
3172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setSuspendOptimizationsNative(int reason, boolean enabled) {
3175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) {
3176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            log("setSuspendOptimizationsNative: " + reason + " " + enabled
3177f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    + " -want " + mUserWantsSuspendOpt.get()
3178f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
3179f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    +" - "+ Thread.currentThread().getStackTrace()[3].getMethodName()
3180f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    +" - "+ Thread.currentThread().getStackTrace()[4].getMethodName()
3181f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    +" - "+ Thread.currentThread().getStackTrace()[5].getMethodName());
3182f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
3183a2903b7c6fc2419d48fd9976fa24852370653c4avandwalle        //mWifiNative.setSuspendOptimizations(enabled);
3184f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
3185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enabled) {
3186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSuspendOptNeedsDisabled &= ~reason;
3187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* None of dhcp, screen or highperf need it disabled and user wants it enabled */
3188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) {
3189f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                if (DBG) {
3190f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    log("setSuspendOptimizationsNative do it " + reason + " " + enabled
3191f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                            + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
3192f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                            +" - "+ Thread.currentThread().getStackTrace()[3].getMethodName()
3193f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                            +" - "+ Thread.currentThread().getStackTrace()[4].getMethodName()
3194f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                            +" - "+ Thread.currentThread().getStackTrace()[5].getMethodName());
3195f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                }
3196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.setSuspendOptimizations(true);
3197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
3199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSuspendOptNeedsDisabled |= reason;
3200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.setSuspendOptimizations(false);
3201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setSuspendOptimizations(int reason, boolean enabled) {
3205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) log("setSuspendOptimizations: " + reason + " " + enabled);
3206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enabled) {
3207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSuspendOptNeedsDisabled &= ~reason;
3208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
3209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSuspendOptNeedsDisabled |= reason;
3210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
3212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setWifiState(int wifiState) {
3215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final int previousWifiState = mWifiState.get();
3216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
3218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (wifiState == WIFI_STATE_ENABLED) {
3219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiOn();
3220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else if (wifiState == WIFI_STATE_DISABLED) {
3221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiOff();
3222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (RemoteException e) {
3224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to note battery stats in wifi");
3225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiState.set(wifiState);
3228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) log("setWifiState: " + syncGetWifiStateByName());
3230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
3232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
3233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
3234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
3235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
3236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setWifiApState(int wifiApState) {
3239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final int previousWifiApState = mWifiApState.get();
3240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
3242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (wifiApState == WIFI_AP_STATE_ENABLED) {
3243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiOn();
3244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
3245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mBatteryStats.noteWifiOff();
3246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (RemoteException e) {
3248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to note battery stats in wifi");
3249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Update state
3252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiApState.set(wifiApState);
3253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
3255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
3257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
3258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
3259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
3260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
3261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3263e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    /*
3264e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    void ageOutScanResults(int age) {
3265e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        synchronized(mScanResultCache) {
3266e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            // Trim mScanResults, which prevent WifiStateMachine to return
3267e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            // obsolete scan results to queriers
3268e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            long now = System.CurrentTimeMillis();
3269e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            for (int i = 0; i < mScanResults.size(); i++) {
3270e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                ScanResult result = mScanResults.get(i);
3271e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                if ((result.seen > now || (now - result.seen) > age)) {
3272e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    mScanResults.remove(i);
3273e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                }
3274e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            }
3275e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
3276e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    }*/
3277e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
3278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String ID_STR = "id=";
3279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String BSSID_STR = "bssid=";
3280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String FREQ_STR = "freq=";
3281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String LEVEL_STR = "level=";
3282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String TSF_STR = "tsf=";
3283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String FLAGS_STR = "flags=";
3284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String SSID_STR = "ssid=";
3285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String DELIMITER_STR = "====";
3286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String END_STR = "####";
3287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3288e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle    int emptyScanResultCount = 0;
3289e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle
32902f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle    // Used for matching BSSID strings, at least one characteer must be a non-zero number
32912f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle    private static Pattern mNotZero = Pattern.compile("[1-9a-fA-F]");
32922f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle
3293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Format:
3295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * id=1
3297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * bssid=68:7f:76:d7:1a:6e
3298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * freq=2412
3299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * level=-44
3300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * tsf=1344626243700342
3301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * flags=[WPA2-PSK-CCMP][WPS][ESS]
3302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * ssid=zfdy
3303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * ====
3304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * id=2
3305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * bssid=68:5f:74:d7:1a:6f
3306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * freq=5180
3307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * level=-73
3308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * tsf=1344626243700373
3309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * flags=[WPA2-PSK-CCMP][WPS][ESS]
3310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * ssid=zuby
3311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * ====
3312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setScanResults() {
3314be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle        mNumScanResultsKnown = 0;
33152f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        mNumScanResultsReturned = 0;
3316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String bssid = "";
3317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int level = 0;
3318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int freq = 0;
3319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        long tsf = 0;
3320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String flags = "";
3321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiSsid wifiSsid = null;
3322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String scanResults;
3323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String tmpResults;
3324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        StringBuffer scanResultsBuf = new StringBuffer();
3325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int sid = 0;
3326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        while (true) {
3328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            tmpResults = mWifiNative.scanResults(sid);
3329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (TextUtils.isEmpty(tmpResults)) break;
3330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            scanResultsBuf.append(tmpResults);
3331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            scanResultsBuf.append("\n");
3332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] lines = tmpResults.split("\n");
3333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sid = -1;
3334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (int i=lines.length - 1; i >= 0; i--) {
3335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (lines[i].startsWith(END_STR)) {
3336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
3337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (lines[i].startsWith(ID_STR)) {
3338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
3339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sid = Integer.parseInt(lines[i].substring(ID_STR.length())) + 1;
3340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (NumberFormatException e) {
3341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Nothing to do
3342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
3344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (sid == -1) break;
3347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3349e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        // Age out scan results, we return all scan results found in the last 12 seconds,
3350e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        // and NOT all scan results since last scan.
3351e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        // ageOutScanResults(12000);
3352e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
3353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        scanResults = scanResultsBuf.toString();
3354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(scanResults)) {
3355e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle            emptyScanResultCount++;
3356e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle            if (emptyScanResultCount > 10) {
3357e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                // If we got too many empty scan results, the current scan cache is stale,
3358e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                // hence clear it.
3359e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                mScanResults = new ArrayList<ScanResult>();
3360e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle            }
3361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande           return;
3362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3364e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle        emptyScanResultCount = 0;
3365a0708b09ad17b086c008ab100aec7143d7613c80vandwalle
3366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // note that all these splits and substrings keep references to the original
3367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // huge string buffer while the amount we really want is generally pretty small
3368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // so make copies instead (one example b/11087956 wasted 400k of heap here).
3369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized(mScanResultCache) {
3370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mScanResults = new ArrayList<ScanResult>();
3371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] lines = scanResults.split("\n");
3372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final int bssidStrLen = BSSID_STR.length();
3373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final int flagLen = FLAGS_STR.length();
3374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String line : lines) {
3376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (line.startsWith(BSSID_STR)) {
3377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    bssid = new String(line.getBytes(), bssidStrLen, line.length() - bssidStrLen);
3378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (line.startsWith(FREQ_STR)) {
3379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
3380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        freq = Integer.parseInt(line.substring(FREQ_STR.length()));
3381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (NumberFormatException e) {
3382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        freq = 0;
3383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (line.startsWith(LEVEL_STR)) {
3385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
3386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        level = Integer.parseInt(line.substring(LEVEL_STR.length()));
3387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /* some implementations avoid negative values by adding 256
3388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * so we need to adjust for that here.
3389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         */
3390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (level > 0) level -= 256;
3391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch(NumberFormatException e) {
3392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        level = 0;
3393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (line.startsWith(TSF_STR)) {
3395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
3396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        tsf = Long.parseLong(line.substring(TSF_STR.length()));
3397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (NumberFormatException e) {
3398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        tsf = 0;
3399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (line.startsWith(FLAGS_STR)) {
3401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    flags = new String(line.getBytes(), flagLen, line.length() - flagLen);
3402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (line.startsWith(SSID_STR)) {
3403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    wifiSsid = WifiSsid.createFromAsciiEncoded(
3404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            line.substring(SSID_STR.length()));
3405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else if (line.startsWith(DELIMITER_STR) || line.startsWith(END_STR)) {
34062f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                    Matcher match = null;
34072f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                    if (bssid!= null) {
34082f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                        match = mNotZero.matcher(bssid);
34092f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                    }
34102f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                    if (match != null && !bssid.isEmpty() && match.find()) {
3411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        String ssid = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
3412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        String key = bssid + ssid;
3413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ScanResult scanResult = mScanResultCache.get(key);
3414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (scanResult != null) {
3415e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            // TODO: average the RSSI, instead of overwriting it
3416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult.level = level;
3417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult.wifiSsid = wifiSsid;
3418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // Keep existing API
3419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult.SSID = (wifiSsid != null) ? wifiSsid.toString() :
3420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    WifiSsid.NONE;
3421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult.capabilities = flags;
3422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult.frequency = freq;
3423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult.timestamp = tsf;
3424ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle                            scanResult.seen = System.currentTimeMillis();
3425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
3426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            scanResult =
3427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                new ScanResult(
3428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                        wifiSsid, bssid, flags, level, freq, tsf);
3429be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            scanResult.seen = System.currentTimeMillis();
3430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mScanResultCache.put(key, scanResult);
3431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
34322f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        mNumScanResultsReturned ++; // Keep track of how many scan results we got
34332f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                                                    // as part of this scan's processing
3434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mScanResults.add(scanResult);
34352f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                    } else {
34362f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                        if (bssid != null)  {
34372f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                            loge("setScanResults obtaining null BSSID results <"
34382f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                                + bssid + ">, discard it");
34392f05eff93e2503c9f29a0d7ede62c71c430ccf5fvandwalle                        }
3440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    bssid = null;
3442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    level = 0;
3443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    freq = 0;
3444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    tsf = 0;
3445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    flags = "";
3446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    wifiSsid = null;
3447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
34507806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        boolean attemptAutoJoin = true;
345156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle        SupplicantState state = mWifiInfo.getSupplicantState();
3452104a9803187593ab25d3784b420077022686dbe4vandwalle        String selection = mWifiConfigStore.getLastSelectedConfiguration();
34537806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        if (getCurrentState() == mRoamingState
34547806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                || getCurrentState() == mObtainingIpState
34559f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                || getCurrentState() == mScanModeState
34569f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                || getCurrentState() == mDisconnectingState
34572f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                || (getCurrentState() == mConnectedState
345870468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                && !mWifiConfigStore.enableAutoJoinWhenAssociated)
345956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                || linkDebouncing
346056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                || state == SupplicantState.ASSOCIATING
346156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                || state == SupplicantState.AUTHENTICATING
346256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                || state == SupplicantState.FOUR_WAY_HANDSHAKE
34630af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti                || state == SupplicantState.GROUP_HANDSHAKE
3464104a9803187593ab25d3784b420077022686dbe4vandwalle                || (/* keep autojoin enabled if user has manually selected a wifi network,
3465104a9803187593ab25d3784b420077022686dbe4vandwalle                        so as to make sure we reliably remain connected to this network */
3466104a9803187593ab25d3784b420077022686dbe4vandwalle                        mConnectionRequests == 0 && selection == null)) {
34677806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // Dont attempt auto-joining again while we are already attempting to join
34687806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // and/or obtaining Ip address
34697806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            attemptAutoJoin = false;
34707806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        }
34719f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (DBG) {
34728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            if (selection == null) {
34738242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                selection = "<none>";
34748242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            }
34759f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            loge("wifi setScanResults state" + getCurrentState()
34769f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    + " sup_state=" + state
3477833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                    + " debouncing=" + linkDebouncing
34788242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    + " mConnectionRequests=" + mConnectionRequests
34798242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    + " selection=" + selection);
34809f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
34812f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        if (attemptAutoJoin) {
34822f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            messageHandlingStatus = MESSAGE_HANDLING_STATUS_PROCESSED;
34832f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        }
3484abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle        // Loose last selected configuration if we have been disconnected for 5 minutes
3485abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle        if (getDisconnectedTimeMilli() > mWifiConfigStore.wifiConfigLastSelectionHysteresis) {
34860eebae7334d6129f7ca1344e4b20199794994358vandwalle            mWifiConfigStore.setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
34870eebae7334d6129f7ca1344e4b20199794994358vandwalle        }
3488e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle
3489e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle        if (mWifiConfigStore.enableAutoJoinWhenAssociated) {
3490e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle            synchronized(mScanResultCache) {
3491e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                // AutoJoincontroller will directly acces the scan result list and update it with
3492e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                // ScanResult status
3493e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                mNumScanResultsKnown = mWifiAutoJoinController.newSupplicantResults(attemptAutoJoin);
3494e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle            }
3495e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
34967806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        if (linkDebouncing) {
34977806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // If debouncing, we dont re-select a SSID or BSSID hence
34987806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // there is no need to call the network selection code
34997806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // in WifiAutoJoinController, instead,
35007806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // just try to reconnect to the same SSID by triggering a roam
35017806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            sendMessage(CMD_AUTO_ROAM, mLastNetworkId, 1, null);
35027806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        }
3503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /*
350674b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme     * Fetch RSSI, linkspeed, and frequency on current connection
3507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
350874b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme    private void fetchRssiLinkSpeedAndFrequencyNative() {
3509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int newRssi = -1;
3510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int newLinkSpeed = -1;
351174b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme        int newFrequency = -1;
3512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String signalPoll = mWifiNative.signalPoll();
3514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (signalPoll != null) {
3516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] lines = signalPoll.split("\n");
3517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String line : lines) {
3518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                String[] prop = line.split("=");
3519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (prop.length < 2) continue;
3520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
3521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (prop[0].equals("RSSI")) {
3522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        newRssi = Integer.parseInt(prop[1]);
3523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (prop[0].equals("LINKSPEED")) {
3524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        newLinkSpeed = Integer.parseInt(prop[1]);
352574b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme                    } else if (prop[0].equals("FREQUENCY")) {
352674b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme                        newFrequency = Integer.parseInt(prop[1]);
3527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (NumberFormatException e) {
3529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Ignore, defaults on rssi and linkspeed are assigned
3530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3534117be607246604e875de62aa8cdd99700b77a2b4vandwalle        if (PDBG) {
3535117be607246604e875de62aa8cdd99700b77a2b4vandwalle            loge("fetchRssiLinkSpeedAndFrequencyNative rssi="
3536117be607246604e875de62aa8cdd99700b77a2b4vandwalle                    + Integer.toString(newRssi) + " linkspeed="
3537117be607246604e875de62aa8cdd99700b77a2b4vandwalle                    + Integer.toString(newLinkSpeed));
3538117be607246604e875de62aa8cdd99700b77a2b4vandwalle        }
3539117be607246604e875de62aa8cdd99700b77a2b4vandwalle
35404b50786546ce4c4fee555d66028991fe257b8811vandwalle        if (newRssi > WifiInfo.INVALID_RSSI && newRssi < WifiInfo.MAX_RSSI) {
35414b50786546ce4c4fee555d66028991fe257b8811vandwalle        // screen out invalid values
3542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* some implementations avoid negative values by adding 256
3543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * so we need to adjust for that here.
3544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             */
3545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (newRssi > 0) newRssi -= 256;
3546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiInfo.setRssi(newRssi);
3547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /*
3548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * Rather then sending the raw RSSI out every time it
3549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * changes, we precalculate the signal level that would
3550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * be displayed in the status bar, and only send the
3551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * broadcast if that much more coarse-grained number
3552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * changes. This cuts down greatly on the number of
3553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * broadcasts, at the cost of not informing others
3554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * interested in RSSI of all the changes in signal
3555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * level.
3556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             */
3557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, WifiManager.RSSI_LEVELS);
3558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (newSignalLevel != mLastSignalLevel) {
3559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendRssiChangeBroadcast(newRssi);
3560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mLastSignalLevel = newSignalLevel;
3562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
35634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            mWifiInfo.setRssi(WifiInfo.INVALID_RSSI);
3564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (newLinkSpeed != -1) {
3567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiInfo.setLinkSpeed(newLinkSpeed);
3568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
356974b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme        if (newFrequency > 0) {
35700e916560ab551ac44e6ce0324bdc511f66268944Brian Williammee            if (ScanResult.is5GHz(newFrequency)) {
3571c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                mWifiConnectionStatistics.num5GhzConnected++;
3572c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle            }
3573c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle            if (ScanResult.is24GHz(newFrequency)) {
3574c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                mWifiConnectionStatistics.num24GhzConnected++;
3575c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle            }
357674b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme            mWifiInfo.setFrequency(newFrequency);
357774b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme        }
3578c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle        mWifiConfigStore.updateConfiguration(mWifiInfo);
3579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3581931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle    /**
3582931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle     *  Determine if we need to switch network:
35834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle     * - the delta determine the urgency to switch and/or or the expected evilness of the disruption
35844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle     * - match the uregncy of the switch versus the packet usage at the interface
35854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle     */
35864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    boolean shouldSwitchNetwork(int networkDelta) {
35874dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        int delta;
3588b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle        if (networkDelta <= 0) {
3589b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle            return false;
35904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
35914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        delta = networkDelta;
35924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        if (mWifiInfo != null) {
359370468b47454c8657e8963932f2e08a3f4d7e3881vandwalle            if (!mWifiConfigStore.enableAutoJoinWhenAssociated
35948c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    && mWifiInfo.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
35958c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                // If AutoJoin while associated is not enabled,
35968c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                // we should never switch network when already associated
35978c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                delta = -1000;
35988c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle            } else {
35998c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                // TODO: Look at per AC packet count, do not switch if VO/VI traffic is present
36008c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                // TODO: at the interface. We should also discriminate between ucast and mcast,
36018c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                // TODO: since the rxSuccessRate include all the bonjour and Ipv6
36028c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                // TODO: broadcasts
36038c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                if ((mWifiInfo.txSuccessRate > 20) || (mWifiInfo.rxSuccessRate > 80)) {
36048c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    delta -= 999;
36058c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                } else if ((mWifiInfo.txSuccessRate > 5) || (mWifiInfo.rxSuccessRate > 30)) {
36068c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    delta -= 6;
36078c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                }
36088c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                loge("WifiStateMachine shouldSwitchNetwork "
36098c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                        + " txSuccessRate=" + String.format("%.2f", mWifiInfo.txSuccessRate)
36108c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                        + " rxSuccessRate=" + String.format("%.2f", mWifiInfo.rxSuccessRate)
36118c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                        + " delta " + networkDelta + " -> " + delta);
36124dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            }
36134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        } else {
36144dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            loge("WifiStateMachine shouldSwitchNetwork "
36154dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    + " delta " + networkDelta + " -> " + delta);
36164dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
36174dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        if (delta > 0) {
36184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            return true;
36194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
36204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        return false;
36214dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    }
362227355a942653264388e909a4276196ee63e57811vandwalle
3623ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    // Polling has completed, hence we wont have a score anymore
3624ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    private void cleanWifiScore() {
3625ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        mWifiInfo.txBadRate = 0;
3626ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        mWifiInfo.txSuccessRate = 0;
3627ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        mWifiInfo.txRetriesRate = 0;
3628ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle        mWifiInfo.rxSuccessRate = 0;
3629ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle    }
3630ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle
36317736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle    int mBadLinkspeedcount = 0;
36327736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle
36337b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    // For debug, provide information about the last scoring operation
36347b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle    String wifiScoringReport = null;
363527355a942653264388e909a4276196ee63e57811vandwalle    private void calculateWifiScore(WifiLinkLayerStats stats) {
36367b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        StringBuilder sb = new StringBuilder();
3637efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle
36387b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        int score = 56; // Starting score, temporarily hardcoded in between 50 and 60
363927355a942653264388e909a4276196ee63e57811vandwalle        boolean isBadLinkspeed = (mWifiInfo.is24GHz()
364017e828848eebb4eb11d27ce32d02716334dd6011vandwalle                && mWifiInfo.getLinkSpeed() < mWifiConfigStore.badLinkSpeed24)
364117e828848eebb4eb11d27ce32d02716334dd6011vandwalle                || (mWifiInfo.is5GHz() && mWifiInfo.getLinkSpeed()
364217e828848eebb4eb11d27ce32d02716334dd6011vandwalle                < mWifiConfigStore.badLinkSpeed5);
364327355a942653264388e909a4276196ee63e57811vandwalle        boolean isGoodLinkspeed = (mWifiInfo.is24GHz()
364417e828848eebb4eb11d27ce32d02716334dd6011vandwalle                && mWifiInfo.getLinkSpeed() >= mWifiConfigStore.goodLinkSpeed24)
364517e828848eebb4eb11d27ce32d02716334dd6011vandwalle                || (mWifiInfo.is5GHz() && mWifiInfo.getLinkSpeed()
364617e828848eebb4eb11d27ce32d02716334dd6011vandwalle                >= mWifiConfigStore.goodLinkSpeed5);
36474b50786546ce4c4fee555d66028991fe257b8811vandwalle
36487736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle        if (isBadLinkspeed) {
36497736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle            if (mBadLinkspeedcount < 6)
36507736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle                mBadLinkspeedcount++;
36517736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle        } else {
36527736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle            if (mBadLinkspeedcount > 0)
36537736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle                mBadLinkspeedcount--;
36547736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle        }
36557736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle
36567736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle        if (isBadLinkspeed) sb.append(" bl(").append(mBadLinkspeedcount).append(")");
36577b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (isGoodLinkspeed) sb.append(" gl");
36587b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
3659931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        /**
3660a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle         * We want to make sure that we use the 24GHz RSSI thresholds if
3661931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle         * there are 2.4GHz scan results
3662931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle         * otherwise we end up lowering the score based on 5GHz values
3663931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle         * which may cause a switch to LTE before roaming has a chance to try 2.4GHz
3664931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle         * We also might unblacklist the configuation based on 2.4GHz
3665931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle         * thresholds but joining 5GHz anyhow, and failing over to 2.4GHz because 5GHz is not good
3666931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle         */
36674b50786546ce4c4fee555d66028991fe257b8811vandwalle        boolean use24Thresholds = false;
36684b50786546ce4c4fee555d66028991fe257b8811vandwalle        boolean homeNetworkBoost = false;
36694b50786546ce4c4fee555d66028991fe257b8811vandwalle        WifiConfiguration currentConfiguration = getCurrentWifiConfiguration();
36704b50786546ce4c4fee555d66028991fe257b8811vandwalle        if (currentConfiguration != null
36714b50786546ce4c4fee555d66028991fe257b8811vandwalle                && currentConfiguration.scanResultCache != null) {
36724b50786546ce4c4fee555d66028991fe257b8811vandwalle            currentConfiguration.setVisibility(12000);
36734b50786546ce4c4fee555d66028991fe257b8811vandwalle            if (currentConfiguration.visibility != null) {
36744b50786546ce4c4fee555d66028991fe257b8811vandwalle                if (currentConfiguration.visibility.rssi24 != WifiConfiguration.INVALID_RSSI
36754b50786546ce4c4fee555d66028991fe257b8811vandwalle                        && currentConfiguration.visibility.rssi24
36764b50786546ce4c4fee555d66028991fe257b8811vandwalle                        >= (currentConfiguration.visibility.rssi5-2)) {
36774b50786546ce4c4fee555d66028991fe257b8811vandwalle                    use24Thresholds = true;
36784b50786546ce4c4fee555d66028991fe257b8811vandwalle                }
36794b50786546ce4c4fee555d66028991fe257b8811vandwalle            }
3680ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle            if (currentConfiguration.scanResultCache.size() <= 6
36814b50786546ce4c4fee555d66028991fe257b8811vandwalle                && currentConfiguration.allowedKeyManagement.cardinality() == 1
36824b50786546ce4c4fee555d66028991fe257b8811vandwalle                && currentConfiguration.allowedKeyManagement.
36834b50786546ce4c4fee555d66028991fe257b8811vandwalle                    get(WifiConfiguration.KeyMgmt.WPA_PSK) == true) {
3684ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                // A PSK network with less than 6 known BSSIDs
3685931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                // This is most likely a home network and thus we want to stick to wifi more
36864b50786546ce4c4fee555d66028991fe257b8811vandwalle                homeNetworkBoost = true;
36874b50786546ce4c4fee555d66028991fe257b8811vandwalle            }
36884b50786546ce4c4fee555d66028991fe257b8811vandwalle        }
36897b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (homeNetworkBoost) sb.append(" hn");
36907b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (use24Thresholds) sb.append(" u24");
36914b50786546ce4c4fee555d66028991fe257b8811vandwalle
36924b50786546ce4c4fee555d66028991fe257b8811vandwalle        int rssi = mWifiInfo.getRssi() - 6 * mAggressiveHandover
36934b50786546ce4c4fee555d66028991fe257b8811vandwalle                + (homeNetworkBoost ? WifiConfiguration.HOME_NETWORK_RSSI_BOOST : 0);
36947b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(" rssi=%d ag=%d", rssi, mAggressiveHandover));
36957b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
36964b50786546ce4c4fee555d66028991fe257b8811vandwalle        boolean is24GHz = use24Thresholds || mWifiInfo.is24GHz();
36974b50786546ce4c4fee555d66028991fe257b8811vandwalle
36988c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle        boolean isBadRSSI = (is24GHz && rssi < mWifiConfigStore.thresholdBadRssi24)
36998c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                || (!is24GHz && rssi < mWifiConfigStore.thresholdBadRssi5);
37008c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle        boolean isLowRSSI = (is24GHz && rssi < mWifiConfigStore.thresholdLowRssi24)
37018c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                || (!is24GHz && mWifiInfo.getRssi() < mWifiConfigStore.thresholdLowRssi5);
37028c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle        boolean isHighRSSI = (is24GHz && rssi >= mWifiConfigStore.thresholdGoodRssi24)
37038c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                || (!is24GHz && mWifiInfo.getRssi() >= mWifiConfigStore.thresholdGoodRssi5);
370427355a942653264388e909a4276196ee63e57811vandwalle
37057b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (isBadRSSI) sb.append(" br");
37067b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (isLowRSSI) sb.append(" lr");
37077b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (isHighRSSI) sb.append(" hr");
37087b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
37090eebae7334d6129f7ca1344e4b20199794994358vandwalle        int penalizedDueToUserTriggeredDisconnect = 0;        // For debug information
37109f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (currentConfiguration!= null &&
37117b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                (mWifiInfo.txSuccessRate > 5 || mWifiInfo.rxSuccessRate > 5)) {
37129f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            if (isBadRSSI) {
37139f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                currentConfiguration.numTicksAtBadRSSI++;
37149f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                if (currentConfiguration.numTicksAtBadRSSI > 1000) {
37159f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // We remained associated for a compound amount of time while passing
37169f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // traffic, hence loose the corresponding user triggered disabled stats
37179f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (currentConfiguration.numUserTriggeredWifiDisableBadRSSI > 0) {
37189f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        currentConfiguration.numUserTriggeredWifiDisableBadRSSI--;
37199f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
37209f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (currentConfiguration.numUserTriggeredWifiDisableLowRSSI > 0) {
37219f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        currentConfiguration.numUserTriggeredWifiDisableLowRSSI--;
37229f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
37239f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0) {
37249f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI--;
37259f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
37269f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    currentConfiguration.numTicksAtBadRSSI = 0;
37279f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                }
372817e828848eebb4eb11d27ce32d02716334dd6011vandwalle                if (mWifiConfigStore.enableWifiCellularHandoverUserTriggeredAdjustment &&
372917e828848eebb4eb11d27ce32d02716334dd6011vandwalle                        (currentConfiguration.numUserTriggeredWifiDisableBadRSSI > 0
37300eebae7334d6129f7ca1344e4b20199794994358vandwalle                        || currentConfiguration.numUserTriggeredWifiDisableLowRSSI > 0
373117e828848eebb4eb11d27ce32d02716334dd6011vandwalle                        || currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0)) {
37320eebae7334d6129f7ca1344e4b20199794994358vandwalle                    score = score -5;
37330eebae7334d6129f7ca1344e4b20199794994358vandwalle                    penalizedDueToUserTriggeredDisconnect = 1;
37347b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" p1");
37350eebae7334d6129f7ca1344e4b20199794994358vandwalle                }
37369f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            } else if (isLowRSSI) {
37379f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                currentConfiguration.numTicksAtLowRSSI++;
37389f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                if (currentConfiguration.numTicksAtLowRSSI > 1000) {
37399f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // We remained associated for a compound amount of time while passing
37409f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // traffic, hence loose the corresponding user triggered disabled stats
37419f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (currentConfiguration.numUserTriggeredWifiDisableLowRSSI > 0) {
37429f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        currentConfiguration.numUserTriggeredWifiDisableLowRSSI--;
37439f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
37449f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0) {
37459f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI--;
37469f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
37479f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    currentConfiguration.numTicksAtLowRSSI = 0;
37489f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                }
374917e828848eebb4eb11d27ce32d02716334dd6011vandwalle                if (mWifiConfigStore.enableWifiCellularHandoverUserTriggeredAdjustment &&
375017e828848eebb4eb11d27ce32d02716334dd6011vandwalle                        (currentConfiguration.numUserTriggeredWifiDisableLowRSSI > 0
375117e828848eebb4eb11d27ce32d02716334dd6011vandwalle                        || currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0)) {
37520eebae7334d6129f7ca1344e4b20199794994358vandwalle                    score = score -5;
37530eebae7334d6129f7ca1344e4b20199794994358vandwalle                    penalizedDueToUserTriggeredDisconnect = 2;
37547b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" p2");
37550eebae7334d6129f7ca1344e4b20199794994358vandwalle                }
37569f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            } else if (!isHighRSSI) {
37579f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                currentConfiguration.numTicksAtNotHighRSSI++;
37589f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                if (currentConfiguration.numTicksAtNotHighRSSI > 1000) {
37599f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // We remained associated for a compound amount of time while passing
37609f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // traffic, hence loose the corresponding user triggered disabled stats
37619f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0) {
37629f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI--;
37639f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
37649f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    currentConfiguration.numTicksAtNotHighRSSI = 0;
37659f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                }
376617e828848eebb4eb11d27ce32d02716334dd6011vandwalle                if (mWifiConfigStore.enableWifiCellularHandoverUserTriggeredAdjustment &&
376717e828848eebb4eb11d27ce32d02716334dd6011vandwalle                        currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0) {
37680eebae7334d6129f7ca1344e4b20199794994358vandwalle                    score = score -5;
37690eebae7334d6129f7ca1344e4b20199794994358vandwalle                    penalizedDueToUserTriggeredDisconnect = 3;
37707b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    sb.append(" p3");
37710eebae7334d6129f7ca1344e4b20199794994358vandwalle                }
37729f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            }
377370468b47454c8657e8963932f2e08a3f4d7e3881vandwalle            sb.append(String.format(" ticks %d,%d,%d", currentConfiguration.numTicksAtBadRSSI,
377470468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    currentConfiguration.numTicksAtLowRSSI,
377570468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    currentConfiguration.numTicksAtNotHighRSSI));
37769f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
37779f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
37780eebae7334d6129f7ca1344e4b20199794994358vandwalle        if (PDBG) {
37790eebae7334d6129f7ca1344e4b20199794994358vandwalle            String rssiStatus = "";
37800eebae7334d6129f7ca1344e4b20199794994358vandwalle            if (isBadRSSI) rssiStatus += " badRSSI ";
37810eebae7334d6129f7ca1344e4b20199794994358vandwalle            else if (isHighRSSI) rssiStatus += " highRSSI ";
37820eebae7334d6129f7ca1344e4b20199794994358vandwalle            else if (isLowRSSI) rssiStatus += " lowRSSI ";
37830eebae7334d6129f7ca1344e4b20199794994358vandwalle            if (isBadLinkspeed) rssiStatus += " lowSpeed ";
37840eebae7334d6129f7ca1344e4b20199794994358vandwalle            loge("calculateWifiScore freq=" + Integer.toString(mWifiInfo.getFrequency())
37850eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " speed=" + Integer.toString(mWifiInfo.getLinkSpeed())
37860eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " score=" + Integer.toString(mWifiInfo.score)
37870eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + rssiStatus
37880eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " -> txbadrate=" + String.format( "%.2f", mWifiInfo.txBadRate )
37890eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " txgoodrate=" + String.format("%.2f", mWifiInfo.txSuccessRate)
37900eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " txretriesrate=" + String.format("%.2f", mWifiInfo.txRetriesRate)
37910eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " rxrate=" + String.format("%.2f", mWifiInfo.rxSuccessRate)
37920eebae7334d6129f7ca1344e4b20199794994358vandwalle                            + " userTriggerdPenalty" + penalizedDueToUserTriggeredDisconnect);
37930eebae7334d6129f7ca1344e4b20199794994358vandwalle        }
37940eebae7334d6129f7ca1344e4b20199794994358vandwalle
3795c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        if ((mWifiInfo.txBadRate >= 1) && (mWifiInfo.txSuccessRate < 3)
3796c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                && (isBadRSSI || isLowRSSI)) {
3797931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // Link is stuck
3798c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle            if (mWifiInfo.linkStuckCount < 5)
3799c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                mWifiInfo.linkStuckCount += 1;
38007b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            sb.append(String.format(" ls+=%d", mWifiInfo.linkStuckCount));
38014b50786546ce4c4fee555d66028991fe257b8811vandwalle            if (PDBG) loge(" bad link -> stuck count ="
38024b50786546ce4c4fee555d66028991fe257b8811vandwalle                    + Integer.toString(mWifiInfo.linkStuckCount));
3803c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        } else if (mWifiInfo.txSuccessRate > 2 || mWifiInfo.txBadRate < 0.1) {
3804c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle            if (mWifiInfo.linkStuckCount > 0)
3805c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                mWifiInfo.linkStuckCount -= 1;
38067b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            sb.append(String.format(" ls-=%d", mWifiInfo.linkStuckCount));
38074b50786546ce4c4fee555d66028991fe257b8811vandwalle            if (PDBG) loge(" good link -> stuck count ="
38084b50786546ce4c4fee555d66028991fe257b8811vandwalle                    + Integer.toString(mWifiInfo.linkStuckCount));
3809c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        }
3810c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
38117b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(" [%d", score));
38127b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
3813c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        if (mWifiInfo.linkStuckCount > 1) {
3814931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // Once link gets stuck for more than 3 seconds, start reducing the score
3815c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle            score = score - 2 * (mWifiInfo.linkStuckCount - 1);
381627355a942653264388e909a4276196ee63e57811vandwalle        }
38177b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(",%d", score));
381827355a942653264388e909a4276196ee63e57811vandwalle
381927355a942653264388e909a4276196ee63e57811vandwalle        if (isBadLinkspeed) {
3820a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle            score -= 4 ;
38217736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle            if (PDBG) {
38227736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle                loge(" isBadLinkspeed   ---> count=" + mBadLinkspeedcount
38237736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle                        + " score=" + Integer.toString(score));
38247736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle            }
382527355a942653264388e909a4276196ee63e57811vandwalle        } else if ((isGoodLinkspeed) && (mWifiInfo.txSuccessRate > 5)) {
3826931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            score += 4; // So as bad rssi alone dont kill us
382727355a942653264388e909a4276196ee63e57811vandwalle        }
38287b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(",%d", score));
382927355a942653264388e909a4276196ee63e57811vandwalle
383027355a942653264388e909a4276196ee63e57811vandwalle        if (isBadRSSI) {
383127355a942653264388e909a4276196ee63e57811vandwalle            if (mWifiInfo.badRssiCount < 7)
383227355a942653264388e909a4276196ee63e57811vandwalle                mWifiInfo.badRssiCount += 1;
383327355a942653264388e909a4276196ee63e57811vandwalle        } else if (isLowRSSI) {
38347b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            mWifiInfo.lowRssiCount = 1; // Dont increment the lowRssi count above 1
3835c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle            if (mWifiInfo.badRssiCount > 0) {
38367b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                // Decrement bad Rssi count
3837c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                mWifiInfo.badRssiCount -= 1;
3838c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle            }
383927355a942653264388e909a4276196ee63e57811vandwalle        } else {
384027355a942653264388e909a4276196ee63e57811vandwalle            mWifiInfo.badRssiCount = 0;
384127355a942653264388e909a4276196ee63e57811vandwalle            mWifiInfo.lowRssiCount = 0;
384227355a942653264388e909a4276196ee63e57811vandwalle        }
384327355a942653264388e909a4276196ee63e57811vandwalle
3844c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        score -= mWifiInfo.badRssiCount * 2 +  mWifiInfo.lowRssiCount ;
38457b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(",%d", score));
384627355a942653264388e909a4276196ee63e57811vandwalle
384727355a942653264388e909a4276196ee63e57811vandwalle        if (PDBG) loge(" badRSSI count" + Integer.toString(mWifiInfo.badRssiCount)
384827355a942653264388e909a4276196ee63e57811vandwalle                     + " lowRSSI count" + Integer.toString(mWifiInfo.lowRssiCount)
384927355a942653264388e909a4276196ee63e57811vandwalle                        + " --> score " + Integer.toString(score));
385027355a942653264388e909a4276196ee63e57811vandwalle
385127355a942653264388e909a4276196ee63e57811vandwalle
385227355a942653264388e909a4276196ee63e57811vandwalle        if (isHighRSSI) {
385327355a942653264388e909a4276196ee63e57811vandwalle            score += 5;
385427355a942653264388e909a4276196ee63e57811vandwalle            if (PDBG) loge(" isHighRSSI       ---> score=" + Integer.toString(score));
385527355a942653264388e909a4276196ee63e57811vandwalle        }
38567b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(",%d]", score));
38577b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle
38587b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        sb.append(String.format(" brc=%d lrc=%d", mWifiInfo.badRssiCount, mWifiInfo.lowRssiCount));
385927355a942653264388e909a4276196ee63e57811vandwalle
386027355a942653264388e909a4276196ee63e57811vandwalle        //sanitize boundaries
386127355a942653264388e909a4276196ee63e57811vandwalle        if (score > NetworkAgent.WIFI_BASE_SCORE)
386227355a942653264388e909a4276196ee63e57811vandwalle            score = NetworkAgent.WIFI_BASE_SCORE;
386327355a942653264388e909a4276196ee63e57811vandwalle        if (score < 0)
386427355a942653264388e909a4276196ee63e57811vandwalle            score = 0;
386527355a942653264388e909a4276196ee63e57811vandwalle
386627355a942653264388e909a4276196ee63e57811vandwalle        //report score
386727355a942653264388e909a4276196ee63e57811vandwalle        if (score != mWifiInfo.score) {
386827355a942653264388e909a4276196ee63e57811vandwalle            if (DBG) {
386927355a942653264388e909a4276196ee63e57811vandwalle                loge("calculateWifiScore() report new score " + Integer.toString(score));
387027355a942653264388e909a4276196ee63e57811vandwalle            }
387127355a942653264388e909a4276196ee63e57811vandwalle            mWifiInfo.score = score;
38726e51388c5b7d7840644570de5bc61edbd173b203vandwalle            if (mNetworkAgent != null) {
38736e51388c5b7d7840644570de5bc61edbd173b203vandwalle                mNetworkAgent.sendNetworkScore(score);
38746e51388c5b7d7840644570de5bc61edbd173b203vandwalle            }
387527355a942653264388e909a4276196ee63e57811vandwalle        }
38767b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        wifiScoringReport = sb.toString();
387727355a942653264388e909a4276196ee63e57811vandwalle    }
387827355a942653264388e909a4276196ee63e57811vandwalle
387927355a942653264388e909a4276196ee63e57811vandwalle    public double getTxPacketRate() {
388027355a942653264388e909a4276196ee63e57811vandwalle        if (mWifiInfo != null) {
388127355a942653264388e909a4276196ee63e57811vandwalle            return mWifiInfo.txSuccessRate;
388227355a942653264388e909a4276196ee63e57811vandwalle        }
388327355a942653264388e909a4276196ee63e57811vandwalle        return -1;
388427355a942653264388e909a4276196ee63e57811vandwalle    }
388527355a942653264388e909a4276196ee63e57811vandwalle
388627355a942653264388e909a4276196ee63e57811vandwalle    public double getRxPacketRate() {
388727355a942653264388e909a4276196ee63e57811vandwalle        if (mWifiInfo != null) {
388827355a942653264388e909a4276196ee63e57811vandwalle            return mWifiInfo.rxSuccessRate;
388927355a942653264388e909a4276196ee63e57811vandwalle        }
389027355a942653264388e909a4276196ee63e57811vandwalle        return -1;
389127355a942653264388e909a4276196ee63e57811vandwalle    }
389227355a942653264388e909a4276196ee63e57811vandwalle
3893931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle    /**
3894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Fetch TX packet counters on current connection
3895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void fetchPktcntNative(RssiPacketCountInfo info) {
3897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String pktcntPoll = mWifiNative.pktcntPoll();
3898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (pktcntPoll != null) {
3900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] lines = pktcntPoll.split("\n");
3901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String line : lines) {
3902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                String[] prop = line.split("=");
3903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (prop.length < 2) continue;
3904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
3905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (prop[0].equals("TXGOOD")) {
3906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        info.txgood = Integer.parseInt(prop[1]);
3907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (prop[0].equals("TXBAD")) {
3908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        info.txbad = Integer.parseInt(prop[1]);
3909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
3910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (NumberFormatException e) {
3911931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Ignore
3912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
39170ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti    private boolean clearIPv4Address(String iface) {
39180ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti        try {
39190ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti            InterfaceConfiguration ifcg = new InterfaceConfiguration();
39200ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti            ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
39210ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti            mNwService.setInterfaceConfig(iface, ifcg);
39220ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti            return true;
39230ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti        } catch (RemoteException e) {
39240ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti            return false;
39250ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti        }
39260ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti    }
39270ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti
3928badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    private boolean isProvisioned(LinkProperties lp) {
39296d66b5730446fa4df96c6dcda8612a64ed5bf383Erik Kline        return lp.isProvisioned() ||
39306d66b5730446fa4df96c6dcda8612a64ed5bf383Erik Kline               (mWifiConfigStore.isUsingStaticIp(mLastNetworkId) && lp.hasIPv4Address());
3931badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    }
3932badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti
3933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Updates mLinkProperties by merging information from various sources.
3935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * This is needed because the information in mLinkProperties comes from multiple sources (DHCP,
3937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * netlink, static configuration, ...). When one of these sources of information has updated
3938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * link properties, we can't just assign them to mLinkProperties or we'd lose track of the
3939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * information that came from other sources. Instead, when one of those sources has new
3940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * information, we update the object that tracks the information from that source and then
3941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * call this method to apply the change to mLinkProperties.
3942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The information in mLinkProperties is currently obtained as follows:
3944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * - Interface name: set in the constructor.
3945d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti     * - IPv4 and IPv6 addresses: netlink, passed in by mNetlinkTracker.
3946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * - IPv4 routes, DNS servers, and domains: DHCP.
3947a43d6d71ad51ce7fe54198d9b60d554208054eb8Lorenzo Colitti     * - IPv6 routes and DNS servers: netlink, passed in by mNetlinkTracker.
3948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * - HTTP proxy: the wifi config store.
3949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3950badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    private void updateLinkProperties(int reason) {
3951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        LinkProperties newLp = new LinkProperties();
3952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Interface name and proxy are locally configured.
3954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        newLp.setInterfaceName(mInterfaceName);
3955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        newLp.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
3956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3957a43d6d71ad51ce7fe54198d9b60d554208054eb8Lorenzo Colitti        // IPv4/v6 addresses, IPv6 routes and IPv6 DNS servers come from netlink.
3958ec474c010a79c12d24c34e79383b328cc53d5eceLorenzo Colitti        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
3959ec474c010a79c12d24c34e79383b328cc53d5eceLorenzo Colitti        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
3960c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
3961ec474c010a79c12d24c34e79383b328cc53d5eceLorenzo Colitti            newLp.addRoute(route);
3962ec474c010a79c12d24c34e79383b328cc53d5eceLorenzo Colitti        }
3963a43d6d71ad51ce7fe54198d9b60d554208054eb8Lorenzo Colitti        for (InetAddress dns : netlinkLinkProperties.getDnsServers()) {
3964a43d6d71ad51ce7fe54198d9b60d554208054eb8Lorenzo Colitti            newLp.addDnsServer(dns);
3965a43d6d71ad51ce7fe54198d9b60d554208054eb8Lorenzo Colitti        }
3966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3967a43d6d71ad51ce7fe54198d9b60d554208054eb8Lorenzo Colitti        // IPv4 routes, DNS servers and domains come from mDhcpResults.
3968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mDhcpResultsLock) {
3969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // Even when we're using static configuration, we don't need to look at the config
3970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // store, because static IP configuration also populates mDhcpResults.
39713b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti            if ((mDhcpResults != null)) {
39723b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
3973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    newLp.addRoute(route);
3974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
39753b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                for (InetAddress dns : mDhcpResults.dnsServers) {
397682d1c6aeadfa24797b314ae2b2a55717df064b57Robert Greenwalt                    newLp.addDnsServer(dns);
3977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
39783b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                newLp.setDomains(mDhcpResults.domains);
3979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3982e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        final boolean linkChanged = !newLp.equals(mLinkProperties);
3983badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        final boolean wasProvisioned = isProvisioned(mLinkProperties);
3984badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        final boolean isProvisioned = isProvisioned(newLp);
3985ac9667902d52ef3efdb53125080419fbbdc7ba80Erik Kline        final boolean lostIPv4Provisioning =
3986ac9667902d52ef3efdb53125080419fbbdc7ba80Erik Kline            mLinkProperties.hasIPv4Address() && !newLp.hasIPv4Address();
3987e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        final DetailedState detailedState = getNetworkDetailedState();
3988e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt
3989e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        if (linkChanged) {
3990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) {
3991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                log("Link configuration changed for netId: " + mLastNetworkId
3992badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                        + " old: " + mLinkProperties + " new: " + newLp);
3993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mLinkProperties = newLp;
39953c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt            if (TextUtils.isEmpty(mTcpBufferSizes) == false) {
39963c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt                mLinkProperties.setTcpBufferSizes(mTcpBufferSizes);
39973c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt            }
39987d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            if (mNetworkAgent != null) mNetworkAgent.sendLinkProperties(mLinkProperties);
3999e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        }
400014be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti
4001c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        if (DBG) {
4002c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            StringBuilder sb = new StringBuilder();
4003c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            sb.append("updateLinkProperties nid: " + mLastNetworkId);
4004c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            sb.append(" state: " + detailedState);
4005badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            sb.append(" reason: " + smToString(reason));
4006c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle
4007c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            if (mLinkProperties != null) {
4008c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                if (mLinkProperties.hasIPv4Address()) {
4009c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" v4");
4010c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4011c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                if (mLinkProperties.hasGlobalIPv6Address()) {
4012c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" v6");
4013c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4014c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                if (mLinkProperties.hasIPv4DefaultRoute()) {
4015c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" v4r");
4016c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4017c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                if (mLinkProperties.hasIPv6DefaultRoute()) {
4018c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" v6r");
4019c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4020c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                if (mLinkProperties.hasIPv4DnsServer()) {
4021c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" v4dns");
4022c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4023c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                if (mLinkProperties.hasIPv6DnsServer()) {
4024c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" v6dns");
4025c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4026badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                if (isProvisioned) {
4027c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                    sb.append(" isprov");
4028c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                }
4029c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            }
4030c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            loge(sb.toString());
4031c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        }
4032c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle
4033e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        // If we just configured or lost IP configuration, do the needful.
4034e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        // We don't just call handleSuccessfulIpConfiguration() or handleIpConfigurationLost()
4035e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        // here because those should only be called if we're attempting to connect or already
4036e0e491671f348cceb6e20fdc55438d8cfd2f07f1Robert Greenwalt        // connected, whereas updateLinkProperties can be called at any time.
4037badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        switch (reason) {
4038badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case DhcpStateMachine.DHCP_SUCCESS:
4039badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case CMD_STATIC_IP_SUCCESS:
4040badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                // IPv4 provisioning succeded. Advance to connected state.
4041badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL);
4042badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                if (!isProvisioned) {
4043badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // Can never happen unless DHCP reports success but isProvisioned thinks the
4044badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // resulting configuration is invalid (e.g., no IPv4 address, or the state in
4045badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // mLinkProperties is out of sync with reality, or there's a bug in this code).
4046badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // TODO: disconnect here instead. If our configuration is not usable, there's no
4047badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // point in staying connected, and if mLinkProperties is out of sync with
4048badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // reality, that will cause problems in the future.
4049badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    loge("IPv4 config succeeded, but not provisioned");
4050badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                }
4051badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
4052badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti
4053badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case DhcpStateMachine.DHCP_FAILURE:
4054ac9667902d52ef3efdb53125080419fbbdc7ba80Erik Kline                // DHCP failed. If we're not already provisioned, or we had IPv4 and now lost it,
4055ac9667902d52ef3efdb53125080419fbbdc7ba80Erik Kline                // give up and disconnect.
4056badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                // If we're already provisioned (e.g., IPv6-only network), stay connected.
4057ac9667902d52ef3efdb53125080419fbbdc7ba80Erik Kline                if (!isProvisioned || lostIPv4Provisioning) {
4058badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    sendMessage(CMD_IP_CONFIGURATION_LOST);
4059badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                } else {
4060badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // DHCP failed, but we're provisioned (e.g., if we're on an IPv6-only network).
4061badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL);
4062badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti
4063badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // To be sure we don't get stuck with a non-working network if all we had is
4064badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // IPv4, remove the IPv4 address from the interface (since we're using DHCP,
4065badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // and DHCP failed). If we had an IPv4 address before, the deletion of the
4066badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // address  will cause a CMD_UPDATE_LINKPROPERTIES. If the IPv4 address was
4067badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // necessary for provisioning, its deletion will cause us to disconnect.
4068badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    //
40690ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    // This shouldn't be needed, because on an IPv4-only network a DHCP failure will
40700ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    // have empty DhcpResults and thus empty LinkProperties, and isProvisioned will
40710ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    // not return true if we're using DHCP and don't have an IPv4 default route. So
40720ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    // for now it's only here for extra redundancy. However, it will increase
40730ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    // robustness if we move to getting IPv4 routes from netlink as well.
40740ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    loge("DHCP failure: provisioned, clearing IPv4 address.");
40750ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    if (!clearIPv4Address(mInterfaceName)) {
4076badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                        sendMessage(CMD_IP_CONFIGURATION_LOST);
4077badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    }
4078badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                }
4079badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
4080badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti
4081badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case CMD_STATIC_IP_FAILURE:
4082badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                // Static configuration was invalid, or an error occurred in applying it. Give up.
4083badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                sendMessage(CMD_IP_CONFIGURATION_LOST);
4084badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
4085badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti
4086badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case CMD_UPDATE_LINKPROPERTIES:
4087badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                // IP addresses, DNS servers, etc. changed. Act accordingly.
4088badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                if (wasProvisioned && !isProvisioned) {
4089badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // We no longer have a usable network configuration. Disconnect.
4090badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    sendMessage(CMD_IP_CONFIGURATION_LOST);
4091badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                } else if (!wasProvisioned && isProvisioned) {
4092badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // We have a usable IPv6-only config. Advance to connected state.
4093badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL);
4094badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                }
4095badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                if (linkChanged && getNetworkDetailedState() == DetailedState.CONNECTED) {
4096badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    // If anything has changed and we're already connected, send out a notification.
4097badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    sendLinkConfigurationChangedBroadcast();
4098badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                }
4099badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
4100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
410214be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti
4103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
4104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Clears all our link properties.
4105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
4106c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle     private void clearLinkProperties() {
4107c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         // Clear the link properties obtained from DHCP and netlink.
4108c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         synchronized (mDhcpResultsLock) {
41093b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti             if (mDhcpResults != null) {
41103b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                 mDhcpResults.clear();
4111c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle             }
4112c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         }
4113c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         mNetlinkTracker.clearLinkProperties();
4114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4115c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         // Now clear the merged link properties.
4116c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         mLinkProperties.clear();
4117c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle         if (mNetworkAgent != null) mNetworkAgent.sendLinkProperties(mLinkProperties);
4118c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle     }
4119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     /**
4121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle      * try to update default route MAC address.
4122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle      */
4123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle      private String updateDefaultRouteMacAddress(int timeout) {
4124c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle          String address = null;
4125c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle          for (RouteInfo route : mLinkProperties.getRoutes()) {
4126c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle              if (route.isDefaultRoute() && route.hasGateway()) {
4127c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                  InetAddress gateway = route.getGateway();
4128c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                  if (gateway instanceof Inet4Address) {
4129c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      if (PDBG) {
4130c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          loge("updateDefaultRouteMacAddress found Ipv4 default :"
4131c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                  + gateway.getHostAddress());
4132c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      }
4133c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      address = macAddressFromRoute(gateway.getHostAddress());
4134931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                     /* The gateway's MAC address is known */
4135c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      if ((address == null) && (timeout > 0)) {
4136c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          boolean reachable = false;
4137c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          try {
4138c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              reachable = gateway.isReachable(timeout);
4139c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          } catch (Exception e) {
4140c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              loge("updateDefaultRouteMacAddress exception reaching :"
4141c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                      + gateway.getHostAddress());
4142c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
4143c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          } finally {
4144c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              if (reachable == true) {
4145c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle
4146c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                  address = macAddressFromRoute(gateway.getHostAddress());
4147c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                  if (PDBG) {
4148c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                      loge("updateDefaultRouteMacAddress reachable (tried again) :"
4149c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                              + gateway.getHostAddress() + " found " + address);
4150c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                  }
4151c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              }
4152c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          }
4153c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      }
4154c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      if (address != null) {
4155c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                          mWifiConfigStore.setDefaultGwMacAddress(mLastNetworkId, address);
4156c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                      }
4157c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                  }
4158c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle              }
4159c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle          }
4160c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle          return address;
4161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle      }
4162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendScanResultsAvailableBroadcast() {
4164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
4165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendRssiChangeBroadcast(final int newRssi) {
417051991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn        try {
417151991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn            mBatteryStats.noteWifiRssiChanged(newRssi);
417251991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn        } catch (RemoteException e) {
417351991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn            // Won't happen.
417451991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn        }
4175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
4176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
4178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
4179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendNetworkStateChangeBroadcast(String bssid) {
4182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
4183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
4185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties));
4186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (bssid != null)
4187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
4188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mNetworkInfo.getDetailedState() == DetailedState.VERIFYING_POOR_LINK ||
4189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) {
4190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiManager.EXTRA_WIFI_INFO, new WifiInfo(mWifiInfo));
4191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
4193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendLinkConfigurationChangedBroadcast() {
4196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
4197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));
4199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
4203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
4204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
4206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
4210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Record the detailed state of a network.
4211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param state the new {@code DetailedState}
4212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
42139f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    private boolean setNetworkDetailedState(NetworkInfo.DetailedState state) {
42147806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        boolean hidden = false;
42157806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
42167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        if (linkDebouncing || isRoaming()) {
42177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // There is generally a confusion in the system about colluding
42187806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // WiFi Layer 2 state (as reported by supplicant) and the Network state
42197806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // which leads to multiple confusion.
42207806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            //
42217806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // If link is de-bouncing or roaming, we already have an IP address
42227806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // as well we were connected and are doing L2 cycles of
42237806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // reconnecting or renewing IP address to check that we still have it
42247806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // This L2 link flapping should ne be reflected into the Network state
42257806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // which is the state of the WiFi Network visible to Layer 3 and applications
42267806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // Note that once debouncing and roaming are completed, we will
42277806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // set the Network state to where it should be, or leave it as unchanged
42287806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            //
42297806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            hidden = true;
42307806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        }
4231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) {
4232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            log("setDetailed state, old ="
42337806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    + mNetworkInfo.getDetailedState() + " and new state=" + state
42347806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    + " hidden=" + hidden);
4235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
42369f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (mNetworkInfo.getExtraInfo() != null && mWifiInfo.getSSID() != null) {
42379f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            // Always indicate that SSID has changed
42389f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            if (!mNetworkInfo.getExtraInfo().equals(mWifiInfo.getSSID())) {
42399f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                if (DBG) {
42409f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    log("setDetailed state send new extra info"  + mWifiInfo.getSSID());
42419f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                }
42429f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                mNetworkInfo.setExtraInfo(mWifiInfo.getSSID());
42439f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                sendNetworkStateChangeBroadcast(null);
42449f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            }
42459f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
42469f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (hidden == true) {
42479f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            return false;
42489f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
4249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (state != mNetworkInfo.getDetailedState()) {
4251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setDetailedState(state, null, mWifiInfo.getSSID());
42524dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            if (mNetworkAgent != null) {
42539f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                mNetworkAgent.sendNetworkInfo(mNetworkInfo);
42544dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            }
42559f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            sendNetworkStateChangeBroadcast(null);
42569f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            return true;
4257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
42589f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        return false;
4259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private DetailedState getNetworkDetailedState() {
4262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mNetworkInfo.getDetailedState();
4263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private SupplicantState handleSupplicantStateChange(Message message) {
4267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
4268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        SupplicantState state = stateChangeResult.state;
4269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Supplicant state change
4270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // [31-13] Reserved for future use
4271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // [8 - 0] Supplicant state (as defined in SupplicantState.java)
4272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // 50023 supplicant_state_changed (custom|1|5)
4273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setSupplicantState(state);
4274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Network id is only valid when we start connecting
4275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (SupplicantState.isConnecting(state)) {
4276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiInfo.setNetworkId(stateChangeResult.networkId);
4277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
4278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
4279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setBSSID(stateChangeResult.BSSID);
4282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setSSID(stateChangeResult.wifiSsid);
4283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mSupplicantStateTracker.sendMessage(Message.obtain(message));
4285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return state;
4287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
4290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
4291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * using the interface, stopping DHCP & disabling interface
4292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
4293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleNetworkDisconnect() {
42944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        if (DBG) log("handleNetworkDisconnect: Stopping DHCP and clearing IP"
42954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
42964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                +" - "+ Thread.currentThread().getStackTrace()[3].getMethodName()
42974dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                +" - "+ Thread.currentThread().getStackTrace()[4].getMethodName()
42984dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                +" - "+ Thread.currentThread().getStackTrace()[5].getMethodName());
4299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
43002f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle
43019f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        clearCurrentConfigBSSID("handleNetworkDisconnect");
43029f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
4303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        stopDhcp();
4304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
4306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.clearInterfaceAddresses(mInterfaceName);
4307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.disableIpv6(mInterfaceName);
4308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
4309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to clear addresses or disable ipv6" + e);
4310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Reset data structures */
43137736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle        mBadLinkspeedcount = 0;
43144dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        mWifiInfo.reset();
43157806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        linkDebouncing = false;
43167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        /* Reset roaming parameters */
43177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE;
43188242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
43198242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        /**
43208242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         *  fullBandConnectedTimeIntervalMilli:
43218242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         *  - start scans at mWifiConfigStore.associatedPartialScanPeriodMilli seconds interval
43228242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         *  - exponentially increase to mWifiConfigStore.associatedFullScanMaxIntervalMilli
43238242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         *  Initialize to sane value = 20 seconds
43248242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle         */
43258242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle        fullBandConnectedTimeIntervalMilli = 20 * 1000;
4326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setNetworkDetailedState(DetailedState.DISCONNECTED);
43287d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        if (mNetworkAgent != null) {
43297d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
43307d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            mNetworkAgent = null;
43317d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        }
4332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
4333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Clear network properties */
4335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearLinkProperties();
4336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4337931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        /* Cend event to CM & network change broadcast */
4338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendNetworkStateChangeBroadcast(mLastBssid);
4339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4340931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        /* Cancel auto roam requests */
4341b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle        autoRoamSetBSSID(mLastNetworkId, "any");
4342b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
4343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mLastBssid= null;
43444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        registerDisconnected();
4345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
4346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleSupplicantConnectionLoss() {
4349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Socket connection can be lost when we do a graceful shutdown
4350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        * or when the driver is hung. Ensure supplicant is stopped here.
4351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        */
4352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiMonitor.killSupplicant(mP2pSupported);
4353ae0b5cce21686ad00fd0a3d5aab35fe2152c4737Vinit Deshapnde        mWifiNative.closeSupplicantConnection();
4354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendSupplicantConnectionChangedBroadcast(false);
4355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setWifiState(WIFI_STATE_DISABLED);
4356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void handlePreDhcpSetup() {
4359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDhcpActive = true;
4360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!mBluetoothConnectionActive) {
4361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /*
4362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * There are problems setting the Wi-Fi driver's power
4363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * mode to active when bluetooth coexistence mode is
4364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * enabled or sense.
4365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * <p>
4366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * We set Wi-Fi to active mode when
4367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * obtaining an IP address because we've found
4368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * compatibility issues with some routers with low power
4369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * mode.
4370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * <p>
4371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * In order for this active power mode to properly be set,
4372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * we disable coexistence mode until we're done with
4373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * obtaining an IP address.  One exception is if we
4374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * are currently connected to a headset, since disabling
4375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * coexistence would interrupt that connection.
4376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             */
4377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // Disable the coexistence mode
4378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.setBluetoothCoexistenceMode(
4379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
4380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4382931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        // Disable power save and suspend optimizations during DHCP
4383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Note: The order here is important for now. Brcm driver changes
4384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // power settings when we control suspend mode optimizations.
4385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // TODO: Remove this comment when the driver is fixed.
4386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
4387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setPowerSave(false);
4388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        stopBatchedScan();
4390b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        WifiNative.pauseScan();
4391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4392efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle        // Update link layer stats
4393efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle        getWifiLinkLayerStats(false);
4394efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle
4395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* P2p discovery breaks dhcp, shut it down in order to get through this */
4396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message msg = new Message();
4397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY;
4398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.arg1 = WifiP2pServiceImpl.ENABLED;
4399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.arg2 = DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE;
4400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.obj = mDhcpStateMachine;
4401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pChannel.sendMessage(msg);
4402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void startDhcp() {
4406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mDhcpStateMachine == null) {
4407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
4408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mContext, WifiStateMachine.this, mInterfaceName);
4409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDhcpStateMachine.registerForPreDhcpNotification();
4412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
4413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
44154dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    void renewDhcp() {
44164dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        if (mDhcpStateMachine == null) {
44174dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
44184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    mContext, WifiStateMachine.this, mInterfaceName);
44194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
44204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
44214dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        mDhcpStateMachine.registerForPreDhcpNotification();
44224dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_RENEW_DHCP);
44234dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    }
44244dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
4425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void stopDhcp() {
4426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mDhcpStateMachine != null) {
4427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* In case we were in middle of DHCP operation restore back powermode */
4428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            handlePostDhcpSetup();
4429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
4430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void handlePostDhcpSetup() {
4434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Restore power save and suspend optimizations */
4435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
4436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setPowerSave(true);
4437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, WifiP2pServiceImpl.DISABLED);
4439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Set the coexistence mode back to its default value
4441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setBluetoothCoexistenceMode(
4442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
4443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDhcpActive = false;
4445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        startBatchedScan();
4447b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        WifiNative.restartScan();
4448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4450badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    private void handleIPv4Success(DhcpResults dhcpResults, int reason) {
4451f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4452f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (PDBG) {
44533b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti            loge("wifistatemachine handleIPv4Success <" + dhcpResults.toString() + ">");
44543b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti            loge("link address " + dhcpResults.ipAddress);
4455f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
4456f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        synchronized (mDhcpResultsLock) {
4458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpResults = dhcpResults;
4459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
44604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
44613b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti        Inet4Address addr = (Inet4Address) dhcpResults.ipAddress.getAddress();
4462b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle        if (isRoaming()) {
44634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            if (addr instanceof Inet4Address) {
44644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                int previousAddress = mWifiInfo.getIpAddress();
44653b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                int newAddress = NetworkUtils.inetAddressToInt(addr);
44664dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                if (previousAddress != newAddress) {
446714be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    loge("handleIPv4Success, roaming and address changed" +
44684dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            mWifiInfo + " got: " + addr);
44694dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                } else {
44704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
44714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                }
44724dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            } else {
447314be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                loge("handleIPv4Success, roaming and didnt get an IPv4 address" +
44744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        addr.toString());
44754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            }
44764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
4477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setInetAddress(addr);
4478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setMeteredHint(dhcpResults.hasMeteredHint());
4479badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        updateLinkProperties(reason);
4480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
448214be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    private void handleSuccessfulIpConfiguration() {
4483931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        mLastSignalLevel = -1; // Force update of signal strength
4484c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        WifiConfiguration c = getCurrentWifiConfiguration();
4485c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        if (c != null) {
44868639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson            // Reset IP failure tracking
4487c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            c.numConnectionFailures = 0;
44888639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson
44898639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson            // Tell the framework whether the newly connected network is trusted or untrusted.
44903aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson            updateCapabilities(c);
4491c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        }
4492e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        if (c != null) {
4493e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            ScanResult result = getCurrentScanResult();
4494e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            if (result == null) {
4495e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                loge("WifiStateMachine: handleSuccessfulIpConfiguration and no scan results" +
4496e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        c.configKey());
4497e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            } else {
4498e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                // Clear the per BSSID failure count
4499e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                result.numIpConfigFailures = 0;
4500e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                // Clear the WHOLE BSSID blacklist, which means supplicant is free to retry
4501e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                // any BSSID, even though it may already have a non zero ip failure count,
4502e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                // this will typically happen if the user walks away and come back to his arrea
4503e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                // TODO: implement blacklisting based on a timer, i.e. keep BSSID blacklisted
4504e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                // in supplicant for a couple of hours or a day
4505a5283c01ac413e378e2261050cac3a6d6e9cf385vandwalle                mWifiNative.clearBlacklist();
4506e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            }
4507e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
450814be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    }
4509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4510badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    private void handleIPv4Failure(int reason) {
451114be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti        synchronized(mDhcpResultsLock) {
45123b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti             if (mDhcpResults != null) {
45133b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                 mDhcpResults.clear();
451414be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti             }
451514be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti        }
4516c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        if (PDBG) {
4517c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            loge("wifistatemachine handleIPv4Failure");
4518c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle        }
4519badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        updateLinkProperties(reason);
452014be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    }
452114be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti
452214be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti    private void handleIpConfigurationLost() {
4523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setInetAddress(null);
4524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiInfo.setMeteredHint(false);
4525c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle
4526e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        mWifiConfigStore.handleSSIDStateChange(mLastNetworkId, false,
4527e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                "DHCP FAILURE", mWifiInfo.getBSSID());
4528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* DHCP times out after about 30 seconds, we do a
4530c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle         * disconnect thru supplicant, we will let autojoin retry connecting to the network
4531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
4532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.disconnect();
4533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Current design is to not set the config on a running hostapd but instead
4536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * stop and start tethering when user changes config on a running access point
4537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
4538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: Add control channel setup through hostapd that allows changing config
4539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * on a running daemon
4540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
4541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void startSoftApWithConfig(final WifiConfiguration config) {
4542931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        // Start hostapd on a separate thread
4543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        new Thread(new Runnable() {
4544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            public void run() {
4545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
4546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mNwService.startAccessPoint(config, mInterfaceName);
4547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (Exception e) {
4548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Exception in softap start " + e);
4549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
4550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mNwService.stopAccessPoint(mInterfaceName);
4551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mNwService.startAccessPoint(config, mInterfaceName);
4552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (Exception e1) {
4553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Exception in softap re-start " + e1);
4554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_START_AP_FAILURE);
4555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return;
4556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
4557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
4558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) log("Soft AP start successful");
4559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendMessage(CMD_START_AP_SUCCESS);
4560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
4561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }).start();
4562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4564f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    /*
4565f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     * Read a MAC address in /proc/arp/table, used by WifistateMachine
4566f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     * so as to record MAC address of default gateway.
4567f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle     **/
4568f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private String macAddressFromRoute(String ipAddress) {
4569f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        String macAddress = null;
4570f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        BufferedReader reader = null;
4571f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        try {
4572f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            reader = new BufferedReader(new FileReader("/proc/net/arp"));
4573f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4574f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            // Skip over the line bearing colum titles
4575f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            String line = reader.readLine();
4576f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4577f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            while ((line = reader.readLine()) != null) {
4578f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                String[] tokens = line.split("[ ]+");
4579f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                if (tokens.length < 6) {
4580f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    continue;
4581f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                }
4582f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4583f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                // ARP column format is
4584f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                // Address HWType HWAddress Flags Mask IFace
4585f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                String ip = tokens[0];
4586f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                String mac = tokens[3];
4587f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4588f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                if (ipAddress.equals(ip)) {
4589f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    macAddress = mac;
4590f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    break;
4591f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                }
4592f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
4593f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4594f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (macAddress == null) {
4595f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                loge("Did not find remoteAddress {" + ipAddress + "} in " +
4596f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        "/proc/net/arp");
4597f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
4598f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4599f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        } catch (FileNotFoundException e) {
4600f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            loge("Could not open /proc/net/arp to lookup mac address");
4601f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        } catch (IOException e) {
4602f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            loge("Could not read /proc/net/arp to lookup mac address");
4603f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        } finally {
4604f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            try {
4605f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                if (reader != null) {
4606f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    reader.close();
4607f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                }
4608f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            } catch (IOException e) {
4609f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                // Do nothing
4610f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
4611f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
4612f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        return macAddress;
4613f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4614f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
46157d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt
46167d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt    private class WifiNetworkFactory extends NetworkFactory {
46177d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        public WifiNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities f) {
46187d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            super(l, c, TAG, f);
46197d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        }
46208639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson
46218639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson        @Override
46228639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
46230af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti            ++mConnectionRequests;
4624ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        }
4625ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4626ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        @Override
4627ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        protected void releaseNetworkFor(NetworkRequest networkRequest) {
4628ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson            --mConnectionRequests;
4629ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        }
4630ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4631ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
4632ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson            pw.println("mConnectionRequests " + mConnectionRequests);
4633ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        }
4634ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4635ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson    }
4636ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4637ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson    private class UntrustedWifiNetworkFactory extends NetworkFactory {
4638ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        private int mUntrustedReqCount;
4639ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4640ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        public UntrustedWifiNetworkFactory(Looper l, Context c, String tag, NetworkCapabilities f) {
4641ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson            super(l, c, tag, f);
4642ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        }
4643ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4644ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        @Override
4645ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
46468639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson            if (!networkRequest.networkCapabilities.hasCapability(
46478639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                    NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
46488639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                if (++mUntrustedReqCount == 1) {
46498639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                    mWifiAutoJoinController.setAllowUntrustedConnections(true);
46508639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                }
46518639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson            }
46527d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        }
46538639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson
46548639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson        @Override
46558639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson        protected void releaseNetworkFor(NetworkRequest networkRequest) {
46568639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson            if (!networkRequest.networkCapabilities.hasCapability(
46578639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                    NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
46588639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                if (--mUntrustedReqCount == 0) {
46598639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                    mWifiAutoJoinController.setAllowUntrustedConnections(false);
46608639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson                }
46618639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson            }
46627d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        }
46630af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti
46640af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
46650af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti            pw.println("mUntrustedReqCount " + mUntrustedReqCount);
46660af9c80053bd2736d5bea095b363d6a0c8ce71d0Lorenzo Colitti        }
46677d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt    }
46689f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle
46699f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle    void maybeRegisterNetworkFactory() {
46709f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle        if (mNetworkFactory == null) {
46719f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle            checkAndSetConnectivityInstance();
46729f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle            if (mCm != null) {
46739f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle                mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext,
46749f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle                        NETWORKTYPE, mNetworkCapabilitiesFilter);
46759f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle                mNetworkFactory.setScoreFilter(60);
46769f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle                mNetworkFactory.register();
4677ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson
4678ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson                // We can't filter untrusted network in the capabilities filter because a trusted
4679ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson                // network would still satisfy a request that accepts untrusted ones.
4680ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson                mUntrustedNetworkFactory = new UntrustedWifiNetworkFactory(getHandler().getLooper(),
4681ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson                        mContext, NETWORKTYPE_UNTRUSTED, mNetworkCapabilitiesFilter);
4682ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson                mUntrustedNetworkFactory.setScoreFilter(Integer.MAX_VALUE);
4683ebe870ef4051da2fc307114ed3c14927f548d9d4Jeff Davidson                mUntrustedNetworkFactory.register();
46849f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle            }
46859f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle        }
46869f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle    }
46879f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle
4688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /********************************************************
4689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * HSM states
4690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *******************************************************/
4691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DefaultState extends State {
4693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
4694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
4695f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
4696f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
4697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
46983831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
46993831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                    AsyncChannel ac = (AsyncChannel) message.obj;
47003831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                    if (ac == mWifiP2pChannel) {
47013831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                        if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
47023831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                            mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
47033831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                        } else {
47043831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                            loge("WifiP2pService connection failure, error=" + message.arg1);
47053831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                        }
4706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
47073831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                        loge("got HALF_CONNECTED for unknown channel");
4708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
4709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
47103831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                }
47113831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
47123831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                    AsyncChannel ac = (AsyncChannel) message.obj;
47133831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                    if (ac == mWifiP2pChannel) {
47143831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                        loge("WifiP2pService channel lost, message.arg1 =" + message.arg1);
47153831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                        //TODO: Re-establish connection to state machine after a delay
4716931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // mWifiP2pChannel.connect(mContext, getHandler(),
47170888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle                        // mWifiP2pManager.getMessenger());
47183831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                    }
4719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
47203831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt                }
4721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
4722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mBluetoothConnectionActive = (message.arg1 !=
4723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            BluetoothAdapter.STATE_DISCONNECTED);
4724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Synchronous call returns */
4726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_PING_SUPPLICANT:
4727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_NETWORK:
4728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ADD_OR_UPDATE_NETWORK:
4729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REMOVE_NETWORK:
4730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SAVE_CONFIG:
4731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, message.what, FAILURE);
4732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4733a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                case CMD_GET_CAPABILITY_FREQ:
4734a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    replyToMessage(message, message.what, null);
4735a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    break;
4736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_GET_CONFIGURED_NETWORKS:
4737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, message.what, (List<WifiConfiguration>) null);
4738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
47399878c61bbd81176561991be025af44efc67332feWenchao Tong                case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS:
47409878c61bbd81176561991be025af44efc67332feWenchao Tong                    replyToMessage(message, message.what, (List<WifiConfiguration>) null);
47419878c61bbd81176561991be025af44efc67332feWenchao Tong                    break;
4742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_RSSI_POLL:
4743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mEnableRssiPolling = (message.arg1 == 1);
4744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_HIGH_PERF_MODE:
4746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == 1) {
4747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, false);
4748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
4749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, true);
4750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
4751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_BOOT_COMPLETED:
4753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    String countryCode = mPersistedCountryCode;
4754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (TextUtils.isEmpty(countryCode) == false) {
4755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        Settings.Global.putString(mContext.getContentResolver(),
4756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                Settings.Global.WIFI_COUNTRY_CODE,
4757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                countryCode);
4758931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // It may be that the state transition that should send this info
4759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // to the driver happened between mPersistedCountryCode getting set
4760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // and now, so simply persisting it here would mean we have sent
4761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // nothing to the driver.  Send the cmd so it might be set now.
47629c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        int sequenceNum = mCountryCodeSequence.incrementAndGet();
47639c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE,
47649c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                                sequenceNum, 0, countryCode);
4765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
47669f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle                    maybeRegisterNetworkFactory();
4767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_BATCHED_SCAN:
4769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    recordBatchedScanSettings(message.arg1, message.arg2, (Bundle)message.obj);
4770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_POLL_BATCHED_SCAN:
4772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleBatchedScanPollRequest();
4773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_NEXT_BATCHED_SCAN:
4775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    startNextBatchedScan();
4776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
477782199a285f4a45a46b44eb8253999aa918534753vandwalle                case CMD_SCREEN_STATE_CHANGED:
47787c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                    handleScreenStateChanged(message.arg1 != 0,
47797c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                            /* startBackgroundScanIfNeeded = */ false);
478082199a285f4a45a46b44eb8253999aa918534753vandwalle                    break;
4781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Discard */
4782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
4783ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
4784ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    break;
4785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
4786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
4787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT_FAILED:
4788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
4789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
4790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DELAYED_STOP_DRIVER:
4791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DRIVER_START_TIMED_OUT:
4792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
4793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP_SUCCESS:
4794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP_FAILURE:
4795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
4796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_STATE_CHANGE:
4797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
4798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISCONNECT:
4799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
4800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
4801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RELOAD_TLS_AND_RECONNECT:
4802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
4803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
4804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
4805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
4806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SCAN_RESULTS_EVENT:
4807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
4808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
4809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
4810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_OVERLAP_EVENT:
4811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_BLACKLIST_NETWORK:
4812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_CLEAR_BLACKLIST:
4813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
4814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
4815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
4816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RSSI_POLL:
4817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_ALL_NETWORKS:
4818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
4819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
4820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                /* Handled by WifiApConfigStore */
4821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_AP_CONFIG:
4822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_AP_CONFIG_COMPLETED:
4823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REQUEST_AP_CONFIG:
4824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RESPONSE_AP_CONFIG:
4825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
4826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
4827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_NO_NETWORKS_PERIODIC_SCAN:
4828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISABLE_P2P_RSP:
482940ff222cec1bd05879edb53abc75c6deead734cavandwalle                case WifiMonitor.SUP_REQUEST_IDENTITY:
48307806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                case CMD_TEST_NETWORK_DISCONNECT:
48317806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER:
483233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                case WifiMonitor.SUP_REQUEST_SIM_AUTH:
4833e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                case CMD_TARGET_BSSID:
4834be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                case CMD_AUTO_CONNECT:
4835be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                case CMD_AUTO_ROAM:
4836be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                case CMD_AUTO_SAVE_NETWORK:
48372f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                case CMD_ASSOCIATED_BSSID:
4838e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                case CMD_UNWANTED_NETWORK:
4839e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                case CMD_DISCONNECTING_WATCHDOG_TIMER:
4840a0708b09ad17b086c008ab100aec7143d7613c80vandwalle                case CMD_ROAM_WATCHDOG_TIMER:
48412ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                case CMD_DISABLE_EPHEMERAL_NETWORK:
4842ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
4843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_ON_QUIT:
4845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDhcpStateMachine = null;
4846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_SUSPEND_OPT_ENABLED:
4848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == 1) {
4849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSuspendWakeLock.release();
4850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, true);
4851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
4852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, false);
4853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
4854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.DRIVER_HUNG_EVENT:
4856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setSupplicantRunning(false);
4857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setSupplicantRunning(true);
4858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.CONNECT_NETWORK:
4860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
4861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.FORGET_NETWORK:
4864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
4865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.SAVE_NETWORK:
4868b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
4869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
4870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.START_WPS:
4873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.WPS_FAILED,
4874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.CANCEL_WPS:
4877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.CANCEL_WPS_FAILED,
4878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.DISABLE_NETWORK:
4881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
4882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.RSSI_PKTCNT_FETCH:
4885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED,
4886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.BUSY);
4887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4888048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande                case CMD_GET_SUPPORTED_FEATURES:
4889981e966999f4448a682084d6657d07bab2bbc13eVinit Deshpande                    if (WifiNative.startHal()) {
4890981e966999f4448a682084d6657d07bab2bbc13eVinit Deshpande                        int featureSet = WifiNative.getSupportedFeatureSet();
4891048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande                        replyToMessage(message, message.what, featureSet);
4892981e966999f4448a682084d6657d07bab2bbc13eVinit Deshpande                    } else {
4893048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande                        replyToMessage(message, message.what, 0);
4894981e966999f4448a682084d6657d07bab2bbc13eVinit Deshpande                    }
4895981e966999f4448a682084d6657d07bab2bbc13eVinit Deshpande                    break;
4896200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                case CMD_GET_LINK_LAYER_STATS:
4897200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    // Not supported hence reply with error message
4898200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    replyToMessage(message, message.what, null);
4899200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    break;
4900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
4901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    NetworkInfo info = (NetworkInfo) message.obj;
4902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mP2pConnected.set(info.isConnected());
4903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST:
4905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTemporarilyDisconnectWifi = (message.arg1 == 1);
4906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE);
4907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4908d60cf2efc576f016506ebe6d8a83b4a6217b2e0eLorenzo Colitti                /* Link configuration (IP address, DNS, ...) changes notified via netlink */
4909badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                case CMD_UPDATE_LINKPROPERTIES:
4910badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                    updateLinkProperties(CMD_UPDATE_LINKPROPERTIES);
491114be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    break;
491214be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                case CMD_IP_CONFIGURATION_SUCCESSFUL:
491314be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                case CMD_IP_CONFIGURATION_LOST:
4914ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
491514be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    break;
4916c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                case CMD_GET_CONNECTION_STATISTICS:
4917c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                    replyToMessage(message, message.what, mWifiConnectionStatistics);
4918c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                    break;
4919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
4920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Error! unhandled message" + message);
4921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
4922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
4923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
4924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
4926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class InitialState extends State {
4928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
4929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
4930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.unloadDriver();
4931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mWifiP2pChannel == null) {
4933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiP2pChannel = new AsyncChannel();
4934f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                mWifiP2pChannel.connect(mContext, getHandler(),
4935f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                    mWifiP2pServiceImpl.getP2pStateMachineMessenger());
4936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
4937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mWifiApConfigChannel == null) {
4939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiApConfigChannel = new AsyncChannel();
4940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
4941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mContext, getHandler());
4942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                wifiApConfigStore.loadApConfiguration();
4943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiApConfigChannel.connectSync(mContext, getHandler(),
4944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        wifiApConfigStore.getMessenger());
4945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
4946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
4947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
4948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
4949f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
4950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
4951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
4952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.loadDriver()) {
4953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
4954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNwService.wifiFirmwareReload(mInterfaceName, "STA");
4955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (Exception e) {
4956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Failed to reload STA firmware " + e);
4957931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                            // Continue
4958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
4959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
4961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // A runtime crash can leave the interface up and
496208b2a6f380652e7836687632a10e5183fd7ac689Lorenzo Colitti                            // IP addresses configured, and this affects
496308b2a6f380652e7836687632a10e5183fd7ac689Lorenzo Colitti                            // connectivity when supplicant starts up.
496408b2a6f380652e7836687632a10e5183fd7ac689Lorenzo Colitti                            // Ensure interface is down and we have no IP
496508b2a6f380652e7836687632a10e5183fd7ac689Lorenzo Colitti                            // addresses before a supplicant start.
4966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNwService.setInterfaceDown(mInterfaceName);
496708b2a6f380652e7836687632a10e5183fd7ac689Lorenzo Colitti                            mNwService.clearInterfaceAddresses(mInterfaceName);
496808b2a6f380652e7836687632a10e5183fd7ac689Lorenzo Colitti
4969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // Set privacy extensions
4970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
4971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                           // IPv6 is enabled only as long as access point is connected since:
4973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                           // - IPv6 addresses and routes stick around after disconnection
4974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                           // - kernel is unaware when connected and fails to start IPv6 negotiation
4975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                           // - kernel can start autoconfiguration when 802.1x is not complete
4976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNwService.disableIpv6(mInterfaceName);
4977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (RemoteException re) {
4978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Unable to change interface settings: " + re);
4979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (IllegalStateException ie) {
4980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Unable to change interface settings: " + ie);
4981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
4982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
4983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                       /* Stop a running supplicant after a runtime restart
4984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        * Avoids issues with drivers that do not handle interface down
4985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        * on a running supplicant properly.
4986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        */
4987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiMonitor.killSupplicant(mP2pSupported);
4988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if(mWifiNative.startSupplicant(mP2pSupported)) {
4989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            setWifiState(WIFI_STATE_ENABLING);
4990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) log("Supplicant start successful");
4991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiMonitor.startMonitoring();
4992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            transitionTo(mSupplicantStartingState);
4993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
4994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Failed to start supplicant!");
4995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
4996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
4997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to load driver");
4998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
4999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
5001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.loadDriver()) {
5002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setWifiApState(WIFI_AP_STATE_ENABLING);
5003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mSoftApStartingState);
5004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to load driver for softap");
5006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class SupplicantStartingState extends State {
5015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private void initializeWpsDetails() {
5016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String detail;
5017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            detail = SystemProperties.get("ro.product.name", "");
5018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setDeviceName(detail)) {
5019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set device name " +  detail);
5020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            detail = SystemProperties.get("ro.product.manufacturer", "");
5022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setManufacturer(detail)) {
5023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set manufacturer " + detail);
5024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            detail = SystemProperties.get("ro.product.model", "");
5026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setModelName(detail)) {
5027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set model name " + detail);
5028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            detail = SystemProperties.get("ro.product.model", "");
5030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setModelNumber(detail)) {
5031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set model number " + detail);
5032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            detail = SystemProperties.get("ro.serialno", "");
5034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setSerialNumber(detail)) {
5035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set serial number " + detail);
5036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setConfigMethods("physical_display virtual_push_button")) {
5038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set WPS config methods");
5039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiNative.setDeviceType(mPrimaryDeviceType)) {
5041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                loge("Failed to set primary device type " + mPrimaryDeviceType);
5042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5047f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5048f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
5051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Supplicant connection established");
5052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiState(WIFI_STATE_ENABLED);
5053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSupplicantRestartCount = 0;
5054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Reset the supplicant state to indicate the supplicant
5055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * state is not known at this time */
5056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
5057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Initialize data structures */
5058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mLastBssid = null;
5059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
5060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mLastSignalLevel = -1;
5061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
50630a696d168d7ad98ab5084d2a16e3d02c545a85aaVinit Deshapnde                    mWifiNative.enableSaveConfig();
5064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiConfigStore.loadAndEnableAllNetworks();
5065a0708b09ad17b086c008ab100aec7143d7613c80vandwalle                    if (mWifiConfigStore.enableVerboseLogging > 0) {
5066a0708b09ad17b086c008ab100aec7143d7613c80vandwalle                        enableVerboseLogging(mWifiConfigStore.enableVerboseLogging);
5067a0708b09ad17b086c008ab100aec7143d7613c80vandwalle                    }
50680eebae7334d6129f7ca1344e4b20199794994358vandwalle                    if (mWifiConfigStore.associatedPartialScanPeriodMilli < 0) {
50690eebae7334d6129f7ca1344e4b20199794994358vandwalle                        mWifiConfigStore.associatedPartialScanPeriodMilli = 0;
5070e67ec726c07410073575473c0f50dc737629f5davandwalle                    }
5071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    initializeWpsDetails();
5072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendSupplicantConnectionChangedBroadcast(true);
5074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDriverStartedState);
5075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
5077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
5078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to setup control channel, restart supplicant");
5079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiMonitor.killSupplicant(mP2pSupported);
5080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInitialState);
5081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
5082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed " + mSupplicantRestartCount +
5084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                " times to start supplicant, unload driver");
5085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSupplicantRestartCount = 0;
5086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setWifiState(WIFI_STATE_UNKNOWN);
5087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInitialState);
5088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
5091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
5092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
5093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
5094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
5096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
5097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
5098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
5099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
5100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
5101ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
5102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
5103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class SupplicantStartedState extends State {
5112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
5114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Wifi is available as long as we have a connection to supplicant */
5115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setIsAvailable(true);
51163831a926f6762a3b4c398da51cc67e9d81572458Robert Greenwalt            if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo);
5117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int defaultInterval = mContext.getResources().getInteger(
5119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    R.integer.config_wifi_supplicant_scan_interval);
5120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSupplicantScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
5122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
5123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    defaultInterval);
5124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000);
512633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            mWifiNative.setExternalSim(true);
5127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5128eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande            setRandomMacOui();
5129be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            mWifiNative.enableAutoConnect(false);
5130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5131eedd70ee3fa7f161ea1f4ae26543ac927e82a681Vinit Deshpande
5132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
5138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mP2pSupported) {
5139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mWaitForP2pDisableState);
5140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mSupplicantStoppingState);
5142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
5145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Connection lost, restart supplicant");
5146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleSupplicantConnectionLoss();
5147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleNetworkDisconnect();
5148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
5149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mP2pSupported) {
5150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mWaitForP2pDisableState);
5151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInitialState);
5153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
5155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SCAN_RESULTS_EVENT:
51579f2b11623eec3b20edc93e30f94b263f287a4ca3vandwalle                    maybeRegisterNetworkFactory(); // Make sure our NetworkFactory is registered
51580eebae7334d6129f7ca1344e4b20199794994358vandwalle                    closeRadioScanStats();
51597b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    noteScanEnd();
5160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setScanResults();
51619086afccf6938a49eb9a2cd248917c1cb0943942vandwalle                    if (mIsFullScanOngoing || mSendScanResultsBroadcast) {
5162765b9dc1c45bbeed87243d21cc5938bd5f1ba0d4Vinit Deshpande                        /* Just updated results from full scan, let apps know about this */
5163765b9dc1c45bbeed87243d21cc5938bd5f1ba0d4Vinit Deshpande                        sendScanResultsAvailableBroadcast();
5164765b9dc1c45bbeed87243d21cc5938bd5f1ba0d4Vinit Deshpande                    }
51659086afccf6938a49eb9a2cd248917c1cb0943942vandwalle                    mSendScanResultsBroadcast = false;
5166a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    mIsScanOngoing = false;
5167a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    mIsFullScanOngoing = false;
5168a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    if (mBufferedScanMsg.size() > 0)
5169a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                        sendMessage(mBufferedScanMsg.remove());
5170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_PING_SUPPLICANT:
5172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean ok = mWifiNative.ping();
5173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
5174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5175a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                case CMD_GET_CAPABILITY_FREQ:
5176a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    String freqs = mWifiNative.getFreqCapability();
5177a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    replyToMessage(message, message.what, freqs);
5178a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    break;
5179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
5180a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    /* Cannot start soft AP while in client mode */
5181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Failed to start soft AP with a running supplicant");
5182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiApState(WIFI_AP_STATE_FAILED);
5183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
5185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mOperationalMode = message.arg1;
5186abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle                    mWifiConfigStore.
5187abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle                            setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
5188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5189e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                case CMD_TARGET_BSSID:
5190e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    // Trying to associate to this BSSID
5191e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    if (message.obj != null) {
5192e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        mTargetRoamBSSID = (String) message.obj;
5193e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    }
5194e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                    break;
5195200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                case CMD_GET_LINK_LAYER_STATS:
51967b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    WifiLinkLayerStats stats = getWifiLinkLayerStats(DBG);
51977b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    if (stats == null) {
5198048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande                        // When firmware doesnt support link layer stats, return an empty object
5199048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande                        stats = new WifiLinkLayerStats();
5200200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    }
5201200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    replyToMessage(message, message.what, stats);
5202200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    break;
5203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
5211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setIsAvailable(false);
52127d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo);
5213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class SupplicantStoppingState extends State {
5217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
5219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Send any reset commands to supplicant before shutting it down */
5220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            handleNetworkDisconnect();
5221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mDhcpStateMachine != null) {
5222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mDhcpStateMachine.doQuit();
5223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5225005c1ef113192f898499a407dd266393a8d6b076vandwalle            String suppState = System.getProperty("init.svc.wpa_supplicant");
5226005c1ef113192f898499a407dd266393a8d6b076vandwalle            if (suppState == null) suppState = "unknown";
5227005c1ef113192f898499a407dd266393a8d6b076vandwalle            String p2pSuppState = System.getProperty("init.svc.p2p_supplicant");
5228005c1ef113192f898499a407dd266393a8d6b076vandwalle            if (p2pSuppState == null) p2pSuppState = "unknown";
5229005c1ef113192f898499a407dd266393a8d6b076vandwalle
5230005c1ef113192f898499a407dd266393a8d6b076vandwalle            loge("SupplicantStoppingState: stopSupplicant "
5231005c1ef113192f898499a407dd266393a8d6b076vandwalle                    + " init.svc.wpa_supplicant=" + suppState
5232005c1ef113192f898499a407dd266393a8d6b076vandwalle                    + " init.svc.p2p_supplicant=" + p2pSuppState);
5233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiMonitor.stopSupplicant();
5234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Send ourselves a delayed message to indicate failure after a wait time */
5236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(CMD_STOP_SUPPLICANT_FAILED,
5237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mSupplicantStopFailureToken, 0), SUPPLICANT_RESTART_INTERVAL_MSECS);
5238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setWifiState(WIFI_STATE_DISABLING);
5239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
5240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5243f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5244f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
5247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Supplicant connection received while stopping");
5248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
5250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Supplicant connection lost");
5251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleSupplicantConnectionLoss();
5252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInitialState);
5253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT_FAILED:
5255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == mSupplicantStopFailureToken) {
5256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Timed out on a supplicant stop, kill and proceed");
5257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleSupplicantConnectionLoss();
5258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInitialState);
5259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
5262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
5263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
5264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
5265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
5267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
5268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
5269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
5270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
5271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
5272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
5273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DriverStartingState extends State {
5282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private int mTries;
5283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
5285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mTries = 1;
5286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Send ourselves a delayed message to start driver a second time */
5287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(CMD_DRIVER_START_TIMED_OUT,
5288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ++mDriverStartToken, 0), DRIVER_START_TIME_OUT_MSECS);
5289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5292f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5293f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
5296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    SupplicantState state = handleSupplicantStateChange(message);
5297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* If suplicant is exiting out of INTERFACE_DISABLED state into
5298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * a state that indicates driver has started, it is ready to
5299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * receive driver commands
5300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     */
5301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (SupplicantState.isDriverActive(state)) {
5302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDriverStartedState);
5303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DRIVER_START_TIMED_OUT:
5306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == mDriverStartToken) {
5307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mTries >= 2) {
5308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Failed to start driver after " + mTries);
5309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            transitionTo(mDriverStoppedState);
5310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
5311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Driver start failed, retrying");
5312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWakeLock.acquire();
5313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiNative.startDriver();
5314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWakeLock.release();
5315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ++mTries;
5317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            /* Send ourselves a delayed message to start driver again */
5318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessageDelayed(obtainMessage(CMD_DRIVER_START_TIMED_OUT,
5319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                        ++mDriverStartToken, 0), DRIVER_START_TIME_OUT_MSECS);
5320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
5321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Queue driver commands & connection events */
5324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
5326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
5327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
5328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
5329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
5330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_OVERLAP_EVENT:
5331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
5332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
5333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
5334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
5335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
5336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISCONNECT:
5337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
5338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
5339ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
5340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
5341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
53429f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                case WifiMonitor.SCAN_RESULTS_EVENT:
53439f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // Loose scan results obtained in Driver Starting state, they can only confuse
53449f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    // the state machine
53459f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    break;
5346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DriverStartedState extends State {
5354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
5356f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5357f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (PDBG) {
53588242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                loge("DriverStartedState enter");
5359f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
5360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mIsRunning = true;
5361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mInDelayedStop = false;
5362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDelayedStopCounter++;
5363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            updateBatteryWorkSource(null);
5364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /**
5365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
5366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * When this mode is on, some of the low-level scan parameters used by the
5367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * driver are changed to reduce interference with bluetooth
5368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             */
5369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
5370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* set country code */
5371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setCountryCode();
5372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* set frequency band of operation */
5373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setFrequencyBand();
5374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* initialize network state */
5375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setNetworkDetailedState(DetailedState.DISCONNECTED);
5376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Remove any filtering on Multicast v6 at start */
5378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.stopFilteringMulticastV6Packets();
5379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Reset Multicast v4 filtering state */
5381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mFilteringMulticastV4Packets.get()) {
5382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.startFilteringMulticastV4Packets();
5383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
5384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.stopFilteringMulticastV4Packets();
5385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpActive = false;
5388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            startBatchedScan();
5390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mOperationalMode != CONNECT_MODE) {
5392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.disconnect();
5393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiConfigStore.disableAllNetworks();
5394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
5395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiState(WIFI_STATE_DISABLED);
5396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
5397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                transitionTo(mScanModeState);
5398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
5399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Status pulls in the current supplicant state and network connection state
5401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // events over the monitor connection. This helps framework sync up with
5402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // current supplicant state
54039f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // TODO: actually check th supplicant status string and make sure the supplicant
54049f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // is in disconnecte4d state.
5405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.status();
54069f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // Transitioning to Disconnected state will trigger a scan and subsequently AutoJoin
5407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                transitionTo(mDisconnectedState);
5408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // We may have missed screen update at boot
5411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mScreenBroadcastReceived.get() == false) {
5412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                PowerManager powerManager = (PowerManager)mContext.getSystemService(
5413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        Context.POWER_SERVICE);
54147c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                handleScreenStateChanged(powerManager.isScreenOn(),
54157c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                        /* startBackgroundScanIfNeeded = */ false);
5416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
5417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Set the right suspend mode settings
5418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.setSuspendOptimizations(mSuspendOptNeedsDisabled == 0
5419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        && mUserWantsSuspendOpt.get());
5420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.setPowerSave(true);
5422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mP2pSupported) {
5424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (mOperationalMode == CONNECT_MODE) {
5425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
5426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
5427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // P2P statemachine starts in disabled state, and is not enabled until
5428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // CMD_ENABLE_P2P is sent from here; so, nothing needs to be done to
5429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // keep it disabled.
5430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
5431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
5434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
5435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_ENABLED);
5436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5437f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5438f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (PDBG) {
5439f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                loge("Driverstarted State enter done");
5440f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
5441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5445f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
5449b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message);
5450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_BATCHED_SCAN:
5452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (recordBatchedScanSettings(message.arg1, message.arg2,
5453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            (Bundle)message.obj)) {
54549bd0507bf45c39dcb6beca7ae885bc790352eda8Wei Wang                        if (mBatchedScanSettings != null) {
54559bd0507bf45c39dcb6beca7ae885bc790352eda8Wei Wang                            startBatchedScan();
54569bd0507bf45c39dcb6beca7ae885bc790352eda8Wei Wang                        } else {
54579bd0507bf45c39dcb6beca7ae885bc790352eda8Wei Wang                            stopBatchedScan();
54589bd0507bf45c39dcb6beca7ae885bc790352eda8Wei Wang                        }
5459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
5462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    String country = (String) message.obj;
54639c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    final boolean persist = (message.arg2 == 1);
54649c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    final int sequence = message.arg1;
54659c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    if (sequence != mCountryCodeSequence.get()) {
54669c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        if (DBG) log("set country code ignored due to sequnce num");
54679c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        break;
54689c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    }
5469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("set country code " + country);
54709c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    if (persist) {
54719c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        mPersistedCountryCode = country;
54729c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        Settings.Global.putString(mContext.getContentResolver(),
54739c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                                Settings.Global.WIFI_COUNTRY_CODE,
54749c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                                country);
54759c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    }
54769c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    country = country.toUpperCase(Locale.ROOT);
54779c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    if (mLastSetCountryCode == null
54789c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                            || country.equals(mLastSetCountryCode) == false) {
54799c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        if (mWifiNative.setCountryCode(country)) {
54809c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                            mLastSetCountryCode = country;
54819c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                        } else {
54829c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                            loge("Failed to set country code " + country);
5483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
5484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
54859c22c8ea193360f50ad490368ca6a11af0684362Robert Greenwalt                    mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.SET_COUNTRY_CODE, country);
5486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
5488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int band =  message.arg1;
5489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("set frequency band " + band);
5490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.setBand(band)) {
5491f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5492f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        if (PDBG)  loge("did set frequency band " + band);
5493f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mFrequencyBand.set(band);
5495931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // Flush old data - like scan results
5496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.bssFlush();
5497931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // Fetch the latest scan results when frequency band is set
5498be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, null);
5499be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
5500f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        if (PDBG)  loge("done set frequency band " + band);
5501f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to set frequency band " + band);
5504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
5507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mBluetoothConnectionActive = (message.arg1 !=
5508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            BluetoothAdapter.STATE_DISCONNECTED);
5509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
5510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
5512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int mode = message.arg1;
5513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Already doing a delayed stop */
5515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mInDelayedStop) {
5516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) log("Already in delayed stop");
5517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
5518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* disconnect right now, but leave the driver running for a bit */
5520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiConfigStore.disableAllNetworks();
5521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mInDelayedStop = true;
5523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDelayedStopCounter++;
5524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Delayed stop message " + mDelayedStopCounter);
5525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* send regular delayed shut down */
5527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Intent driverStopIntent = new Intent(ACTION_DELAYED_DRIVER_STOP, null);
5528cc9395f7b604c626e8c45021b52dad3abff9bd18Vinit Deshpande                    driverStopIntent.setPackage(this.getClass().getPackage().getName());
5529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    driverStopIntent.putExtra(DELAYED_STOP_COUNTER, mDelayedStopCounter);
5530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDriverStopIntent = PendingIntent.getBroadcast(mContext,
5531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            DRIVER_STOP_REQUEST, driverStopIntent,
5532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            PendingIntent.FLAG_UPDATE_CURRENT);
5533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
5535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            + mDriverStopDelayMs, mDriverStopIntent);
5536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mInDelayedStop) {
5539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mInDelayedStop = false;
5540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDelayedStopCounter++;
5541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mAlarmManager.cancel(mDriverStopIntent);
5542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) log("Delayed stop ignored due to start");
5543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mOperationalMode == CONNECT_MODE) {
5544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiConfigStore.enableAllNetworks();
5545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
5546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DELAYED_STOP_DRIVER:
5549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("delayed stop " + message.arg1 + " " + mDelayedStopCounter);
5550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 != mDelayedStopCounter) break;
5551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (getCurrentState() != mDisconnectedState) {
5552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.disconnect();
5553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleNetworkDisconnect();
5554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWakeLock.acquire();
5556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.stopDriver();
5557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWakeLock.release();
5558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mP2pSupported) {
5559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mWaitForP2pDisableState);
5560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDriverStoppingState);
5562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
5565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == MULTICAST_V6) {
5566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startFilteringMulticastV6Packets();
5567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (message.arg1 == MULTICAST_V4) {
5568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startFilteringMulticastV4Packets();
5569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Illegal arugments to CMD_START_PACKET_FILTERING");
5571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
5574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == MULTICAST_V6) {
5575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.stopFilteringMulticastV6Packets();
5576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (message.arg1 == MULTICAST_V4) {
5577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.stopFilteringMulticastV4Packets();
5578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
5580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_SUSPEND_OPT_ENABLED:
5583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == 1) {
5584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
5585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSuspendWakeLock.release();
5586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
5588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_HIGH_PERF_MODE:
5591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == 1) {
5592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, false);
5593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
5595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_TDLS:
5598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.obj != null) {
5599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        String remoteAddress = (String) message.obj;
5600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        boolean enable = (message.arg1 == 1);
5601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startTdls(remoteAddress, enable);
5602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
5611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mIsRunning = false;
5612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            updateBatteryWorkSource(null);
5613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mScanResults = new ArrayList<ScanResult>();
5614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            stopBatchedScan();
5616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
5618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
5619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
5620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            noteScanEnd(); // wrap up any pending request.
5622a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng            mBufferedScanMsg.clear();
5623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mLastSetCountryCode = null;
5625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5626155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class WaitForP2pDisableState extends State {
5629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private State mTransitionToState;
5630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
5632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (getCurrentMessage().what) {
5633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
5634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTransitionToState = mInitialState;
5635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DELAYED_STOP_DRIVER:
5637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTransitionToState = mDriverStoppingState;
5638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
5640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTransitionToState = mSupplicantStoppingState;
5641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mTransitionToState = mDriverStoppingState;
5644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
5647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5650f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5651f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_RSP:
5654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mTransitionToState);
5655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                /* Defer wifi start/shut and driver commands */
5657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
5658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
5659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
5660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
5661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
5662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
5664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
5665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
5666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
5667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
5668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
5669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
5670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISCONNECT:
5671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
5672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
5673ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
5674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
5675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DriverStoppingState extends State {
5684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5686f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5687f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
5690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    SupplicantState state = handleSupplicantStateChange(message);
5691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (state == SupplicantState.INTERFACE_DISABLED) {
5692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDriverStoppedState);
5693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Queue driver commands */
5696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
5698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
5699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
5700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
5701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
5702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
5703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISCONNECT:
5704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
5705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
5706ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
5707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
5708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DriverStoppedState extends State {
5717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5719f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
5721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
5722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
5723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    SupplicantState state = stateChangeResult.state;
5724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // A WEXT bug means that we can be back to driver started state
5725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // unexpectedly
5726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (SupplicantState.isDriverActive(state)) {
5727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDriverStartedState);
5728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
5731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWakeLock.acquire();
5732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.startDriver();
5733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWakeLock.release();
5734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDriverStartingState);
5735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ScanModeState extends State {
5744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private int mLastOperationMode;
5745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
5747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mLastOperationMode = mOperationalMode;
5748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
5750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
5751f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
5752f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
5754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
5755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == CONNECT_MODE) {
5756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mLastOperationMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
5758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            setWifiState(WIFI_STATE_ENABLED);
5759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // Load and re-enable networks when going back to enabled state
5760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // This is essential for networks to show up after restore
5761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiConfigStore.loadAndEnableAllNetworks();
5762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiP2pChannel.sendMessage(CMD_ENABLE_P2P);
5763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
5764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiConfigStore.enableAllNetworks();
5765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
5766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
576768fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle                        // Try autojoining with recent network already present in the cache
576868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle                        // If none are found then trigger a scan which will trigger autojoin
576968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle                        // upon reception of scan results event
577068fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle                        if (!mWifiAutoJoinController.attemptAutoJoin()) {
577168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle                            startScan(ENABLE_WIFI, 0, null, null);
577268fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle                        }
5773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5774abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle                        // Loose last selection choice since user toggled WiFi
5775abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle                        mWifiConfigStore.
5776abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle                                setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
5777abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle
5778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mOperationalMode = CONNECT_MODE;
5779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDisconnectedState);
5780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
5781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Nothing to do
5782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return HANDLED;
5783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
5784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Handle scan. All the connection related commands are
5786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // handled only in ConnectModeState
5787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
5788a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message);
5789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
5790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
5791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
5792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
5793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
5794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
5796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
5797f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
5798f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    String smToString(Message message) {
5799badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        return smToString(message.what);
5800badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    }
5801badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti
5802badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti    String smToString(int what) {
5803f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        String s = "unknown";
5804badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti        switch (what) {
5805b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            case WifiMonitor.DRIVER_HUNG_EVENT:
5806b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                s = "DRIVER_HUNG_EVENT";
5807b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                break;
5808f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
5809f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "AsyncChannel.CMD_CHANNEL_HALF_CONNECTED";
5810f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5811f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
5812f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "AsyncChannel.CMD_CHANNEL_DISCONNECTED";
5813f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5814f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SET_FREQUENCY_BAND:
5815f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_SET_FREQUENCY_BAND";
5816f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
58177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            case CMD_DELAYED_NETWORK_DISCONNECT:
58187806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                s = "CMD_DELAYED_NETWORK_DISCONNECT";
58197806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                break;
58207806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            case CMD_TEST_NETWORK_DISCONNECT:
58217806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                s = "CMD_TEST_NETWORK_DISCONNECT";
58227806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                break;
58237806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER:
58247806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                s = "CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER";
58257806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                break;
58262ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle            case CMD_DISABLE_EPHEMERAL_NETWORK:
58272ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                s = "CMD_DISABLE_EPHEMERAL_NETWORK";
58282ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                break;
5829f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_START_DRIVER:
5830f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_START_DRIVER";
5831f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5832f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_STOP_DRIVER:
5833f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_STOP_DRIVER";
5834f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5835f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_STOP_SUPPLICANT:
5836f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_STOP_SUPPLICANT";
5837f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5838e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle            case CMD_STOP_SUPPLICANT_FAILED:
5839e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                s = "CMD_STOP_SUPPLICANT_FAILED";
5840e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                break;
5841f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_START_SUPPLICANT:
5842f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_START_SUPPLICANT";
5843f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5844f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_REQUEST_AP_CONFIG:
5845f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_REQUEST_AP_CONFIG";
5846f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5847f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_RESPONSE_AP_CONFIG:
5848f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_RESPONSE_AP_CONFIG";
5849f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5850f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_TETHER_STATE_CHANGE:
5851f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_TETHER_STATE_CHANGE";
5852f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5853f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_TETHER_NOTIFICATION_TIMED_OUT:
5854f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_TETHER_NOTIFICATION_TIMED_OUT";
5855f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5856f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
5857f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_BLUETOOTH_ADAPTER_STATE_CHANGE";
5858f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5859f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_ADD_OR_UPDATE_NETWORK:
5860931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_ADD_OR_UPDATE_NETWORK";
5861f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5862f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_REMOVE_NETWORK:
5863931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_REMOVE_NETWORK";
5864f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5865f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_ENABLE_NETWORK:
5866931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_ENABLE_NETWORK";
5867f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5868f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_ENABLE_ALL_NETWORKS:
5869931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_ENABLE_ALL_NETWORKS";
5870f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5871f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_AUTO_CONNECT:
5872f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_AUTO_CONNECT";
5873f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
58744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            case CMD_AUTO_ROAM:
58754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                s = "CMD_AUTO_ROAM";
58764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                break;
5877be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            case CMD_AUTO_SAVE_NETWORK:
5878be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                s = "CMD_AUTO_SAVE_NETWORK";
5879be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                break;
5880f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_BOOT_COMPLETED:
5881f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "CMD_BOOT_COMPLETED";
5882f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5883f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_START_DHCP:
5884b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_START_DHCP";
5885f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5886f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_STOP_DHCP:
5887b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_STOP_DHCP";
5888f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5889f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_RENEW_DHCP:
5890b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_RENEW_DHCP";
5891f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5892f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
5893b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_PRE_DHCP_ACTION";
5894f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5895f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_POST_DHCP_ACTION:
5896b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_POST_DHCP_ACTION";
5897f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5898f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE:
5899b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_PRE_DHCP_ACTION_COMPLETE";
5900f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5901f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case DhcpStateMachine.CMD_ON_QUIT:
5902b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "CMD_ON_QUIT";
5903f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5904f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST:
5905f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                s = "WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST";
5906f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5907f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiManager.DISABLE_NETWORK:
5908931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "WifiManager.DISABLE_NETWORK";
5909f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5910f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_BLACKLIST_NETWORK:
5911931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_BLACKLIST_NETWORK";
5912f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5913f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_CLEAR_BLACKLIST:
5914931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_CLEAR_BLACKLIST";
5915f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5916f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SAVE_CONFIG:
5917931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_SAVE_CONFIG";
5918f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5919f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_GET_CONFIGURED_NETWORKS:
5920931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_GET_CONFIGURED_NETWORKS";
5921f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5922048dc8df2bd9394979dbb090b0cfe8d6627d23e3Vinit Deshpande            case CMD_GET_SUPPORTED_FEATURES:
5923931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_GET_ADAPTORS";
5924e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                break;
5925e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle            case CMD_UNWANTED_NETWORK:
5926e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                s = "CMD_UNWANTED_NETWORK";
5927e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                break;
5928d30127db46224e45554f8964209221bba8ad41d9vandwalle            case CMD_NETWORK_STATUS:
5929d30127db46224e45554f8964209221bba8ad41d9vandwalle                s = "CMD_NETWORK_STATUS";
5930d30127db46224e45554f8964209221bba8ad41d9vandwalle                break;
5931200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle            case CMD_GET_LINK_LAYER_STATS:
5932200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                s = "CMD_GET_LINK_LAYER_STATS";
5933200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                break;
59349878c61bbd81176561991be025af44efc67332feWenchao Tong            case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS:
5935931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS";
5936a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande                break;
5937f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_DISCONNECT:
5938931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_DISCONNECT";
5939f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5940f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_RECONNECT:
5941931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_RECONNECT";
5942f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5943f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_REASSOCIATE:
5944931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_REASSOCIATE";
5945f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5946c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle            case CMD_GET_CONNECTION_STATISTICS:
5947c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                s = "CMD_GET_CONNECTION_STATISTICS";
5948c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle                break;
5949f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SET_HIGH_PERF_MODE:
5950931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_SET_HIGH_PERF_MODE";
5951f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5952f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SET_COUNTRY_CODE:
5953931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_SET_COUNTRY_CODE";
5954f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5955f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_ENABLE_RSSI_POLL:
5956931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_ENABLE_RSSI_POLL";
5957f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5958f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_RSSI_POLL:
5959931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_RSSI_POLL";
5960f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5961f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_START_PACKET_FILTERING:
5962931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_START_PACKET_FILTERING";
5963f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5964f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_STOP_PACKET_FILTERING:
5965931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_STOP_PACKET_FILTERING";
5966f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5967f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SET_SUSPEND_OPT_ENABLED:
5968931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_SET_SUSPEND_OPT_ENABLED";
5969f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5970f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_NO_NETWORKS_PERIODIC_SCAN:
5971931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_NO_NETWORKS_PERIODIC_SCAN";
5972f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5973f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SET_BATCHED_SCAN:
5974931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_SET_BATCHED_SCAN";
5975f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5976f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_START_NEXT_BATCHED_SCAN:
5977931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_START_NEXT_BATCHED_SCAN";
5978f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5979f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_POLL_BATCHED_SCAN:
5980931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_POLL_BATCHED_SCAN";
5981f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5982badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case CMD_UPDATE_LINKPROPERTIES:
5983badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                s = "CMD_UPDATE_LINKPROPERTIES";
5984f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5985f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_RELOAD_TLS_AND_RECONNECT:
5986931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_RELOAD_TLS_AND_RECONNECT";
5987f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5988f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiManager.CONNECT_NETWORK:
5989931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CONNECT_NETWORK";
5990f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5991f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiManager.SAVE_NETWORK:
5992931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SAVE_NETWORK";
5993f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5994f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiManager.FORGET_NETWORK:
5995b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                s = "FORGET_NETWORK";
5996f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
5997f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.SUP_CONNECTION_EVENT:
5998931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SUP_CONNECTION_EVENT";
5999f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6000f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.SUP_DISCONNECTION_EVENT:
6001931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SUP_DISCONNECTION_EVENT";
6002f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6003f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.SCAN_RESULTS_EVENT:
6004931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SCAN_RESULTS_EVENT";
6005f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6006f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
6007931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SUPPLICANT_STATE_CHANGE_EVENT";
6008f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6009f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
6010931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "AUTHENTICATION_FAILURE_EVENT";
6011f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6012453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle            case WifiMonitor.SSID_TEMP_DISABLED:
6013931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SSID_TEMP_DISABLED";
6014453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle                break;
6015453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle            case WifiMonitor.SSID_REENABLED:
6016931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "SSID_REENABLED";
6017453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle                break;
6018f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.WPS_SUCCESS_EVENT:
6019931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "WPS_SUCCESS_EVENT";
6020f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6021f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.WPS_FAIL_EVENT:
6022931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "WPS_FAIL_EVENT";
6023f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
602440ff222cec1bd05879edb53abc75c6deead734cavandwalle            case WifiMonitor.SUP_REQUEST_IDENTITY:
602540ff222cec1bd05879edb53abc75c6deead734cavandwalle                s = "SUP_REQUEST_IDENTITY";
602640ff222cec1bd05879edb53abc75c6deead734cavandwalle                break;
6027f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.NETWORK_CONNECTION_EVENT:
6028931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "NETWORK_CONNECTION_EVENT";
6029f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6030f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
6031931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "NETWORK_DISCONNECTION_EVENT";
6032f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
603340ff222cec1bd05879edb53abc75c6deead734cavandwalle            case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
6034931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "ASSOCIATION_REJECTION_EVENT";
603540ff222cec1bd05879edb53abc75c6deead734cavandwalle                break;
6036f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_SET_OPERATIONAL_MODE:
6037931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_SET_OPERATIONAL_MODE";
6038f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6039f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            case CMD_START_SCAN:
6040931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_START_SCAN";
6041f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                break;
6042b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_DISABLE_P2P_RSP:
6043931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_DISABLE_P2P_RSP";
6044b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
6045b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            case CMD_DISABLE_P2P_REQ:
6046931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "CMD_DISABLE_P2P_REQ";
6047b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                break;
604840ff222cec1bd05879edb53abc75c6deead734cavandwalle            case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
604940ff222cec1bd05879edb53abc75c6deead734cavandwalle                s = "GOOD_LINK_DETECTED";
605040ff222cec1bd05879edb53abc75c6deead734cavandwalle                break;
605140ff222cec1bd05879edb53abc75c6deead734cavandwalle            case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
605240ff222cec1bd05879edb53abc75c6deead734cavandwalle                s = "POOR_LINK_DETECTED";
605340ff222cec1bd05879edb53abc75c6deead734cavandwalle                break;
6054931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case WifiP2pServiceImpl.GROUP_CREATING_TIMED_OUT:
6055931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "GROUP_CREATING_TIMED_OUT";
6056931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
6057931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
6058931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "P2P_CONNECTION_CHANGED";
6059931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
6060931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE:
6061931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "P2P.DISCONNECT_WIFI_RESPONSE";
6062931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
6063931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case WifiP2pServiceImpl.SET_MIRACAST_MODE:
6064931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "P2P.SET_MIRACAST_MODE";
6065931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
6066931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case WifiP2pServiceImpl.BLOCK_DISCOVERY:
6067931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "P2P.BLOCK_DISCOVERY";
6068931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
6069931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            case WifiP2pServiceImpl.SET_COUNTRY_CODE:
6070931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                s = "P2P.SET_COUNTRY_CODE";
6071931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                break;
6072ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.CANCEL_WPS:
6073ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "CANCEL_WPS";
6074ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6075ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.CANCEL_WPS_FAILED:
6076ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "CANCEL_WPS_FAILED";
6077ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6078ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.CANCEL_WPS_SUCCEDED:
6079ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "CANCEL_WPS_SUCCEDED";
6080ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6081ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.START_WPS:
6082ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "START_WPS";
6083ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6084ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.START_WPS_SUCCEEDED:
6085ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "START_WPS_SUCCEEDED";
6086ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6087ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.WPS_FAILED:
6088ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "WPS_FAILED";
6089ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6090ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle            case WifiManager.WPS_COMPLETED:
6091ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                s = "WPS_COMPLETED";
6092ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle                break;
6093326120045502363422cf5c52a467163d4bcb703avandwalle            case WifiManager.RSSI_PKTCNT_FETCH:
6094326120045502363422cf5c52a467163d4bcb703avandwalle                s = "RSSI_PKTCNT_FETCH";
6095326120045502363422cf5c52a467163d4bcb703avandwalle                break;
6096c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            case CMD_IP_CONFIGURATION_LOST:
6097c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                s = "CMD_IP_CONFIGURATION_LOST";
6098c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                break;
6099c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle            case CMD_IP_CONFIGURATION_SUCCESSFUL:
6100c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                s = "CMD_IP_CONFIGURATION_SUCCESSFUL";
6101c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                break;
6102badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case CMD_STATIC_IP_SUCCESS:
6103badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                s = "CMD_STATIC_IP_SUCCESSFUL";
6104badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
6105badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case CMD_STATIC_IP_FAILURE:
6106badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                s = "CMD_STATIC_IP_FAILURE";
6107badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
6108badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case DhcpStateMachine.DHCP_SUCCESS:
6109badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                s = "DHCP_SUCCESS";
6110badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
6111badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti            case DhcpStateMachine.DHCP_FAILURE:
6112badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                s = "DHCP_FAILURE";
6113badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                break;
6114e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle            case CMD_TARGET_BSSID:
6115e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                s = "CMD_TARGET_BSSID";
6116e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle                break;
61179f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            case CMD_ASSOCIATED_BSSID:
61189f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                s = "CMD_ASSOCIATED_BSSID";
61199f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                break;
61200d616ef3bf635dff8722e064c0be842676390ed8vandwalle            case CMD_ROAM_WATCHDOG_TIMER:
61210d616ef3bf635dff8722e064c0be842676390ed8vandwalle                s = "CMD_ROAM_WATCHDOG_TIMER";
61220d616ef3bf635dff8722e064c0be842676390ed8vandwalle                break;
612382199a285f4a45a46b44eb8253999aa918534753vandwalle            case CMD_SCREEN_STATE_CHANGED:
612482199a285f4a45a46b44eb8253999aa918534753vandwalle                s = "CMD_SCREEN_STATE_CHANGED";
612582199a285f4a45a46b44eb8253999aa918534753vandwalle                break;
61267b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            case CMD_DISCONNECTING_WATCHDOG_TIMER:
61277b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                s = "CMD_DISCONNECTING_WATCHDOG_TIMER";
61287b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                break;
6129b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            default:
6130badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                s = "what:" + Integer.toString(what);
6131b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                break;
6132f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
6133f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        return s;
6134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
6135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
61364dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    void registerConnected() {
61374dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle       if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
61384dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle           long now_ms = System.currentTimeMillis();
6139931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle           // We are switching away from this configuration,
6140931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle           // hence record the time we were connected last
61414dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle           WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(mLastNetworkId);
61424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle           if (config != null) {
61434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               config.lastConnected = System.currentTimeMillis();
61440eebae7334d6129f7ca1344e4b20199794994358vandwalle               config.autoJoinBailedDueToLowRssi = false;
61450eebae7334d6129f7ca1344e4b20199794994358vandwalle               config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED);
6146e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle               config.numConnectionFailures = 0;
6147e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle               config.numIpConfigFailures = 0;
6148e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle               config.numAuthFailures = 0;
6149e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle               config.numAssociation++;
61504dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle           }
61517736c07a4cad4e2d86e1ec2f4221c7f788c18d3avandwalle           mBadLinkspeedcount = 0;
61524dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle       }
61534dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    }
61544dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
61554dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    void registerDisconnected() {
61564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
61574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            long now_ms = System.currentTimeMillis();
6158931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // We are switching away from this configuration,
6159931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // hence record the time we were connected last
61604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(mLastNetworkId);
61614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            if (config != null) {
61624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                config.lastDisconnected = System.currentTimeMillis();
61632ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                if (config.ephemeral) {
61642ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                    // Remove ephemeral WifiConfigurations from file
61652ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                    mWifiConfigStore.forgetNetwork(mLastNetworkId);
61662ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                }
61674dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            }
61684dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
61694dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    }
61704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
61719f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    void noteWifiDisabledWhileAssociated() {
61729f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        // We got disabled by user while we were associated, make note of it
61739f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        int rssi = mWifiInfo.getRssi();
61749f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        WifiConfiguration config = getCurrentWifiConfiguration();
61759f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (getCurrentState() == mConnectedState
61769f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                && rssi != WifiInfo.INVALID_RSSI
61779f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                && config != null) {
61789f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            boolean is24GHz = mWifiInfo.is24GHz();
61799f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            boolean isBadRSSI = (is24GHz && rssi < mWifiConfigStore.thresholdBadRssi24)
61809f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    || (!is24GHz && rssi < mWifiConfigStore.thresholdBadRssi5);
61819f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            boolean isLowRSSI = (is24GHz && rssi < mWifiConfigStore.thresholdLowRssi24)
61829f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    || (!is24GHz && mWifiInfo.getRssi() < mWifiConfigStore.thresholdLowRssi5);
61839f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            boolean isHighRSSI = (is24GHz && rssi >= mWifiConfigStore.thresholdGoodRssi24)
61849f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    || (!is24GHz && mWifiInfo.getRssi() >= mWifiConfigStore.thresholdGoodRssi5);
61859f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            if (isBadRSSI) {
61869f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // Take note that we got disabled while RSSI was Bad
61879f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                config.numUserTriggeredWifiDisableLowRSSI++;
61889f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            } else if (isLowRSSI) {
61899f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // Take note that we got disabled while RSSI was Low
61909f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                config.numUserTriggeredWifiDisableBadRSSI++;
61919f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            } else if (!isHighRSSI) {
61929f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                // Take note that we got disabled while RSSI was Not high
61939f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                config.numUserTriggeredWifiDisableNotHighRSSI++;
61949f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            }
61959f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
61969f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    }
61979f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
6198f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    WifiConfiguration getCurrentWifiConfiguration() {
6199f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (mLastNetworkId == WifiConfiguration.INVALID_NETWORK_ID) {
6200f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            return null;
6201f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
6202f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        return mWifiConfigStore.getWifiConfiguration(mLastNetworkId);
6203f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
6204f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6205e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    ScanResult getCurrentScanResult() {
6206e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        WifiConfiguration config = getCurrentWifiConfiguration();
6207e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        if (config == null) {
6208e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            return null;
6209e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
6210e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        String BSSID = mWifiInfo.getBSSID();
6211e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        if (BSSID == null) {
6212e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            BSSID = mTargetRoamBSSID;
6213e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
6214e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        if (config.scanResultCache == null) {
6215e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            return null;
6216e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
6217e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        return config.scanResultCache.get(BSSID);
6218e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    }
6219e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
62204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    String getCurrentBSSID() {
62217806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        if (linkDebouncing) {
62227806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            return null;
62237806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        }
62244dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        return mLastBssid;
62254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    }
62264dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
6227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ConnectModeState extends State {
6228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
6229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
6230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiConfiguration config;
6231f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            int netId;
6232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ok;
6233e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            boolean didDisconnect;
623440ff222cec1bd05879edb53abc75c6deead734cavandwalle            String bssid;
623540ff222cec1bd05879edb53abc75c6deead734cavandwalle            String ssid;
6236b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle            NetworkUpdateResult result;
6237f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
6238f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6239200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle            switch (message.what) {
6240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
62412451dbcc4f9641df188326215b204b798eb70c46vandwalle                    didBlackListBSSID = false;
6242200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    bssid = (String) message.obj;
6243931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    if (bssid == null || TextUtils.isEmpty(bssid)) {
6244931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // If BSSID is null, use the target roam BSSID
624540ff222cec1bd05879edb53abc75c6deead734cavandwalle                        bssid = mTargetRoamBSSID;
6246931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    }
624740ff222cec1bd05879edb53abc75c6deead734cavandwalle                    if (bssid != null) {
6248931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // If we have a BSSID, tell configStore to black list it
6249e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        synchronized(mScanResultCache) {
6250e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                            didBlackListBSSID = mWifiConfigStore.handleBSSIDBlackList
6251e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                    (mLastNetworkId, bssid, false);
6252e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        }
625340ff222cec1bd05879edb53abc75c6deead734cavandwalle                    }
6254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSupplicantStateTracker.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT);
6255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
6257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT);
6258ede1310be531a84faa08f02c3fd243448dd936ddvandwalle                    break;
6259ede1310be531a84faa08f02c3fd243448dd936ddvandwalle                case WifiMonitor.SSID_TEMP_DISABLED:
6260ede1310be531a84faa08f02c3fd243448dd936ddvandwalle                case WifiMonitor.SSID_REENABLED:
6261200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    String substr = (String) message.obj;
6262ede1310be531a84faa08f02c3fd243448dd936ddvandwalle                    String en = message.what == WifiMonitor.SSID_TEMP_DISABLED ?
6263200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                            "temp-disabled" : "re-enabled";
6264ede1310be531a84faa08f02c3fd243448dd936ddvandwalle                    loge("ConnectModeState SSID state=" + en + " nid="
6265ede1310be531a84faa08f02c3fd243448dd936ddvandwalle                            + Integer.toString(message.arg1) + " [" + substr + "]");
6266e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    synchronized(mScanResultCache) {
6267e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        mWifiConfigStore.handleSSIDStateChange(message.arg1, message.what ==
6268e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                                WifiMonitor.SSID_REENABLED, substr, mWifiInfo.getBSSID());
6269e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    }
6270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
6272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    SupplicantState state = handleSupplicantStateChange(message);
6273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // A driver/firmware hang can now put the interface in a down state.
6274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // We detect the interface going down and recover from it
6275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!SupplicantState.isDriverActive(state)) {
6276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
6277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            handleNetworkDisconnect();
6278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
6279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        log("Detected an interface down, restart driver");
6280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDriverStoppedState);
6281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_START_DRIVER);
6282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
6283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
6285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
6286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // when authentication times out after a successful connection,
6287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // we can figure this from the supplicant state. If supplicant
6288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // state is DISCONNECTED, but the mNetworkInfo says we are not
6289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // disconnected, we need to handle a disconnection
62907806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (!linkDebouncing && state == SupplicantState.DISCONNECTED &&
6291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
6292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
6293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleNetworkDisconnect();
6294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDisconnectedState);
6295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST:
6298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == 1) {
6299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.disconnect();
6300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mTemporarilyDisconnectWifi = true;
6301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
6302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.reconnect();
6303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mTemporarilyDisconnectWifi = false;
6304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ADD_OR_UPDATE_NETWORK:
6307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = (WifiConfiguration) message.obj;
63082f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                    int res = mWifiConfigStore.addOrUpdateNetwork(config, message.sendingUid);
6309b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    if (res < 0) {
6310b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
6311b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    } else {
6312b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        WifiConfiguration curConfig = getCurrentWifiConfiguration();
6313b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        if (curConfig != null && config != null) {
63142f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                            if (curConfig.priority < config.priority
63152f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                                    && config.status == WifiConfiguration.Status.ENABLED) {
6316b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                // Interpret this as a connect attempt
6317b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                // Set the last selected configuration so as to allow the system to
6318b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                // stick the last user choice without persisting the choice
6319b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                mWifiConfigStore.setLastSelectedConfiguration(res);
6320b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle
6321b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                // Remember time of last connection attempt
6322b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                lastConnectAttempt = System.currentTimeMillis();
6323b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle
6324b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
6325b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle
6326b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                // As a courtesy to the caller, trigger a scan now
6327b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                                startScan(ADD_OR_UPDATE_SOURCE, 0, null, null);
6328b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                            }
6329b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        }
6330b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    }
6331b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK, res);
6332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REMOVE_NETWORK:
6334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ok = mWifiConfigStore.removeNetwork(message.arg1);
6335b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    if (!ok) {
6336b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
6337b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    }
6338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
6339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_NETWORK:
6341ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                    boolean others = message.arg2 == 1;
6342992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    // Tell autojoin the user did try to select to that network
6343992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    // However, do NOT persist the choice by bumping the priority of the network
6344b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    if (others) {
6345992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                        mWifiAutoJoinController.
6346992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                                updateConfigurationHistory(message.arg1, true, false);
6347b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        // Set the last selected configuration so as to allow the system to
6348b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        // stick the last user choice without persisting the choice
6349b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        mWifiConfigStore.setLastSelectedConfiguration(message.arg1);
635052e79f112225e158c5de12685e55906de5e222b9vandwalle
6351931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // Remember time of last connection attempt
635252e79f112225e158c5de12685e55906de5e222b9vandwalle                        lastConnectAttempt = System.currentTimeMillis();
6353e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle
6354e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle                        mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
6355992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                    }
6356931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Cancel auto roam requests
6357b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    autoRoamSetBSSID(message.arg1, "any");
6358b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
6359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
6360b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    if (!ok) {
6361b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
6362b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    }
6363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
6364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_ALL_NETWORKS:
6366200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    long time = android.os.SystemClock.elapsedRealtime();
6367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (time - mLastEnableAllNetworksTime > MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS) {
6368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiConfigStore.enableAllNetworks();
6369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mLastEnableAllNetworksTime = time;
6370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.DISABLE_NETWORK:
6373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiConfigStore.disableNetwork(message.arg1,
63740eebae7334d6129f7ca1344e4b20199794994358vandwalle                            WifiConfiguration.DISABLED_BY_WIFI_MANAGER) == true) {
6375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.DISABLE_NETWORK_SUCCEEDED);
6376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
6377b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
6378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
6379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiManager.ERROR);
6380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
63822ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                case CMD_DISABLE_EPHEMERAL_NETWORK:
63832ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                    config = mWifiConfigStore.disableEphemeralNetwork((String)message.obj);
63842ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                    if (config != null) {
63852ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                        if (config.networkId == mLastNetworkId) {
63862ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                            // Disconnect and let autojoin reselect a new network
63872ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                            sendMessage(CMD_DISCONNECT);
63882ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                        }
63892ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                    }
63902ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle                    break;
6391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_BLACKLIST_NETWORK:
6392200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                    mWifiNative.addToBlacklist((String) message.obj);
6393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_CLEAR_BLACKLIST:
6395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.clearBlacklist();
6396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SAVE_CONFIG:
6398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ok = mWifiConfigStore.saveConfig();
6399f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6400b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    if (DBG) loge("wifistatemachine did save config " + ok);
6401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
6402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
6403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Inform the backup manager about a data change
6404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    IBackupManager ibm = IBackupManager.Stub.asInterface(
6405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ServiceManager.getService(Context.BACKUP_SERVICE));
6406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (ibm != null) {
6407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
6408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ibm.dataChanged("com.android.providers.settings");
6409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (Exception e) {
6410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // Try again later
6411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
6412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_GET_CONFIGURED_NETWORKS:
6415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, message.what,
6416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiConfigStore.getConfiguredNetworks());
6417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
641840ff222cec1bd05879edb53abc75c6deead734cavandwalle                case WifiMonitor.SUP_REQUEST_IDENTITY:
6419931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Supplicant lacks credentials to connect to that network, hence black list
6420931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    ssid = (String) message.obj;
642140ff222cec1bd05879edb53abc75c6deead734cavandwalle
642240ff222cec1bd05879edb53abc75c6deead734cavandwalle                    if (targetWificonfiguration != null && ssid != null
642340ff222cec1bd05879edb53abc75c6deead734cavandwalle                            && targetWificonfiguration.SSID != null
642440ff222cec1bd05879edb53abc75c6deead734cavandwalle                            && targetWificonfiguration.SSID.equals("\"" + ssid + "\"")) {
642540ff222cec1bd05879edb53abc75c6deead734cavandwalle                        mWifiConfigStore.handleSSIDStateChange(targetWificonfiguration.networkId,
6426e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                                false, "AUTH_FAILED no identity", null);
642740ff222cec1bd05879edb53abc75c6deead734cavandwalle                    }
6428931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Disconnect now, as we don't have any way to fullfill the  supplicant request.
6429931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    mWifiConfigStore.setLastSelectedConfiguration
6430931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                            (WifiConfiguration.INVALID_NETWORK_ID);
6431931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    mWifiNative.disconnect();
6432931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    break;
643333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                case WifiMonitor.SUP_REQUEST_SIM_AUTH:
643433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                    logd("Received SUP_REQUEST_SIM_AUTH");
643533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                    SimAuthRequestData requestData = (SimAuthRequestData) message.obj;
643633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                    if (requestData != null) {
6437dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                        if (requestData.protocol == WifiEnterpriseConfig.Eap.SIM) {
6438dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                            handleGsmAuthRequest(requestData);
6439dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                        } else if (requestData.protocol == WifiEnterpriseConfig.Eap.AKA) {
6440dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                            handle3GAuthRequest(requestData);
6441dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                        }
644233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                    } else {
644333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                        loge("Invalid sim auth request");
644433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                    }
644533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                    break;
64469878c61bbd81176561991be025af44efc67332feWenchao Tong                case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS:
64479878c61bbd81176561991be025af44efc67332feWenchao Tong                    replyToMessage(message, message.what,
64489878c61bbd81176561991be025af44efc67332feWenchao Tong                            mWifiConfigStore.getPrivilegedConfiguredNetworks());
64499878c61bbd81176561991be025af44efc67332feWenchao Tong                    break;
64509878c61bbd81176561991be025af44efc67332feWenchao Tong                    /* Do a redundant disconnect without transition */
6451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISCONNECT:
6452117be607246604e875de62aa8cdd99700b77a2b4vandwalle                    mWifiConfigStore.setLastSelectedConfiguration
6453ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                            (WifiConfiguration.INVALID_NETWORK_ID);
6454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.disconnect();
6455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
6457f5a84fcd66298ee6e96b781d2645422a1571ac07Vinit Deshpande                    mWifiAutoJoinController.attemptAutoJoin();
6458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
6460b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    lastConnectAttempt = System.currentTimeMillis();
6461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.reassociate();
6462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RELOAD_TLS_AND_RECONNECT:
6464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiConfigStore.needsUnlockedKeyStore()) {
6465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        logd("Reconnecting to give a chance to un-connected TLS networks");
6466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.disconnect();
6467b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        lastConnectAttempt = System.currentTimeMillis();
6468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.reconnect();
6469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
64714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                case CMD_AUTO_ROAM:
6472b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
64734dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    return HANDLED;
6474f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                case CMD_AUTO_CONNECT:
6475952d359198cb1f04c180fc0f795dc316fe97cb5evandwalle                    /* Work Around: wpa_supplicant can get in a bad state where it returns a non
64767806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                     * associated status to the STATUS command but somehow-someplace still thinks
64771e0d2b64c03a05da87d59a5f0774e549e82080ccvandwalle                     * it is associated and thus will ignore select/reconnect command with
64781e0d2b64c03a05da87d59a5f0774e549e82080ccvandwalle                     * following message:
64791e0d2b64c03a05da87d59a5f0774e549e82080ccvandwalle                     * "Already associated with the selected network - do nothing"
64801e0d2b64c03a05da87d59a5f0774e549e82080ccvandwalle                     *
6481952d359198cb1f04c180fc0f795dc316fe97cb5evandwalle                     * Hence, sends a disconnect to supplicant first.
64821e0d2b64c03a05da87d59a5f0774e549e82080ccvandwalle                     */
6483e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    didDisconnect = false;
6484e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    if (getCurrentState() != mDisconnectedState) {
6485e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        /** Supplicant will ignore the reconnect if we are currently associated,
6486e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                         * hence trigger a disconnect
6487e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                         */
6488e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        didDisconnect = true;
6489e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        mWifiNative.disconnect();
6490e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    }
64911e0d2b64c03a05da87d59a5f0774e549e82080ccvandwalle
6492f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    /* connect command coming from auto-join */
6493f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    config = (WifiConfiguration) message.obj;
6494f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    netId = message.arg1;
64954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    int roam = message.arg2;
6496ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                    loge("CMD_AUTO_CONNECT sup state "
6497ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                            + mSupplicantStateTracker.getSupplicantStateName()
6498f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                            + " my state " + getCurrentState().getName()
64994dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            + " nid=" + Integer.toString(netId)
65004dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            + " roam=" + Integer.toString(roam));
6501b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    if (config == null) {
6502b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        loge("AUTO_CONNECT and no config, bail out...");
6503b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        break;
6504b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    }
65054dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
6506931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    /* Make sure we cancel any previous roam request */
65079f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    autoRoamSetBSSID(netId, config.BSSID);
6508f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6509f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    /* Save the network config */
6510b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    loge("CMD_AUTO_CONNECT will save config -> " + config.SSID
6511200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                            + " nid=" + Integer.toString(netId));
65120eebae7334d6129f7ca1344e4b20199794994358vandwalle                    result = mWifiConfigStore.saveNetwork(config, -1);
6513b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    netId = result.getNetworkId();
6514b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    loge("CMD_AUTO_CONNECT did save config -> "
6515200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                            + " nid=" + Integer.toString(netId));
6516f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6517b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    // Make sure the network is enabled, since supplicant will not reenable it
6518b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    mWifiConfigStore.enableNetworkWithoutBroadcast(netId, false);
6519b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle
6520f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    if (mWifiConfigStore.selectNetwork(netId) &&
6521f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                            mWifiNative.reconnect()) {
6522b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        lastConnectAttempt = System.currentTimeMillis();
652340ff222cec1bd05879edb53abc75c6deead734cavandwalle                        targetWificonfiguration = mWifiConfigStore.getWifiConfiguration(netId);
6524833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                        config = mWifiConfigStore.getWifiConfiguration(netId);
6525833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                        if (config != null
6526833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                                && !mWifiConfigStore.isLastSelectedConfiguration(config)) {
6527833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // If we autojoined a different config than the user selected one,
6528833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // it means we could not see the last user selection,
6529833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // or that the last user selection was faulty and ended up blacklisted
6530833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // for some reason (in which case the user is notified with an error
6531833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // message in the Wifi picker), and thus we managed to auto-join away
6532833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // from the selected  config. -> in that case we need to forget
6533833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // the selection because we don't want to abruptly switch back to it.
6534833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            //
6535833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // Note that the user selection is also forgotten after a period of time
6536833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // during which the device has been disconnected.
6537833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // The default value is 30 minutes : see the code path at bottom of
6538833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            // setScanResults() function.
6539833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                            mWifiConfigStore.
6540833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                                 setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
6541833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                        }
6542b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        mAutoRoaming = roam;
65437806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        if (isRoaming() || linkDebouncing) {
65444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            transitionTo(mRoamingState);
6545e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        } else if (didDisconnect) {
65464dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            transitionTo(mDisconnectingState);
6547e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        } else {
6548cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande                            /* Already in disconnected state, nothing to change */
65494dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        }
6550f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    } else {
6551f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        loge("Failed to connect config: " + config + " netId: " + netId);
6552f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
6553f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                WifiManager.ERROR);
6554f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        break;
6555f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    }
6556f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    break;
6557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.CONNECT_NETWORK:
6558931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    /**
6559931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                     *  The connect message can contain a network id passed as arg1 on message or
6560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * or a config passed as obj on message.
6561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * For a new network, a config is passed to create and connect.
6562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * For an existing network, a network id is passed
6563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     */
6564f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    netId = message.arg1;
6565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = (WifiConfiguration) message.obj;
6566e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle                    mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
65673aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                    boolean updatedExisting = false;
6568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
6569448c9536a302c58a79e271b1721c08b8882f800evandwalle                    /* Save the network config */
6570448c9536a302c58a79e271b1721c08b8882f800evandwalle                    if (config != null) {
65713aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                        String configKey = config.configKey(true /* allowCached */);
65723aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                        WifiConfiguration savedConfig =
65733aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                                mWifiConfigStore.getWifiConfiguration(configKey);
65743aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                        if (savedConfig != null) {
65753aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            // There is an existing config with this netId, but it wasn't exposed
65763aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            // (either AUTO_JOIN_DELETED or ephemeral; see WifiConfigStore#
65773aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            // getConfiguredNetworks). Remove those bits and update the config.
65783aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            config = savedConfig;
65793aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            loge("CONNECT_NETWORK updating existing config with id=" +
65803aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                                    config.networkId + " configKey=" + configKey);
65813aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            config.ephemeral = false;
65823aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            config.autoJoinStatus = WifiConfiguration.AUTO_JOIN_ENABLED;
65833aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            updatedExisting = true;
65843aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                        }
65853aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson
65860eebae7334d6129f7ca1344e4b20199794994358vandwalle                        result = mWifiConfigStore.saveNetwork(config, message.sendingUid);
6587448c9536a302c58a79e271b1721c08b8882f800evandwalle                        netId = result.getNetworkId();
6588448c9536a302c58a79e271b1721c08b8882f800evandwalle                    }
65890eebae7334d6129f7ca1344e4b20199794994358vandwalle                    config = mWifiConfigStore.getWifiConfiguration(netId);
6590448c9536a302c58a79e271b1721c08b8882f800evandwalle
6591f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    if (config == null) {
6592f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        loge("CONNECT_NETWORK id=" + Integer.toString(netId) + " "
6593f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + mSupplicantStateTracker.getSupplicantStateName() + " my state "
6594f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + getCurrentState().getName());
6595f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    } else {
65960eebae7334d6129f7ca1344e4b20199794994358vandwalle                        String wasSkipped = config.autoJoinBailedDueToLowRssi ? " skipped" : "";
6597f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        loge("CONNECT_NETWORK id=" + Integer.toString(netId)
6598f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " config=" + config.SSID
6599f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " cnid=" + config.networkId
6600f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " supstate=" + mSupplicantStateTracker.getSupplicantStateName()
66012f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                                + " my state " + getCurrentState().getName()
66020eebae7334d6129f7ca1344e4b20199794994358vandwalle                                + " uid = " + message.sendingUid
66030eebae7334d6129f7ca1344e4b20199794994358vandwalle                                + wasSkipped);
6604f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    }
6605f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6606b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    autoRoamSetBSSID(netId, "any");
66072f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle
66082f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                    if (message.sendingUid == Process.WIFI_UID
66092f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        || message.sendingUid == Process.SYSTEM_UID) {
66102f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        // As a sanity measure, clear the BSSID in the supplicant network block.
66112f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        // If system or Wifi Settings want to connect, they will not
66122f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        // specify the BSSID.
66132f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        // If an app however had added a BSSID to this configuration, and the BSSID
66142f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        // was wrong, Then we would forever fail to connect until that BSSID
66152f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        // is cleaned up.
66162f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                        clearConfigBSSID(config, "CONNECT_NETWORK");
66172f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                    }
66182f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle
6619b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE;
6620b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
6621be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    /* Tell autojoin the user did try to connect to that network */
6622be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    mWifiAutoJoinController.updateConfigurationHistory(netId, true, true);
6623be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
6624117be607246604e875de62aa8cdd99700b77a2b4vandwalle                    mWifiConfigStore.setLastSelectedConfiguration(netId);
6625ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle
6626e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    didDisconnect = false;
6627b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID
6628b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                            && mLastNetworkId != netId) {
6629931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        /** Supplicant will ignore the reconnect if we are currently associated,
6630b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                         * hence trigger a disconnect
6631931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                         */
6632e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        didDisconnect = true;
6633b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        mWifiNative.disconnect();
6634b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    }
6635b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle
6636b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    // Make sure the network is enabled, since supplicant will not reenable it
6637b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    mWifiConfigStore.enableNetworkWithoutBroadcast(netId, false);
6638b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle
6639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiConfigStore.selectNetwork(netId) &&
6640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiNative.reconnect()) {
6641b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        lastConnectAttempt = System.currentTimeMillis();
664240ff222cec1bd05879edb53abc75c6deead734cavandwalle                        targetWificonfiguration = mWifiConfigStore.getWifiConfiguration(netId);
6643b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle
6644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /* The state tracker handles enabling networks upon completion/failure */
6645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSupplicantStateTracker.sendMessage(WifiManager.CONNECT_NETWORK);
6646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
6647e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        if (didDisconnect) {
6648e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            /* Expect a disconnection from the old connection */
6649e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            transitionTo(mDisconnectingState);
66503aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                        } else if (updatedExisting && getCurrentState() == mConnectedState &&
66513aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                                getCurrentWifiConfiguration().networkId == netId) {
66523aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            // Update the current set of network capabilities, but stay in the
66533aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            // current state.
66543aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                            updateCapabilities(config);
6655e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        } else {
6656e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            /**
6657e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                             *  Directly go to disconnected state where we
6658e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                             * process the connection events from supplicant
6659e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                             **/
6660e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            transitionTo(mDisconnectedState);
6661e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        }
6662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
6663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to connect config: " + config + " netId: " + netId);
6664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
6665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiManager.ERROR);
6666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
6667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.SAVE_NETWORK:
6670be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
6671be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    // Fall thru
6672be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                case WifiStateMachine.CMD_AUTO_SAVE_NETWORK:
6673be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    lastSavedConfigurationAttempt = null; // Used for debug
6674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = (WifiConfiguration) message.obj;
6675f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                    if (config == null) {
6676be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        loge("ERROR: SAVE_NETWORK with null configuration"
6677be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                + mSupplicantStateTracker.getSupplicantStateName()
6678f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " my state " + getCurrentState().getName());
6679b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
6680be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
6681be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                WifiManager.ERROR);
6682be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        break;
6683be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
6684be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    lastSavedConfigurationAttempt = new WifiConfiguration(config);
6685be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    int nid = config.networkId;
6686be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    loge("SAVE_NETWORK id=" + Integer.toString(nid)
6687f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " config=" + config.SSID
6688be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                + " nid=" + config.networkId
6689f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " supstate=" + mSupplicantStateTracker.getSupplicantStateName()
6690f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                                + " my state " + getCurrentState().getName());
6691f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
66920eebae7334d6129f7ca1344e4b20199794994358vandwalle                    result = mWifiConfigStore.saveNetwork(config, -1);
6693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
6694be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
6695be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            if (result.hasIpChanged()) {
6696be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                // The currently connection configuration was changed
6697be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                // We switched from DHCP to static or from static to DHCP, or the
6698be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                // static IP address has changed.
6699be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                log("Reconfiguring IP on connection");
6700be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                // TODO: clear addresses and disable IPv6
6701be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                // to simplify obtainingIpState.
6702be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                transitionTo(mObtainingIpState);
6703be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            }
6704be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            if (result.hasProxyChanged()) {
6705be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                log("Reconfiguring proxy on connection");
6706be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                updateLinkProperties(CMD_UPDATE_LINKPROPERTIES);
6707be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            }
67080ff9728ea843a291b2665c705cfe6f0357e1aa44vandwalle                        }
67090ff9728ea843a291b2665c705cfe6f0357e1aa44vandwalle                        replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
67100ff9728ea843a291b2665c705cfe6f0357e1aa44vandwalle                        if (VDBG) {
67110ff9728ea843a291b2665c705cfe6f0357e1aa44vandwalle                           loge("Success save network nid="
6712be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                        + Integer.toString(result.getNetworkId()));
6713992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle                        }
6714be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
6715e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        synchronized(mScanResultCache) {
67169d082c381274f27dad1e344223189e00148e2124vandwalle                            /**
67179d082c381274f27dad1e344223189e00148e2124vandwalle                             * If the command comes from WifiManager, then
67189d082c381274f27dad1e344223189e00148e2124vandwalle                             * tell autojoin the user did try to modify and save that network,
67199d082c381274f27dad1e344223189e00148e2124vandwalle                             * and interpret the SAVE_NETWORK as a request to connect
67209d082c381274f27dad1e344223189e00148e2124vandwalle                             */
67219d082c381274f27dad1e344223189e00148e2124vandwalle                            boolean user = message.what == WifiManager.SAVE_NETWORK;
6722e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            mWifiAutoJoinController.updateConfigurationHistory(result.getNetworkId()
67239d082c381274f27dad1e344223189e00148e2124vandwalle                                    , user, true);
6724e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            mWifiAutoJoinController.attemptAutoJoin();
6725e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        }
6726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
6727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to save network");
6728b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
6729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
6730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiManager.ERROR);
6731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.FORGET_NETWORK:
6734be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    // Debug only, remember last configuration that was forgotten
6735be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    WifiConfiguration toRemove
6736be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            = mWifiConfigStore.getWifiConfiguration(message.arg1);
6737be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (toRemove == null) {
6738be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        lastForgetConfigurationAttempt = null;
6739be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    } else {
6740be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        lastForgetConfigurationAttempt = new WifiConfiguration(toRemove);
6741be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
6742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiConfigStore.forgetNetwork(message.arg1)) {
6743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.FORGET_NETWORK_SUCCEEDED);
6744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
6745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to forget network");
6746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
6747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiManager.ERROR);
6748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.START_WPS:
6751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WpsInfo wpsInfo = (WpsInfo) message.obj;
6752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WpsResult wpsResult;
6753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    switch (wpsInfo.setup) {
6754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        case WpsInfo.PBC:
6755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            wpsResult = mWifiConfigStore.startWpsPbc(wpsInfo);
6756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            break;
6757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        case WpsInfo.KEYPAD:
6758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            wpsResult = mWifiConfigStore.startWpsWithPinFromAccessPoint(wpsInfo);
6759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            break;
6760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        case WpsInfo.DISPLAY:
6761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            wpsResult = mWifiConfigStore.startWpsWithPinFromDevice(wpsInfo);
6762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            break;
6763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        default:
6764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            wpsResult = new WpsResult(Status.FAILURE);
6765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("Invalid setup for WPS");
6766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            break;
6767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6768117be607246604e875de62aa8cdd99700b77a2b4vandwalle                    mWifiConfigStore.setLastSelectedConfiguration
6769ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                            (WifiConfiguration.INVALID_NETWORK_ID);
6770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (wpsResult.status == Status.SUCCESS) {
6771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.START_WPS_SUCCEEDED, wpsResult);
6772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mWpsRunningState);
6773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
6774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to start WPS with config " + wpsInfo.toString());
6775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.ERROR);
6776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
6777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
6779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Network connection established");
6780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mLastNetworkId = message.arg1;
6781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mLastBssid = (String) message.obj;
6782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
6783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiInfo.setBSSID(mLastBssid);
6784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiInfo.setNetworkId(mLastNetworkId);
6785cdc5b747a9c6ff40a38a66bdd8f86dbf11852a7avandwalle
6786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendNetworkStateChangeBroadcast(mLastBssid);
6787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mObtainingIpState);
6788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
679056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // Calling handleNetworkDisconnect here is redundant because we might already
679156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // have called it when leaving L2ConnectedState to go to disconnecting state
679256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // or thru other path
679356d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // We should normally check the mWifiInfo or mLastNetworkId so as to check
679456d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // if they are valid, and only in this case call handleNEtworkDisconnect,
679556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // TODO: this should be fixed for a L MR release
679656d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // The side effect of calling handleNetworkDisconnect twice is that a bunch of
679756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // idempotent commands are executed twice (stopping Dhcp, enabling the SPS mode
679856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    // at the chip etc...
6799b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    if (DBG) log("ConnectModeState: Network connection lost ");
6800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleNetworkDisconnect();
6801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectedState);
6802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
6803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
6804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
6805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
6806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
6807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
6808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
6809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
68103aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson    private void updateCapabilities(WifiConfiguration config) {
68113aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson        if (config.ephemeral) {
68123aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson            mNetworkCapabilities.removeCapability(
68133aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                    NetworkCapabilities.NET_CAPABILITY_TRUSTED);
68143aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson        } else {
68153aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson            mNetworkCapabilities.addCapability(
68163aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson                    NetworkCapabilities.NET_CAPABILITY_TRUSTED);
68173aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson        }
68183aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson        mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
68193aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson    }
68203aed1e5a7a7f2ec730c393e2c7d129e3e551a711Jeff Davidson
68217d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt    private class WifiNetworkAgent extends NetworkAgent {
68227d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        public WifiNetworkAgent(Looper l, Context c, String TAG, NetworkInfo ni,
68237d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt                NetworkCapabilities nc, LinkProperties lp, int score) {
68247d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            super(l, c, TAG, ni, nc, lp, score);
68257d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        }
68267d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        protected void unwanted() {
6827931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // Ignore if we're not the current networkAgent.
68287d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            if (this != mNetworkAgent) return;
682927355a942653264388e909a4276196ee63e57811vandwalle            if (DBG) log("WifiNetworkAgent -> Wifi unwanted score "
683027355a942653264388e909a4276196ee63e57811vandwalle                    + Integer.toString(mWifiInfo.score));
6831e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            unwantedNetwork(network_status_unwanted_disconnect);
6832e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        }
6833e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
6834e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        protected void networkStatus(int status) {
6835e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            if (status == NetworkAgent.INVALID_NETWORK) {
6836d30127db46224e45554f8964209221bba8ad41d9vandwalle                if (DBG) log("WifiNetworkAgent -> Wifi networkStatus invalid, score="
6837e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        + Integer.toString(mWifiInfo.score));
6838e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                unwantedNetwork(network_status_unwanted_disable_autojoin);
6839d30127db46224e45554f8964209221bba8ad41d9vandwalle            } else if (status == NetworkAgent.VALID_NETWORK) {
6840d30127db46224e45554f8964209221bba8ad41d9vandwalle                if (DBG && mWifiInfo != null) log("WifiNetworkAgent -> Wifi networkStatus valid, score= "
6841d30127db46224e45554f8964209221bba8ad41d9vandwalle                        + Integer.toString(mWifiInfo.score));
6842d30127db46224e45554f8964209221bba8ad41d9vandwalle                doNetworkStatus(status);
6843e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle            }
68447d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt        }
68457d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt    }
68467d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt
6847e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle    void unwantedNetwork(int reason) {
6848e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle        sendMessage(CMD_UNWANTED_NETWORK, reason);
684927355a942653264388e909a4276196ee63e57811vandwalle    }
685027355a942653264388e909a4276196ee63e57811vandwalle
6851d30127db46224e45554f8964209221bba8ad41d9vandwalle    void doNetworkStatus(int status) {
6852d30127db46224e45554f8964209221bba8ad41d9vandwalle        sendMessage(CMD_NETWORK_STATUS, status);
6853d30127db46224e45554f8964209221bba8ad41d9vandwalle    }
6854e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle
68557806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    boolean startScanForConfiguration(WifiConfiguration config, boolean restrictChannelList) {
68567b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle        if (config == null)
68577b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            return false;
68581ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle
68591ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        // We are still seeing a fairly high power consumption triggered by autojoin scans
68601ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        // Hence do partial scans only for PSK configuration that are roamable since the
68611ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        // primary purpose of the partial scans is roaming.
68621ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        // Full badn scans with exponential backoff for the purpose or extended roaming and
68631ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        // network switching are performed unconditionally.
68641ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        if (config.scanResultCache == null
68651ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                || !config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)
68661ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                || config.scanResultCache.size() > 6) {
68671ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle            //return true but to not trigger the scan
68681ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle            return true;
68691ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle        }
68707806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        HashSet<Integer> channels
68717806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                = mWifiConfigStore.makeChannelList(config,
68727806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                ONE_HOUR_MILLI, restrictChannelList);
68737806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        if (channels != null && channels.size() != 0) {
68747806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            StringBuilder freqs = new StringBuilder();
68757806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            boolean first = true;
68767806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            for (Integer channel : channels) {
68777806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                if (!first)
68787806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    freqs.append(",");
68797806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                freqs.append(channel.toString());
68807806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                first = false;
68817806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            }
68821ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle            //if (DBG) {
68831ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle            loge("WifiStateMachine starting scan for " + config.configKey() + " with " + freqs);
68841ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle            //}
68857806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // Call wifi native to start the scan
68867806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            if (startScanNative(
68877806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    WifiNative.SCAN_WITHOUT_CONNECTION_SETUP,
68887806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    freqs.toString())) {
68897806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                // Only count battery consumption if scan request is accepted
68907806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                noteScanStart(SCAN_ALARM_SOURCE, null);
68911ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK;
68921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle            } else {
68931ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                // used for debug only, mark scan as failed
68941ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                messageHandlingStatus = MESSAGE_HANDLING_STATUS_HANDLING_ERROR;
68957806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            }
68967806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            return true;
68977806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        } else {
68987b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            if (DBG) loge("WifiStateMachine no channels for " + config.configKey());
68997806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            return false;
69007806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle        }
69017806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle    }
69027806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
69039f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    void clearCurrentConfigBSSID(String dbg) {
69049f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        // Clear the bssid in the current config's network block
69059f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        WifiConfiguration config = getCurrentWifiConfiguration();
69069f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (config == null)
69079f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            return;
69082f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        clearConfigBSSID(config, dbg);
69092f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    }
69102f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle    void clearConfigBSSID(WifiConfiguration config, String dbg) {
69112f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        if (config == null)
69122f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            return;
69139f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        if (DBG) {
69149f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            loge(dbg + " " + mTargetRoamBSSID + " config " + config.configKey()
69159f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    + " config.bssid " + config.BSSID);
69169f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
69172f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        config.autoJoinBSSID = "any";
69182f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        config.BSSID = "any";
69192f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        if (DBG) {
69202f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle           loge(dbg + " " + config.SSID
69212f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle                    + " nid=" + Integer.toString(config.networkId));
69229f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle        }
69232f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle        mWifiConfigStore.saveWifiConfigBSSID(config);
69249f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle    }
69259f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
6926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class L2ConnectedState extends State {
6927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
6928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
6929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mRssiPollToken++;
6930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mEnableRssiPolling) {
6931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendMessage(CMD_RSSI_POLL, mRssiPollToken, 0);
6932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
69337d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            if (mNetworkAgent != null) {
69347d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt                loge("Have NetworkAgent when entering L2Connected");
69357d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt                setNetworkDetailedState(DetailedState.DISCONNECTED);
69367d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            }
69377d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            setNetworkDetailedState(DetailedState.CONNECTING);
6938e693d9490d27bcd91bb1f012bb88ef4c95cdaee3Robert Greenwalt
69393c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt            if (TextUtils.isEmpty(mTcpBufferSizes) == false) {
69403c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt                mLinkProperties.setTcpBufferSizes(mTcpBufferSizes);
69413c3c5b64726f04920109e4c8f20a1c58ea7050aaRobert Greenwalt            }
69427d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt            mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext,
69437d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt                    "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter,
69447d6e0b86655bf9862ae81fe37c9c8dc3f70d51f9Robert Greenwalt                    mLinkProperties, 60);
69459f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
69462f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            // We must clear the config BSSID, as the wifi chipset may decide to roam
69472f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            // from this point on and having the BSSID specified in the network block would
69482f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            // cause the roam to faile and the device to disconnect
69499f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            clearCurrentConfigBSSID("L2ConnectedState");
6950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
6951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
6952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
6953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
6954931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // This is handled by receiving a NETWORK_DISCONNECTION_EVENT in ConnectModeState
6955931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // Bug: 15347363
69568c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle            // For paranoia's sake, call handleNetworkDisconnect
69578c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle            // only if BSSID is null or last networkId
6958931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle            // is not invalid.
695956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle            if (DBG) {
696056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                StringBuilder sb = new StringBuilder();
696156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                sb.append("leaving L2ConnectedState state nid=" + Integer.toString(mLastNetworkId));
696256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                if (mLastBssid !=null) {
696356d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    sb.append(" ").append(mLastBssid);
696456d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                }
696556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle            }
6966b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            if (mLastBssid != null || mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
6967b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                handleNetworkDisconnect();
6968b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle            }
6969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
6970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
6971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
6972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
6973f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
6974f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
6975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
6976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
6977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  handlePreDhcpSetup();
6978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
6979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
6980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  handlePostDhcpSetup();
6981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
6982c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                      if (DBG) log("WifiStateMachine DHCP successful");
6983badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                      handleIPv4Success((DhcpResults) message.obj, DhcpStateMachine.DHCP_SUCCESS);
698414be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                      // We advance to mVerifyingLinkState because handleIPv4Success will call
698514be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                      // updateLinkProperties, which then sends CMD_IP_CONFIGURATION_SUCCESSFUL.
6986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
6987c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                      if (DBG) {
6988c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                          int count = -1;
6989c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                          WifiConfiguration config = getCurrentWifiConfiguration();
6990c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                          if (config != null) {
6991c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                              count = config.numConnectionFailures;
6992c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                          }
6993c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                          log("WifiStateMachine DHCP failure count=" + count);
6994c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle                      }
6995badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                      handleIPv4Failure(DhcpStateMachine.DHCP_FAILURE);
699614be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                      // As above, we transition to mDisconnectingState via updateLinkProperties.
6997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  }
6998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
699914be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                case CMD_IP_CONFIGURATION_SUCCESSFUL:
700014be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    handleSuccessfulIpConfiguration();
70014dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt                    sendConnectedState();
70024dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt                    transitionTo(mConnectedState);
700314be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    break;
700414be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                case CMD_IP_CONFIGURATION_LOST:
7005efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle                    // Get Link layer stats so as we get fresh tx packet counters
7006efad8ec6cb12e5658ee0288cc7e5aa755267aeb6vandwalle                    getWifiLinkLayerStats(true);
700714be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    handleIpConfigurationLost();
700814be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    transitionTo(mDisconnectingState);
700914be3cde626bd5935f599cd6e0fca72cf1c4695dLorenzo Colitti                    break;
7010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_DISCONNECT:
7011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.disconnect();
7012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectingState);
7013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST:
7015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == 1) {
7016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.disconnect();
7017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mTemporarilyDisconnectWifi = true;
7018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mDisconnectingState);
7019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
7022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 != CONNECT_MODE) {
7023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_DISCONNECT);
7024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        deferMessage(message);
70259f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        if (message.arg1 == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
70269f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                            noteWifiDisabledWhileAssociated();
70279f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        }
7028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7029104a9803187593ab25d3784b420077022686dbe4vandwalle                    mWifiConfigStore.
7030104a9803187593ab25d3784b420077022686dbe4vandwalle                                setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
7031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7032f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde                case CMD_SET_COUNTRY_CODE:
7033ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
7034f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde                    deferMessage(message);
7035f449336da3fc8f8f9b65de3ba359129779511199Vinit Deshapnde                    break;
7036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
70371ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                    //if (DBG) {
7038c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                        loge("WifiStateMachine CMD_START_SCAN source " + message.arg1
7039c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              + " txSuccessRate="+String.format( "%.2f", mWifiInfo.txSuccessRate)
7040c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              + " rxSuccessRate="+String.format( "%.2f", mWifiInfo.rxSuccessRate)
7041e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                              + " targetRoamBSSID=" + mTargetRoamBSSID
7042c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                              + " RSSI=" + mWifiInfo.getRssi());
70431ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                    //}
70444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    if (message.arg1 == SCAN_ALARM_SOURCE) {
70458242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        // Check if the CMD_START_SCAN message is obsolete (and thus if it should
70468242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        // not be processed) and restart the scan if needed
70478242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        boolean shouldScan =
70488242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                mScreenOn && mWifiConfigStore.enableAutoJoinScanWhenAssociated;
70498242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        if (!checkAndRestartDelayedScan(message.arg2,
70508242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                shouldScan,
70518242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                mWifiConfigStore.associatedPartialScanPeriodMilli, null, null)) {
70528242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE;
70538242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            loge("WifiStateMachine L2Connected CMD_START_SCAN source "
70548242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                    + message.arg1
70558242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                    + " " + message.arg2 + ", " + mDelayedScanCounter
70568242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                    + " -> obsolete");
70578242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            return HANDLED;
70588242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        }
7059a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        if (mP2pConnected.get()) {
7060a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                            loge("WifiStateMachine L2Connected CMD_START_SCAN source "
7061a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                                    + message.arg1
7062a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                                    + " " + message.arg2 + ", " + mDelayedScanCounter
7063a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                                    + " ignore because P2P is connected");
7064a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                            messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
7065a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                            return HANDLED;
7066a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        }
7067b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        boolean tryFullBandScan = false;
7068c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                        boolean restrictChannelList = false;
7069b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        long now_ms = System.currentTimeMillis();
7070e67ec726c07410073575473c0f50dc737629f5davandwalle                        if (DBG) {
7071e67ec726c07410073575473c0f50dc737629f5davandwalle                            loge("WifiStateMachine CMD_START_SCAN with age="
7072e67ec726c07410073575473c0f50dc737629f5davandwalle                                    + Long.toString(now_ms - lastFullBandConnectedTimeMilli)
7073e67ec726c07410073575473c0f50dc737629f5davandwalle                                    + " interval=" + fullBandConnectedTimeIntervalMilli
7074e67ec726c07410073575473c0f50dc737629f5davandwalle                                    + " maxinterval=" + maxFullBandConnectedTimeIntervalMilli);
7075e67ec726c07410073575473c0f50dc737629f5davandwalle                        }
70764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        if (mWifiInfo != null) {
7077e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                            if (mWifiConfigStore.enableFullBandScanWhenAssociated &&
7078e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                    (now_ms - lastFullBandConnectedTimeMilli)
7079c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    > fullBandConnectedTimeIntervalMilli) {
7080c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                if (DBG) {
7081c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    loge("WifiStateMachine CMD_START_SCAN try full band scan age="
7082e67ec726c07410073575473c0f50dc737629f5davandwalle                                         + Long.toString(now_ms - lastFullBandConnectedTimeMilli)
7083e67ec726c07410073575473c0f50dc737629f5davandwalle                                         + " interval=" + fullBandConnectedTimeIntervalMilli
7084e67ec726c07410073575473c0f50dc737629f5davandwalle                                         + " maxinterval=" + maxFullBandConnectedTimeIntervalMilli);
7085c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                }
7086b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                                tryFullBandScan = true;
7087b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                            }
7088b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
70899f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                            if (mWifiInfo.txSuccessRate >
70901ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                                    mWifiConfigStore.maxTxPacketForFullScans
70919f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                                    || mWifiInfo.rxSuccessRate >
70921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                                    mWifiConfigStore.maxRxPacketForFullScans) {
7093931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                                // Too much traffic at the interface, hence no full band scan
7094c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                if (DBG) {
7095c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    loge("WifiStateMachine CMD_START_SCAN " +
7096c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                            "prevent full band scan due to pkt rate");
7097c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                }
7098b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                                tryFullBandScan = false;
7099b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                            }
7100b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
71018c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                            if (mWifiInfo.txSuccessRate >
71029f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                                    mWifiConfigStore.maxTxPacketForPartialScans
71038c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                                    || mWifiInfo.rxSuccessRate >
71049f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                                    mWifiConfigStore.maxRxPacketForPartialScans) {
7105931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                                // Don't scan if lots of packets are being sent
7106c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                restrictChannelList = true;
71079f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                                if (mWifiConfigStore.alwaysEnableScansWhileAssociated == 0) {
7108c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    if (DBG) {
7109c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                     loge("WifiStateMachine CMD_START_SCAN source " + message.arg1
7110c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                        + " ...and ignore scans"
7111c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                        + " tx=" + String.format("%.2f", mWifiInfo.txSuccessRate)
7112c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                        + " rx=" + String.format("%.2f", mWifiInfo.rxSuccessRate));
7113c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    }
7114ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_REFUSED;
7115c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    return HANDLED;
71164dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                                }
71174dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            }
71184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        }
7119b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
71204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        WifiConfiguration currentConfiguration = getCurrentWifiConfiguration();
7121e67ec726c07410073575473c0f50dc737629f5davandwalle                        if (DBG) {
7122e67ec726c07410073575473c0f50dc737629f5davandwalle                            loge("WifiStateMachine CMD_START_SCAN full=" +
7123e67ec726c07410073575473c0f50dc737629f5davandwalle                                    tryFullBandScan);
7124e67ec726c07410073575473c0f50dc737629f5davandwalle                        }
71254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        if (currentConfiguration != null) {
7126e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                            if (fullBandConnectedTimeIntervalMilli
7127e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                    < mWifiConfigStore.associatedPartialScanPeriodMilli) {
7128e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                // Sanity
7129e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                fullBandConnectedTimeIntervalMilli
7130e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                        = mWifiConfigStore.associatedPartialScanPeriodMilli;
7131e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                            }
7132b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                            if (tryFullBandScan) {
7133b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                                lastFullBandConnectedTimeMilli = now_ms;
7134e67ec726c07410073575473c0f50dc737629f5davandwalle                                if (fullBandConnectedTimeIntervalMilli
71350eebae7334d6129f7ca1344e4b20199794994358vandwalle                                        < mWifiConfigStore.associatedFullScanMaxIntervalMilli) {
7136931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                                    // Increase the interval
7137c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                    fullBandConnectedTimeIntervalMilli
7138e67ec726c07410073575473c0f50dc737629f5davandwalle                                            = fullBandConnectedTimeIntervalMilli
7139e67ec726c07410073575473c0f50dc737629f5davandwalle                                            * mWifiConfigStore.associatedFullScanBackoff / 8;
7140e67ec726c07410073575473c0f50dc737629f5davandwalle
7141e67ec726c07410073575473c0f50dc737629f5davandwalle                                    if (DBG) {
7142e67ec726c07410073575473c0f50dc737629f5davandwalle                                        loge("WifiStateMachine CMD_START_SCAN bump interval ="
7143e67ec726c07410073575473c0f50dc737629f5davandwalle                                        + fullBandConnectedTimeIntervalMilli);
7144e67ec726c07410073575473c0f50dc737629f5davandwalle                                    }
71454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                                }
7146c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                handleScanRequest(
7147c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                                        WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message);
71484dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            } else {
71498c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                                if (!startScanForConfiguration(
71508c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                                        currentConfiguration, restrictChannelList)) {
7151b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                                    if (DBG) {
71528c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                                        loge("WifiStateMachine starting scan, " +
7153e67ec726c07410073575473c0f50dc737629f5davandwalle                                                " did not find channels -> full");
7154b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                                    }
7155e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                    lastFullBandConnectedTimeMilli = now_ms;
7156e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                    if (fullBandConnectedTimeIntervalMilli
7157e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                            < mWifiConfigStore.associatedFullScanMaxIntervalMilli) {
7158e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                        // Increase the interval
7159e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                        fullBandConnectedTimeIntervalMilli
7160e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                                = fullBandConnectedTimeIntervalMilli
7161e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                                * mWifiConfigStore.associatedFullScanBackoff / 8;
7162e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle
7163e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                        if (DBG) {
7164e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                            loge("WifiStateMachine CMD_START_SCAN bump interval ="
7165e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                                    + fullBandConnectedTimeIntervalMilli);
7166e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                        }
7167e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle                                    }
7168e67ec726c07410073575473c0f50dc737629f5davandwalle                                    handleScanRequest(
7169e67ec726c07410073575473c0f50dc737629f5davandwalle                                                WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message);
71704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                                }
71714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            }
71728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle
7173ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        } else {
7174ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                            loge("CMD_START_SCAN : connected mode and no configuration");
7175ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                            messageHandlingStatus = MESSAGE_HANDLING_STATUS_HANDLING_ERROR;
71764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        }
71774dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    } else {
7178ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        // Not scan alarm source
71798242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        return NOT_HANDLED;
71804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    }
7181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Ignore connection to same network */
7183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.CONNECT_NETWORK:
7184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int netId = message.arg1;
7185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiInfo.getNetworkId() == netId) {
7186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
7187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
7189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Ignore */
7190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
7191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RSSI_POLL:
7193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == mRssiPollToken) {
719470468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                        if (mWifiConfigStore.enableChipWakeUpWhenAssociated) {
719570468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            if (VVDBG) log(" get link layer stats " + mWifiLinkLayerStatsSupported);
719670468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            WifiLinkLayerStats stats = getWifiLinkLayerStats(VDBG);
719770468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            if (stats != null) {
719870468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                                // Sanity check the results provided by driver
719970468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                                if (mWifiInfo.getRssi() != WifiInfo.INVALID_RSSI
720070468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                                        && (stats.rssi_mgmt == 0
720170468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                                        || stats.beacon_rx == 0)) {
720270468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                                    stats = null;
720370468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                                }
720470468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            }
720570468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            // Get Info and continue polling
720670468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            fetchRssiLinkSpeedAndFrequencyNative();
720770468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                            calculateWifiScore(stats);
720827355a942653264388e909a4276196ee63e57811vandwalle                        }
7209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
7210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
7211e0ba94ba9abde13173ae0de8c8939aa4eb9a9085vandwalle
72129f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        if (DBG) sendRssiChangeBroadcast(mWifiInfo.getRssi());
7213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
7214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Polling has completed
7215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_RSSI_POLL:
721870468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    if (mWifiConfigStore.enableRssiPollWhenAssociated) {
721970468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                        mEnableRssiPolling = (message.arg1 == 1);
722070468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    } else {
722170468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                        mEnableRssiPolling = false;
722270468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    }
7223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mRssiPollToken++;
7224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mEnableRssiPolling) {
7225931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // First poll
722674b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme                        fetchRssiLinkSpeedAndFrequencyNative();
7227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
7228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
7229ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    } else {
7230ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        cleanWifiScore();
7231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.RSSI_PKTCNT_FETCH:
7234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    RssiPacketCountInfo info = new RssiPacketCountInfo();
723574b0804ef846b9b4888025092dd5c75143b559dcFelipe Leme                    fetchRssiLinkSpeedAndFrequencyNative();
7236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    info.rssi = mWifiInfo.getRssi();
7237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    fetchPktcntNative(info);
7238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED, info);
7239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
72407806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                case CMD_DELAYED_NETWORK_DISCONNECT:
72410eebae7334d6129f7ca1344e4b20199794994358vandwalle                    if (!linkDebouncing && mWifiConfigStore.enableLinkDebouncing) {
7242200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle
72437806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // Ignore if we are not debouncing
72448c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                        loge("CMD_DELAYED_NETWORK_DISCONNECT and not debouncing - ignore "
72458c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                                + message.arg1);
72467806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        return HANDLED;
72477806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    } else {
72488c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                        loge("CMD_DELAYED_NETWORK_DISCONNECT and debouncing - disconnect "
72498c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                                + message.arg1);
72507806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
72517806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        linkDebouncing = false;
72527806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // If we are still debouncing while this message comes,
72537806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // it means we were not able to reconnect within the alloted time
72547806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // = LINK_FLAPPING_DEBOUNCE_MSEC
72557806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // and thus, trigger a real disconnect
72567806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        handleNetworkDisconnect();
72577806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        transitionTo(mDisconnectedState);
72587806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
72597806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    break;
72609f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                case CMD_ASSOCIATED_BSSID:
72619f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if ((String) message.obj == null) {
72629f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        loge("Associated command w/o BSSID");
72639f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        break;
72649f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
72659f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    mLastBssid = (String) message.obj;
72669f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    mWifiInfo.setBSSID((String) message.obj);
72679f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    break;
7268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
7269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
7270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
7271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
7273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
7275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ObtainingIpState extends State {
7277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
7279b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle            if (DBG) {
7280b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                String key = "";
7281b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                if (getCurrentWifiConfiguration() != null) {
7282b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    key = getCurrentWifiConfiguration().configKey();
7283b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                }
7284b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                log("enter ObtainingIpState netId=" + Integer.toString(mLastNetworkId)
7285b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        + " " + key + " "
7286b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        + " roam=" + mAutoRoaming
72877806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        + " static=" + mWifiConfigStore.isUsingStaticIp(mLastNetworkId)
72887806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        + " watchdog= " + obtainingIpWatchdogCount);
7289b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle            }
7290b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
72917806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // Reset link Debouncing, indicating we have successfully re-connected to the AP
72927806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // We might still be roaming
72937806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            linkDebouncing = false;
72947806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
7295cdc5b747a9c6ff40a38a66bdd8f86dbf11852a7avandwalle            // Send event to CM & network change broadcast
7296cdc5b747a9c6ff40a38a66bdd8f86dbf11852a7avandwalle            setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
7297cdc5b747a9c6ff40a38a66bdd8f86dbf11852a7avandwalle
72982f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            // We must clear the config BSSID, as the wifi chipset may decide to roam
72992f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            // from this point on and having the BSSID specified in the network block would
73002f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            // cause the roam to faile and the device to disconnect
73019f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle            clearCurrentConfigBSSID("ObtainingIpAddress");
73029f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
73038b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti            try {
73048b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti                mNwService.enableIpv6(mInterfaceName);
73058b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti            } catch (RemoteException re) {
73068b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti                loge("Failed to enable IPv6: " + re);
73078b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti            } catch (IllegalStateException e) {
73088b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti                loge("Failed to enable IPv6: " + e);
73098b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti            }
73108b2bd657976c86e0909ad792f6f96ad94db45c28Lorenzo Colitti
7311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
7312b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                if (isRoaming()) {
73134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    renewDhcp();
73144dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                } else {
73153b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                    // Remove any IP address on the interface in case we're switching from static
73163b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                    // IP configuration to DHCP. This is safe because if we get here when not
73173b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                    // roaming, we don't have a usable address.
73180ebd6d71cecb5147fad1ca7a7f807aec7ffeddd9Lorenzo Colitti                    clearIPv4Address(mInterfaceName);
73194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    startDhcp();
73204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                }
73217806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                obtainingIpWatchdogCount++;
73227806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                loge("Start Dhcp Watchdog " + obtainingIpWatchdogCount);
73238242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                // Get Link layer stats so as we get fresh tx packet counters
73248242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                getWifiLinkLayerStats(true);
73257806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                sendMessageDelayed(obtainMessage(CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER,
73267806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        obtainingIpWatchdogCount, 0), OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC);
7327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
7328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // stop any running dhcp before assigning static IP
7329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                stopDhcp();
73303b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                StaticIpConfiguration config = mWifiConfigStore.getStaticIpConfiguration(
73313b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                        mLastNetworkId);
73323b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                if (config.ipAddress == null) {
7333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Static IP lacks address");
7334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(CMD_STATIC_IP_FAILURE);
7335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
73363b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                    InterfaceConfiguration ifcg = new InterfaceConfiguration();
73373b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                    ifcg.setLinkAddress(config.ipAddress);
7338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ifcg.setInterfaceUp();
7339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
7340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mNwService.setInterfaceConfig(mInterfaceName, ifcg);
7341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) log("Static IP configuration succeeded");
73423b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                        DhcpResults dhcpResults = new DhcpResults(config);
7343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_STATIC_IP_SUCCESS, dhcpResults);
7344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (RemoteException re) {
7345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Static IP configuration failed: " + re);
7346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_STATIC_IP_FAILURE);
7347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (IllegalStateException e) {
7348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Static IP configuration failed: " + e);
7349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_STATIC_IP_FAILURE);
7350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
7352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
7353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande      @Override
7355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande      public boolean processMessage(Message message) {
7356f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle          logStateAndMessage(message, getClass().getSimpleName());
7357f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande          switch(message.what) {
73598c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle              case CMD_STATIC_IP_SUCCESS:
7360badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                  handleIPv4Success((DhcpResults) message.obj, CMD_STATIC_IP_SUCCESS);
7361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
7362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande              case CMD_STATIC_IP_FAILURE:
7363badd604178e757a65dcff91ab1ff818e3527c8e3Lorenzo Colitti                  handleIPv4Failure(CMD_STATIC_IP_FAILURE);
7364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
73658c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle              case CMD_AUTO_CONNECT:
73668c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle              case CMD_AUTO_ROAM:
7367ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                  messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
73688c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                  break;
73698c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle              case WifiManager.SAVE_NETWORK:
7370be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle              case WifiStateMachine.CMD_AUTO_SAVE_NETWORK:
7371ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                  messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
7372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  deferMessage(message);
7373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
7374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  /* Defer any power mode changes since we must keep active power mode at DHCP */
7375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande              case CMD_SET_HIGH_PERF_MODE:
7376ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                  messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
7377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  deferMessage(message);
7378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
7379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  /* Defer scan request since we should not switch to other channels at DHCP */
7380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande              case CMD_START_SCAN:
7381ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                  messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
7382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  deferMessage(message);
7383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  break;
73847806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle              case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER:
73857806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                  if (message.arg1 == obtainingIpWatchdogCount) {
73868c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                      loge("ObtainingIpAddress: Watchdog Triggered, count="
73878c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                              + obtainingIpWatchdogCount);
73887806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                      handleIpConfigurationLost();
73897806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                      transitionTo(mDisconnectingState);
73907806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                      break;
73917806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                  }
7392ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                  messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
7393ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                  break;
7394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande              default:
7395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                  return NOT_HANDLED;
7396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande          }
7397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande          return HANDLED;
7398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande      }
7399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
7400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class VerifyingLinkState extends State {
7402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
7404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            log(getName() + " enter");
7405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setNetworkDetailedState(DetailedState.VERIFYING_POOR_LINK);
7406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.VERIFYING_POOR_LINK);
7407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendNetworkStateChangeBroadcast(mLastBssid);
74087806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // End roaming
7409b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle            mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE;
7410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
7413f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
7414f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
7416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
7417931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Stay here
7418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    log(getName() + " POOR_LINK_DETECTED: no transition");
7419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
7421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    log(getName() + " GOOD_LINK_DETECTED: transition to captive portal check");
7422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    log(getName() + " GOOD_LINK_DETECTED: transition to CONNECTED");
74244dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt                    sendConnectedState();
7425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mConnectedState);
7426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
7428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log(getName() + " what=" + message.what + " NOT_HANDLED");
7429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
7430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
7431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
7432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
7434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
74354dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt    private void sendConnectedState() {
74364dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        // Send out a broadcast with the CAPTIVE_PORTAL_CHECK to preserve
74374dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        // existing behaviour. The captive portal check really happens after we
74384dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        // transition into DetailedState.CONNECTED.
74394dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK);
74404dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        mWifiConfigStore.updateStatus(mLastNetworkId,
74414dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        DetailedState.CAPTIVE_PORTAL_CHECK);
74424dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        sendNetworkStateChangeBroadcast(mLastBssid);
74434dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt
74442dbf6c027271518d868ae52ad90789eb2bc3c363Robert Greenwalt        if (mWifiConfigStore.getLastSelectedConfiguration() != null) {
74452dbf6c027271518d868ae52ad90789eb2bc3c363Robert Greenwalt            if (mNetworkAgent != null) mNetworkAgent.explicitlySelected();
74462dbf6c027271518d868ae52ad90789eb2bc3c363Robert Greenwalt        }
74472dbf6c027271518d868ae52ad90789eb2bc3c363Robert Greenwalt
74484dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        setNetworkDetailedState(DetailedState.CONNECTED);
74494dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
74504dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt        sendNetworkStateChangeBroadcast(mLastBssid);
74514dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt    }
74524dd46ff3cff8e4e66516600ffdac98601e8bf73dRobert Greenwalt
74534dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    class RoamingState extends State {
7454448c9536a302c58a79e271b1721c08b8882f800evandwalle        boolean mAssociated;
74554dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        @Override
74564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        public void enter() {
74574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            if (DBG) {
74584dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                log("RoamingState Enter"
74594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        + " mScreenOn=" + mScreenOn );
74604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            }
74618242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            setScanAlarm(false);
74620d616ef3bf635dff8722e064c0be842676390ed8vandwalle
74630d616ef3bf635dff8722e064c0be842676390ed8vandwalle            // Make sure we disconnect if roaming fails
74640d616ef3bf635dff8722e064c0be842676390ed8vandwalle            roamWatchdogCount++;
74650d616ef3bf635dff8722e064c0be842676390ed8vandwalle            loge("Start Roam Watchdog " + roamWatchdogCount);
74660d616ef3bf635dff8722e064c0be842676390ed8vandwalle            sendMessageDelayed(obtainMessage(CMD_ROAM_WATCHDOG_TIMER,
74670d616ef3bf635dff8722e064c0be842676390ed8vandwalle                    roamWatchdogCount, 0), ROAM_GUARD_TIMER_MSEC);
7468448c9536a302c58a79e271b1721c08b8882f800evandwalle            mAssociated = false;
74694dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
74704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        @Override
74714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        public boolean processMessage(Message message) {
74724dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            logStateAndMessage(message, getClass().getSimpleName());
74734fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle            WifiConfiguration config;
74744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            switch (message.what) {
74754fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                case CMD_IP_CONFIGURATION_LOST:
74764fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                    config = getCurrentWifiConfiguration();
74774fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                    if (config != null) {
74784fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                        mWifiConfigStore.noteRoamingFailure(config,
74794fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                                WifiConfiguration.ROAMING_FAILURE_IP_CONFIG);
74804fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                    }
74814fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                    return NOT_HANDLED;
74824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
74834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    if (DBG) log("Roaming and Watchdog reports poor link -> ignore");
74844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    return HANDLED;
74854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               case CMD_UNWANTED_NETWORK:
74864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    if (DBG) log("Roaming and CS doesnt want the network -> ignore");
74874dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    return HANDLED;
74884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               case CMD_SET_OPERATIONAL_MODE:
74894dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    if (message.arg1 != CONNECT_MODE) {
74904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        deferMessage(message);
74914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    }
74924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    break;
74934dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
7494931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    /**
749597b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                     * If we get a SUPPLICANT_STATE_CHANGE_EVENT indicating a DISCONNECT
749697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                     * before NETWORK_DISCONNECTION_EVENT
749797b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                     * And there is an associated BSSID corresponding to our target BSSID, then
74984dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                     * we have missed the network disconnection, transition to mDisconnectedState
749997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                     * and handle the rest of the events there.
75004dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                     */
75014dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
750297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                    if (stateChangeResult.state == SupplicantState.DISCONNECTED
750397b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                            || stateChangeResult.state == SupplicantState.INACTIVE
750497b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                            || stateChangeResult.state == SupplicantState.INTERFACE_DISABLED) {
750597b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                        if (DBG) {
750697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                            log("STATE_CHANGE_EVENT in roaming state "
750797b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                                    + stateChangeResult.toString() );
750897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                        }
750997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                        if (stateChangeResult.BSSID != null
751097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                                && stateChangeResult.BSSID.equals(mTargetRoamBSSID)) {
751197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                            handleNetworkDisconnect();
75120d616ef3bf635dff8722e064c0be842676390ed8vandwalle                            transitionTo(mDisconnectedState);
751397b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                        }
751497b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle                    }
7515448c9536a302c58a79e271b1721c08b8882f800evandwalle                    if (stateChangeResult.state == SupplicantState.ASSOCIATED) {
7516448c9536a302c58a79e271b1721c08b8882f800evandwalle                        // We completed the layer2 roaming part
7517448c9536a302c58a79e271b1721c08b8882f800evandwalle                        mAssociated = true;
7518e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        if (stateChangeResult.BSSID != null) {
7519e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            mTargetRoamBSSID = (String) stateChangeResult.BSSID;
7520e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        }
7521448c9536a302c58a79e271b1721c08b8882f800evandwalle                    }
75224dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    break;
75230d616ef3bf635dff8722e064c0be842676390ed8vandwalle                case CMD_ROAM_WATCHDOG_TIMER:
75240d616ef3bf635dff8722e064c0be842676390ed8vandwalle                    if (roamWatchdogCount == message.arg1) {
75250d616ef3bf635dff8722e064c0be842676390ed8vandwalle                        if (DBG) log("roaming watchdog! -> disconnect");
75269f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        mRoamFailCount++;
75270d616ef3bf635dff8722e064c0be842676390ed8vandwalle                        handleNetworkDisconnect();
75280d616ef3bf635dff8722e064c0be842676390ed8vandwalle                        mWifiNative.disconnect();
75290d616ef3bf635dff8722e064c0be842676390ed8vandwalle                        transitionTo(mDisconnectedState);
75300d616ef3bf635dff8722e064c0be842676390ed8vandwalle                    }
75310d616ef3bf635dff8722e064c0be842676390ed8vandwalle                    break;
75324dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               case WifiMonitor.NETWORK_CONNECTION_EVENT:
7533448c9536a302c58a79e271b1721c08b8882f800evandwalle                   if (mAssociated) {
7534448c9536a302c58a79e271b1721c08b8882f800evandwalle                       if (DBG) log("roaming and Network connection established");
7535448c9536a302c58a79e271b1721c08b8882f800evandwalle                       mLastNetworkId = message.arg1;
7536448c9536a302c58a79e271b1721c08b8882f800evandwalle                       mLastBssid = (String) message.obj;
7537448c9536a302c58a79e271b1721c08b8882f800evandwalle                       mWifiInfo.setBSSID(mLastBssid);
7538448c9536a302c58a79e271b1721c08b8882f800evandwalle                       mWifiInfo.setNetworkId(mLastNetworkId);
7539448c9536a302c58a79e271b1721c08b8882f800evandwalle                       mWifiConfigStore.handleBSSIDBlackList(mLastNetworkId, mLastBssid, true);
7540448c9536a302c58a79e271b1721c08b8882f800evandwalle                       transitionTo(mObtainingIpState);
7541448c9536a302c58a79e271b1721c08b8882f800evandwalle                   } else {
7542448c9536a302c58a79e271b1721c08b8882f800evandwalle                       messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
7543448c9536a302c58a79e271b1721c08b8882f800evandwalle                   }
75444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                   break;
75454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle               case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
75460d616ef3bf635dff8722e064c0be842676390ed8vandwalle                   // Throw away but only if it corresponds to the network we're roaming to
7547b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                   String bssid = (String)message.obj;
75488c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                   if (true) {
75498c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                       String target = "";
75508c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                       if (mTargetRoamBSSID != null) target = mTargetRoamBSSID;
7551b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                       log("NETWORK_DISCONNECTION_EVENT in roaming state"
75528c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                               + " BSSID=" + bssid
75538c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                               + " target=" + target);
7554b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                   }
7555b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                   if (bssid != null && bssid.equals(mTargetRoamBSSID)) {
7556b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                       handleNetworkDisconnect();
75578c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                       transitionTo(mDisconnectedState);
7558b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                   }
75594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                   break;
7560b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                case WifiMonitor.SSID_TEMP_DISABLED:
7561931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Auth error while roaming
75628c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    loge("SSID_TEMP_DISABLED nid=" + Integer.toString(mLastNetworkId)
75638c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                            + " id=" + Integer.toString(message.arg1)
75648c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                            + " isRoaming=" + isRoaming()
75658c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                            + " roam=" + Integer.toString(mAutoRoaming));
7566b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    if (message.arg1 == mLastNetworkId) {
75674fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                        config = getCurrentWifiConfiguration();
75684fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                        if (config != null) {
75694fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                            mWifiConfigStore.noteRoamingFailure(config,
75704fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                                    WifiConfiguration.ROAMING_FAILURE_AUTH_FAILURE);
75714fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle                        }
75728c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                        handleNetworkDisconnect();
7573b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        transitionTo(mDisconnectingState);
7574b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    }
7575b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                    return NOT_HANDLED;
7576b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                case CMD_START_SCAN:
7577b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    deferMessage(message);
7578b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    break;
7579b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                default:
75804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    return NOT_HANDLED;
75814dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            }
75824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            return HANDLED;
75834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
75844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
75854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        @Override
75864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        public void exit() {
75874dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            loge("WifiStateMachine: Leaving Roaming state");
75884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle        }
75894dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle    }
75904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
7591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ConnectedState extends State {
7592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7593f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        public void enter() {
7594f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            String address;
7595f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            updateDefaultRouteMacAddress(1000);
7596f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (DBG) {
7597be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                log("ConnectedState Enter "
7598f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        + " mScreenOn=" + mScreenOn
7599e67ec726c07410073575473c0f50dc737629f5davandwalle                        + " scanperiod="
76000eebae7334d6129f7ca1344e4b20199794994358vandwalle                        + Integer.toString(mWifiConfigStore.associatedPartialScanPeriodMilli) );
7601f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
76022f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle            if (mScreenOn
760370468b47454c8657e8963932f2e08a3f4d7e3881vandwalle                    && mWifiConfigStore.enableAutoJoinScanWhenAssociated) {
76048242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                // restart scan alarm
76058242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                startDelayedScan(mWifiConfigStore.associatedPartialScanPeriodMilli, null, null);
7606f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
76074dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            registerConnected();
7608b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle            lastConnectAttempt = 0;
760940ff222cec1bd05879edb53abc75c6deead734cavandwalle            targetWificonfiguration = null;
76107806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // Paranoia
76117806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            linkDebouncing = false;
76127806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
76137806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            // Not roaming anymore
76147806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE;
761540ff222cec1bd05879edb53abc75c6deead734cavandwalle
76167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            if (testNetworkDisconnect) {
76177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                testNetworkDisconnectCounter++;
76187806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                loge("ConnectedState Enter start disconnect test " +
76197806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        testNetworkDisconnectCounter);
76207806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                sendMessageDelayed(obtainMessage(CMD_TEST_NETWORK_DISCONNECT,
76217806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        testNetworkDisconnectCounter, 0), 15000);
76227806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle            }
76239f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
7624be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // Reenable all networks, allow for hidden networks to be scanned
7625be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            mWifiConfigStore.enableAllNetworks();
762685f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle
762785f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle            mLastDriverRoamAttempt = 0;
7628f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
7629f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        @Override
7630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
7631be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            WifiConfiguration config = null;
7632f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
7633f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
76354dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
7636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Watchdog reports poor link");
7637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mVerifyingLinkState);
7638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
763927355a942653264388e909a4276196ee63e57811vandwalle                case CMD_UNWANTED_NETWORK:
7640e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    if (message.arg1 == network_status_unwanted_disconnect) {
7641e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        mWifiConfigStore.handleBadNetworkDisconnectReport(mLastNetworkId, mWifiInfo);
7642e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        mWifiNative.disconnect();
7643e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        transitionTo(mDisconnectingState);
7644f9715cc118c446695b2a82211881c7d6c5e59761vandwalle                    } else if (message.arg1 == network_status_unwanted_disable_autojoin) {
7645e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        config = getCurrentWifiConfiguration();
7646e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        if (config != null) {
7647e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                            // Disable autojoin
7648d30127db46224e45554f8964209221bba8ad41d9vandwalle                            config.numNoInternetAccessReports += 1;
7649d30127db46224e45554f8964209221bba8ad41d9vandwalle                        }
7650d30127db46224e45554f8964209221bba8ad41d9vandwalle                    }
7651d30127db46224e45554f8964209221bba8ad41d9vandwalle                    return HANDLED;
7652d30127db46224e45554f8964209221bba8ad41d9vandwalle                case CMD_NETWORK_STATUS:
7653d30127db46224e45554f8964209221bba8ad41d9vandwalle                    if (message.arg1 == NetworkAgent.VALID_NETWORK) {
7654d30127db46224e45554f8964209221bba8ad41d9vandwalle                        config = getCurrentWifiConfiguration();
7655d30127db46224e45554f8964209221bba8ad41d9vandwalle                        if (config != null) {
7656d30127db46224e45554f8964209221bba8ad41d9vandwalle                            // re-enable autojoin
7657d30127db46224e45554f8964209221bba8ad41d9vandwalle                            config.numNoInternetAccessReports = 0;
7658d30127db46224e45554f8964209221bba8ad41d9vandwalle                            config.validatedInternetAccess = true;
7659e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                        }
7660e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle                    }
766127355a942653264388e909a4276196ee63e57811vandwalle                    return HANDLED;
76627806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                case CMD_TEST_NETWORK_DISCONNECT:
76637806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    // Force a disconnect
76647806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    if (message.arg1 == testNetworkDisconnectCounter) {
76657806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        mWifiNative.disconnect();
76667806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
76677806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    break;
766885f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                case CMD_ASSOCIATED_BSSID:
766985f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    // ASSOCIATING to a new BSSID while already connected, indicates
767085f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    // that driver is roaming
767185f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    mLastDriverRoamAttempt = System.currentTimeMillis();
76721ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                    String toBSSID = (String)message.obj;
76731ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                    if (toBSSID != null && !toBSSID.equals(mWifiInfo.getBSSID())) {
76741ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                        mWifiConfigStore.driverRoamedFrom(mWifiInfo);
76751ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                    }
767685f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    return NOT_HANDLED;
76777806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
767885f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    long lastRoam = 0;
767985f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    if (mLastDriverRoamAttempt != 0) {
768085f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                        // Calculate time since last driver roam attempt
768185f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                        lastRoam = System.currentTimeMillis() - mLastDriverRoamAttempt;
768285f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                        mLastDriverRoamAttempt = 0;
768385f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    }
7684be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    config = getCurrentWifiConfiguration();
7685c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                    if (mScreenOn
7686c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                            && !linkDebouncing
7687c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                            && config != null
7688c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                            && config.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED
7689c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                            && !mWifiConfigStore.isLastSelectedConfiguration(config)
769085f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                            && (message.arg2 != 3 /* reason cannot be 3, i.e. locally generated */
769185f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                                || (lastRoam > 0 && lastRoam < 2000) /* unless driver is roaming */)
7692c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                            && ((ScanResult.is24GHz(mWifiInfo.getFrequency())
76937806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    && mWifiInfo.getRssi() >
76947806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    WifiConfiguration.BAD_RSSI_24)
76957806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    || (ScanResult.is5GHz(mWifiInfo.getFrequency())
76967806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    && mWifiInfo.getRssi() >
76977806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    WifiConfiguration.BAD_RSSI_5))) {
76987806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // Start de-bouncing the L2 disconnection:
76997806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // this L2 disconnection might be spurious.
77007806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // Hence we allow 7 seconds for the state machine to try
77017806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // to reconnect, go thru the
77027806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // roaming cycle and enter Obtaining IP address
77037806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        // before signalling the disconnect to ConnectivityService and L3
77047806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        startScanForConfiguration(getCurrentWifiConfiguration(), false);
77057806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        linkDebouncing = true;
77067806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle
77077806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        sendMessageDelayed(obtainMessage(CMD_DELAYED_NETWORK_DISCONNECT,
77087806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                0, mLastNetworkId), LINK_FLAPPING_DEBOUNCE_MSEC);
77097806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        if (DBG) {
77107806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                            log("NETWORK_DISCONNECTION_EVENT in connected state"
77117806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " BSSID=" + mWifiInfo.getBSSID()
77127806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " RSSI=" + mWifiInfo.getRssi()
77137806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " freq=" + mWifiInfo.getFrequency()
7714c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                                    + " reason=" + message.arg2
77157806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " -> debounce");
77167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        }
77177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        return HANDLED;
77187806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    } else {
77197806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        if (DBG) {
7720be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            int ajst = -1;
7721be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                            if (config != null) ajst = config.autoJoinStatus;
77227806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                            log("NETWORK_DISCONNECTION_EVENT in connected state"
77237806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " BSSID=" + mWifiInfo.getBSSID()
77247806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " RSSI=" + mWifiInfo.getRssi()
77257806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                                    + " freq=" + mWifiInfo.getFrequency()
7726be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                    + " was debouncing=" + linkDebouncing
7727c9b047b4cb480edbb490516746cfcbb4a4eedeeavandwalle                                    + " reason=" + message.arg2
7728be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                                    + " ajst=" + ajst);
77297806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        }
77307806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
77317806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    break;
77324dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                case CMD_AUTO_ROAM:
773385f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    // Clear the driver roam indication since we are attempting a framerwork roam
773485f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle                    mLastDriverRoamAttempt = 0;
773585f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle
7736931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    /* Connect command coming from auto-join */
7737b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle                    ScanResult candidate = (ScanResult)message.obj;
77387806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    String bssid = "any";
7739e67ec726c07410073575473c0f50dc737629f5davandwalle                    if (candidate != null && candidate.is5GHz()) {
7740e67ec726c07410073575473c0f50dc737629f5davandwalle                        // Only lock BSSID for 5GHz networks
77417806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                        bssid = candidate.BSSID;
77427806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle                    }
77434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    int netId = mLastNetworkId;
7744be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    config = getCurrentWifiConfiguration();
77454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
77469f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
77479f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (config == null) {
77489f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        loge("AUTO_ROAM and no config, bail out...");
77499f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        break;
77509f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
77519f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
77524dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    loge("CMD_AUTO_ROAM sup state "
77534dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            + mSupplicantStateTracker.getSupplicantStateName()
77544dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            + " my state " + getCurrentState().getName()
77554dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                            + " nid=" + Integer.toString(netId)
77569f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                            + " config " + config.configKey()
7757b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                            + " roam=" + Integer.toString(message.arg2)
77589f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                            + " to " + bssid
77599f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                            + " targetRoamBSSID " + mTargetRoamBSSID);
77604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
7761931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    /* Save the BSSID so as to lock it @ firmware */
77629d082c381274f27dad1e344223189e00148e2124vandwalle                    if (!autoRoamSetBSSID(config, bssid) && !linkDebouncing) {
77639f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        loge("AUTO_ROAM nothing to do");
77649f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        // Same BSSID, nothing to do
77659e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
77669f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        break;
77679f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    };
77689f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle
7769b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    // Make sure the network is enabled, since supplicant will not reenable it
7770b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle                    mWifiConfigStore.enableNetworkWithoutBroadcast(netId, false);
7771b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle
7772e67ec726c07410073575473c0f50dc737629f5davandwalle                    boolean ret = false;
77731ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                    if (mLastNetworkId != netId) {
77741ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                       if (mWifiConfigStore.selectNetwork(netId) &&
77751ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                           mWifiNative.reconnect()) {
77761ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                           ret = true;
77771ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                       }
7778e67ec726c07410073575473c0f50dc737629f5davandwalle                    } else {
77791ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle                         ret = mWifiNative.reassociate();
7780e67ec726c07410073575473c0f50dc737629f5davandwalle                    }
7781e67ec726c07410073575473c0f50dc737629f5davandwalle                    if (ret) {
7782b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        lastConnectAttempt = System.currentTimeMillis();
778340ff222cec1bd05879edb53abc75c6deead734cavandwalle                        targetWificonfiguration = mWifiConfigStore.getWifiConfiguration(netId);
778440ff222cec1bd05879edb53abc75c6deead734cavandwalle
7785931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                        // replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
7786b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle                        mAutoRoaming = message.arg2;
77874dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        transitionTo(mRoamingState);
77884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
77894dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    } else {
77904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        loge("Failed to connect config: " + config + " netId: " + netId);
77914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
77924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                                WifiManager.ERROR);
77939e806a8d9f297e4de826e65322859a89e4d95c8bvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
77944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                        break;
77954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    }
77964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle                    break;
7797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
7798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
7799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
7800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
7801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
7805f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            loge("WifiStateMachine: Leaving Connected state");
78068242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            setScanAlarm(false);
780785f2d77b1b858c063471951f3a5f93c96bd5e72bvandwalle            mLastDriverRoamAttempt = 0;
7808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
7810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DisconnectingState extends State {
7812f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7813f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        @Override
7814f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        public void enter() {
7815f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7816f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (PDBG) {
7817f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                loge(" Enter DisconnectingState State scan interval " + mFrameworkScanIntervalMs
7818f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        + " mEnableBackgroundScan= " + mEnableBackgroundScan
7819f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        + " screenOn=" + mScreenOn);
7820f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
7821be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle
7822be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // Make sure we disconnect: we enter this state prior connecting to a new
7823be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // network, waiting for either a DISCONECT event or a SUPPLICANT_STATE_CHANGE
7824be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // event which in this case will be indicating that supplicant started to associate.
7825be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // In some cases supplicant doesn't ignore the connect requests (it might not
7826be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // find the target SSID in its cache),
7827be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            // Therefore we end up stuck that state, hence the need for the watchdog.
7828be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            disconnectingWatchdogCount++;
7829be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            loge("Start Disconnecting Watchdog " + disconnectingWatchdogCount);
7830be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle            sendMessageDelayed(obtainMessage(CMD_DISCONNECTING_WATCHDOG_TIMER,
7831be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    disconnectingWatchdogCount, 0), DISCONNECTING_GUARD_TIMER_MSEC);
7832f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        }
7833f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
7836f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
7837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
7838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
7839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 != CONNECT_MODE) {
7840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        deferMessage(message);
7841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7843b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                case CMD_START_SCAN:
78448242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    deferMessage(message);
7845b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    return HANDLED;
7846be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                case CMD_DISCONNECTING_WATCHDOG_TIMER:
7847be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    if (disconnectingWatchdogCount == message.arg1) {
7848be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        if (DBG) log("disconnecting watchdog! -> disconnect");
7849be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        handleNetworkDisconnect();
7850be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                        transitionTo(mDisconnectedState);
7851be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    }
7852be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    break;
7853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
7854be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                    /**
7855be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle                     * If we get a SUPPLICANT_STATE_CHANGE_EVENT before NETWORK_DISCONNECTION_EVENT
7856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * we have missed the network disconnection, transition to mDisconnectedState
7857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     * and handle the rest of the events there
7858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                     */
7859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
7860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleNetworkDisconnect();
7861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectedState);
7862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
7864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
7865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
7866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
7867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7868f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
7869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7870f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    class DisconnectedState extends State {
7871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
7873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // We dont scan frequently if this is a temporary disconnect
7874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // due to p2p
7875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mTemporarilyDisconnectWifi) {
7876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE);
7877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return;
7878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
7879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mFrameworkScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
7881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
7882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDefaultFrameworkScanIntervalMs);
7883f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7884f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            if (PDBG) {
7885f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                loge(" Enter disconnected State scan interval " + mFrameworkScanIntervalMs
7886f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle                        + " mEnableBackgroundScan= " + mEnableBackgroundScan
7887833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                        + " screenOn=" + mScreenOn
7888833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle                        + " mFrameworkScanIntervalMs=" + mFrameworkScanIntervalMs);
7889f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
7890f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
78914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle            /** clear the roaming state, if we were roaming, we failed */
7892b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle            mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE;
78934dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle
78948242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            if (mScreenOn) {
78958242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                /**
78968242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                 * screen lit and => delayed timer
7897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 */
78988242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                startDelayedScan(mDisconnectedScanPeriodMs, null, null);
7899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
79008242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                /**
79018242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                 * screen dark and PNO supported => scan alarm disabled
79028242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                 */
79038242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                if (mEnableBackgroundScan) {
79048242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    /* If a regular scan result is pending, do not initiate background
79058242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                     * scan until the scan results are returned. This is needed because
79068242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                     * initiating a background scan will cancel the regular scan and
79078242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                     * scan results will not be returned until background scanning is
79088242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                     * cleared
79098242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                     */
79108242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    if (!mIsScanOngoing) {
79118242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        enableBackgroundScan(true);
79128242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    }
79138242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                } else {
79148242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    setScanAlarm(true);
79158242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                }
7916f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            }
7917f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /**
7919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * If we have no networks saved, the supplicant stops doing the periodic scan.
7920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * The scans are useful to notify the user of the presence of an open network.
7921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * Note that these are not wake up scans.
7922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             */
7923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (!mP2pConnected.get() && mWifiConfigStore.getConfiguredNetworks().size() == 0) {
7924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
7925c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle                        ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
7926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
79270eebae7334d6129f7ca1344e4b20199794994358vandwalle
79280eebae7334d6129f7ca1344e4b20199794994358vandwalle            mDisconnectedTimeStamp = System.currentTimeMillis();
79290eebae7334d6129f7ca1344e4b20199794994358vandwalle
7930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
7931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
7932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
7933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
7934f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7935f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
7936f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
7937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
7938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_NO_NETWORKS_PERIODIC_SCAN:
7939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mP2pConnected.get()) break;
7940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == mPeriodicScanToken &&
7941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiConfigStore.getConfiguredNetworks().size() == 0) {
7942ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                        startScan(UNKNOWN_SCAN_SOURCE, -1, null, null);
7943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
7944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
7945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.FORGET_NETWORK:
7948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REMOVE_NETWORK:
7949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Set up a delayed message here. After the forget/remove is handled
7950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // the handled delayed message will determine if there is a need to
7951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // scan and continue
7952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
7953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
7954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ret = NOT_HANDLED;
7955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
7957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 != CONNECT_MODE) {
7958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mOperationalMode = message.arg1;
7959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
7960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiConfigStore.disableAllNetworks();
7961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
7962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiP2pChannel.sendMessage(CMD_DISABLE_P2P_REQ);
7963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            setWifiState(WIFI_STATE_DISABLED);
7964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
7965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mScanModeState);
7966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
7967104a9803187593ab25d3784b420077022686dbe4vandwalle                    mWifiConfigStore.
7968104a9803187593ab25d3784b420077022686dbe4vandwalle                            setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
7969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Ignore network disconnect */
7971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
7972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
7974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
79759f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    if (DBG) {
79769f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                        loge("SUPPLICANT_STATE_CHANGE_EVENT state=" + stateChangeResult.state +
79779f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                                " -> state= " + WifiInfo.getDetailedStateOf(stateChangeResult.state)
79789f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                                + " debouncing=" + linkDebouncing);
79799f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle                    }
7980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
7981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* ConnectModeState does the rest of the handling */
7982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ret = NOT_HANDLED;
7983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SCAN:
79858242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    if (!checkOrDeferScanAllowed(message)) {
79868242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        // The scan request was rescheduled
79878242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_REFUSED;
7988b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                        return HANDLED;
7989b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    }
7990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Disable background scan temporarily during a regular scan */
7991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mEnableBackgroundScan) {
7992cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande                        enableBackgroundScan(false);
7993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
79948242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    if (message.arg1 == SCAN_ALARM_SOURCE) {
79958242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        // Check if the CMD_START_SCAN message is obsolete (and thus if it should
79968242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        // not be processed) and restart the scan
7997a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        int period =  mDisconnectedScanPeriodMs;
7998a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        if (mP2pConnected.get()) {
7999a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                           period = (int)Settings.Global.getLong(mContext.getContentResolver(),
8000a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                                    Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
8001a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                                    mDisconnectedScanPeriodMs);
8002a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        }
80038242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        if (!checkAndRestartDelayedScan(message.arg2,
8004a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                                true, period, null, null)) {
80058242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE;
80068242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            loge("WifiStateMachine Disconnected CMD_START_SCAN source "
80078242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                    + message.arg1
80088242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                    + " " + message.arg2 + ", " + mDelayedScanCounter
80098242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                                    + " -> obsolete");
80108242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                            return HANDLED;
80118242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        }
80128242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message);
80138242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        ret = HANDLED;
80148242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    } else {
80158242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                        ret = NOT_HANDLED;
80168242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle                    }
8017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SCAN_RESULTS_EVENT:
8019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Re-enable background scan when a pending scan result is received */
8020a0009d14075b5345b8f916c3fb3f2260c938cb9dYuhao Zheng                    if (mEnableBackgroundScan && mIsScanOngoing) {
8021cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande                        enableBackgroundScan(true);
8022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Handled in parent state */
8024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ret = NOT_HANDLED;
8025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
8027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    NetworkInfo info = (NetworkInfo) message.obj;
8028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mP2pConnected.set(info.isConnected());
8029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mP2pConnected.get()) {
8030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        int defaultInterval = mContext.getResources().getInteger(
8031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                R.integer.config_wifi_scan_interval_p2p_connected);
8032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        long scanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
8033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
8034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                defaultInterval);
8035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.setScanInterval((int) scanIntervalMs/1000);
8036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (mWifiConfigStore.getConfiguredNetworks().size() == 0) {
8037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) log("Turn on scanning after p2p disconnected");
8038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
8039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
8040a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                    } else {
8041a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        // If P2P is not connected and there are saved networks, then restart
8042a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        // scanning at the normal period. This is necessary because scanning might
8043a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        // have been disabled altogether if WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS
8044a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        // was set to zero.
8045a1c02f0a73ee35e198e2652cd65b8830a163d9ddvandwalle                        startDelayedScan(mDisconnectedScanPeriodMs, null, null);
8046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
8048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
8049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mTemporarilyDisconnectWifi) {
8050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Drop a third party reconnect/reassociate if STA is
8051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // temporarily disconnected for p2p
8052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
8053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
8054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // ConnectModeState handles it
8055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = NOT_HANDLED;
8056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
80587c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                case CMD_SCREEN_STATE_CHANGED:
80597c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                    handleScreenStateChanged(message.arg1 != 0,
80607c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                            /* startBackgroundScanIfNeeded = */ true);
80617c8a4effa2442b9d00fd421b443ea9645f8651c8Vinit Deshpande                    break;
8062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ret = NOT_HANDLED;
8064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
8066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
8070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* No need for a background scan upon exit from a disconnected state */
8071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mEnableBackgroundScan) {
8072cce5b9e0eded28096991578e020883484ece8c54Vinit Deshpande                enableBackgroundScan(false);
8073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
80748242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle            setScanAlarm(false);
8075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class WpsRunningState extends State {
8079931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle        // Tracks the source to provide a reply
8080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private Message mSourceMessage;
8081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
8083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSourceMessage = Message.obtain(getCurrentMessage());
8084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
8087f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
8088f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
8089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
8090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_SUCCESS_EVENT:
8091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Ignore intermediate success, wait for full connection
8092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
8094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(mSourceMessage, WifiManager.WPS_COMPLETED);
8095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSourceMessage.recycle();
8096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSourceMessage = null;
8097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
8098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectedState);
8099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_OVERLAP_EVENT:
8101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED,
8102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.WPS_OVERLAP_ERROR);
8103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSourceMessage.recycle();
8104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSourceMessage = null;
8105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectedState);
8106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_FAIL_EVENT:
8108931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Arg1 has the reason for the failure
810982b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                    if ((message.arg1 != WifiManager.ERROR) || (message.arg2 != 0)) {
811082b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                        replyToMessage(mSourceMessage, WifiManager.WPS_FAILED, message.arg1);
811182b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                        mSourceMessage.recycle();
811282b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                        mSourceMessage = null;
811382b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                        transitionTo(mDisconnectedState);
811482b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                    } else {
811582b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                        if (DBG) log("Ignore unspecified fail event during WPS connection");
811682b91fd1a87ae9000bac54fb44981d5003958de1Vinit Deshpande                    }
8117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_TIMEOUT_EVENT:
8119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED,
8120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiManager.WPS_TIMED_OUT);
8121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSourceMessage.recycle();
8122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSourceMessage = null;
8123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectedState);
8124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.START_WPS:
8126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.IN_PROGRESS);
8127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.CANCEL_WPS:
8129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.cancelWps()) {
8130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.CANCEL_WPS_SUCCEDED);
8131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
8132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiManager.CANCEL_WPS_FAILED, WifiManager.ERROR);
8133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mDisconnectedState);
8135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8136931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                /**
8137931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                 * Defer all commands that can cause connections to a different network
8138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * or put the state machine out of connect mode
8139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 */
8140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
8141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
8142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiManager.CONNECT_NETWORK:
8143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_ENABLE_NETWORK:
8144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_RECONNECT:
8145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_REASSOCIATE:
8146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
8147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8148e65cebc4284fd320a155a274cb647f73cecabd11Navtej Singh Mann                case CMD_AUTO_CONNECT:
8149b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                case CMD_AUTO_ROAM:
8150ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
8151ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    return HANDLED;
8152b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                case CMD_START_SCAN:
8153ebb7e0cb4572f73325a749539d589ebdefb8635cvandwalle                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
8154b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle                    return HANDLED;
8155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
8156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Network connection lost");
8157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleNetworkDisconnect();
8158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
8160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Ignore Assoc reject event during WPS Connection");
8161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
8163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Disregard auth failure events during WPS connection. The
8164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // EAP sequence is retried several times, and there might be
8165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // failures (especially for wps pin). We will get a WPS_XXX
8166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // event at the end of the sequence anyway.
8167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Ignore auth failure during WPS connection");
8168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
8170931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Throw away supplicant state changes when WPS is running.
8171931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // We will start getting supplicant state changes once we get
8172931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // a WPS success or failure
8173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
8176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
8178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
8182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiConfigStore.enableAllNetworks();
8183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiConfigStore.loadConfiguredNetworks();
8184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class SoftApStartingState extends State {
8188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
8190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            final Message message = getCurrentMessage();
8191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (message.what == CMD_START_AP) {
8192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                final WifiConfiguration config = (WifiConfiguration) message.obj;
8193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (config == null) {
8195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
8196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
8197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
8198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    startSoftApWithConfig(config);
8199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
8200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
8201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                throw new RuntimeException("Illegal transition to SoftApStartingState: " + message);
8202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
8206f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
8207f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
8208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
8209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
8210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
8211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
8212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
8213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
8214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
8215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
8216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
8217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
8218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
8219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
8220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_STATE_CHANGE:
8221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
8222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
8224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiConfiguration config = (WifiConfiguration) message.obj;
8225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (config != null) {
8226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        startSoftApWithConfig(config);
8227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
8228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Softap config is null!");
8229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(CMD_START_AP_FAILURE);
8230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP_SUCCESS:
8233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiApState(WIFI_AP_STATE_ENABLED);
8234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mSoftApStartedState);
8235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP_FAILURE:
8237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiApState(WIFI_AP_STATE_FAILED);
8238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInitialState);
8239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
8242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
8244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class SoftApStartedState extends State {
8248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
8250f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
8251f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
8252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
8253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
8254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Stopping Soft AP");
8255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* We have not tethered at this point, so we just shutdown soft Ap */
8256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
8257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mNwService.stopAccessPoint(mInterfaceName);
8258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch(Exception e) {
8259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Exception in stopAccessPoint()");
8260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiApState(WIFI_AP_STATE_DISABLED);
8262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInitialState);
8263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
8265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Ignore a start on a running access point
8266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8267931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle                    // Fail client mode operation when soft AP is enabled
8268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
8269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Cannot start supplicant with a running soft AP");
8270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiState(WIFI_STATE_UNKNOWN);
8271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_STATE_CHANGE:
8273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    TetherStateChange stateChange = (TetherStateChange) message.obj;
8274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (startTethering(stateChange.available)) {
8275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mTetheringState);
8276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
8280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
8282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class TetheringState extends State {
8286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
8288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Send ourselves a delayed message to shut down if tethering fails to notify */
8289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
8290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
8291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
8294f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
8295f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
8296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
8297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_STATE_CHANGE:
8298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    TetherStateChange stateChange = (TetherStateChange) message.obj;
8299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isWifiTethered(stateChange.active)) {
8300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mTetheredState);
8301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return HANDLED;
8303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
8304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == mTetherToken) {
8305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to get tether update, shutdown soft access point");
8306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mSoftApStartedState);
8307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Needs to be first thing handled
8308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessageAtFrontOfQueue(CMD_STOP_AP);
8309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
8312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
8313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
8314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
8315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
8316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
8317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
8318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
8319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
8320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
8321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
8322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
8323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
8326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
8328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class TetheredState extends State {
8332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
8334f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
8335f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
8336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
8337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_STATE_CHANGE:
8338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    TetherStateChange stateChange = (TetherStateChange) message.obj;
8339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!isWifiTethered(stateChange.active)) {
8340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Tethering reports wifi as untethered!, shut down soft Ap");
8341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setHostApRunning(null, false);
8342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setHostApRunning(null, true);
8343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return HANDLED;
8345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
8346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) log("Untethering before stopping AP");
8347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    setWifiApState(WIFI_AP_STATE_DISABLING);
8348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    stopTethering();
8349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUntetheringState);
8350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // More work to do after untethering
8351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
8352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
8355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
8357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UntetheringState extends State {
8361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
8363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* Send ourselves a delayed message to shut down if tethering fails to notify */
8364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
8365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
8366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
8369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
8370f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle            logStateAndMessage(message, getClass().getSimpleName());
8371f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
8372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(message.what) {
8373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_STATE_CHANGE:
8374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    TetherStateChange stateChange = (TetherStateChange) message.obj;
8375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Wait till wifi is untethered */
8377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isWifiTethered(stateChange.active)) break;
8378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mSoftApStartedState);
8380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
8382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == mTetherToken) {
8383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Failed to get tether update, force stop access point");
8384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mSoftApStartedState);
8385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
8386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_SUPPLICANT:
8388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_SUPPLICANT:
8389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_AP:
8390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_AP:
8391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_DRIVER:
8392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_DRIVER:
8393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_OPERATIONAL_MODE:
8394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_COUNTRY_CODE:
8395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_SET_FREQUENCY_BAND:
8396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_START_PACKET_FILTERING:
8397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case CMD_STOP_PACKET_FILTERING:
8398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
8399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
8400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
8401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
8402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
8403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
8404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
8405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
84070a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick    //State machine initiated requests can have replyTo set to null indicating
84080a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick    //there are no recepients, we ignore those reply actions
8409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what) {
8410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
84110a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick        Message dstMsg = obtainMessageWithArg2(msg);
84120a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick        dstMsg.what = what;
8413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
8414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what, int arg1) {
8417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
84180a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick        Message dstMsg = obtainMessageWithArg2(msg);
84190a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick        dstMsg.what = what;
8420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.arg1 = arg1;
8421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
8422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what, Object obj) {
8425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
84260a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick        Message dstMsg = obtainMessageWithArg2(msg);
84270a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick        dstMsg.what = what;
8428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.obj = obj;
8429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
8430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
8431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
8433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * arg2 on the source message has a unique id that needs to be retained in replies
8434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * to match the request
84350a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick
84360a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick     * see WifiManager for details
8437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
84380a0694d89195ac361a02bf73d5bf35b1e9050c6cChelsea Derrick    private Message obtainMessageWithArg2(Message srcMsg) {
8439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message msg = Message.obtain();
8440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.arg2 = srcMsg.arg2;
8441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return msg;
8442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
844333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
844433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    private static int parseHex(char ch) {
844533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if ('0' <= ch && ch <= '9') {
844633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            return ch - '0';
844733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        } else if ('a' <= ch && ch <= 'f') {
844833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            return ch - 'a' + 10;
844933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        } else if ('A' <= ch && ch <= 'F') {
845033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            return ch - 'A' + 10;
845133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        } else {
845233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            throw new NumberFormatException("" + ch + " is not a valid hex digit");
845333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
845433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
845533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
845633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    private byte[] parseHex(String hex) {
845733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        /* This only works for good input; don't throw bad data at it */
845833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (hex == null) {
845933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            return new byte[0];
846033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
846133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
846233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (hex.length() % 2 != 0) {
846333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            throw new NumberFormatException(hex + " is not a valid hex string");
846433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
846533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
8466dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        byte[] result = new byte[(hex.length())/2 + 1];
8467dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        result[0] = (byte) ((hex.length())/2);
8468dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        for (int i = 0, j = 1; i < hex.length(); i += 2, j++) {
846933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            int val = parseHex(hex.charAt(i)) * 16 + parseHex(hex.charAt(i+1));
847033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            byte b = (byte) (val & 0xFF);
847133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            result[j] = b;
847233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
847333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
847433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        return result;
847533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
847633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
847733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    private static String makeHex(byte[] bytes) {
847833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        StringBuilder sb = new StringBuilder();
847933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        for (byte b : bytes) {
848033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            sb.append(String.format("%02x", b));
848133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
848233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        return sb.toString();
848333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
848433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
8485dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande    private static String makeHex(byte[] bytes, int from, int len) {
8486dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        StringBuilder sb = new StringBuilder();
8487dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        for (int i = 0; i < len; i++) {
8488dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande            sb.append(String.format("%02x", bytes[from+i]));
8489dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        }
8490dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande        return sb.toString();
8491dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande    }
8492dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande
8493dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande
849433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    private static byte[] concat(byte[] array1, byte[] array2, byte[] array3) {
849533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
849633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        int len = array1.length + array2.length + array3.length;
849733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
849833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (array1.length != 0) {
849933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            len++;                      /* add another byte for size */
850033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
850133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
850233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (array2.length != 0) {
850333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            len++;                      /* add another byte for size */
850433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
850533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
850633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (array3.length != 0) {
850733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            len++;                      /* add another byte for size */
850833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
850933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
851033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        byte[] result = new byte[len];
851133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
851233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        int index = 0;
851333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (array1.length != 0) {
851433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            result[index] = (byte) (array1.length & 0xFF);
851533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            index++;
851633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            for (byte b : array1) {
851733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                result[index] = b;
851833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                index++;
851933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            }
852033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
852133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
852233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (array2.length != 0) {
852333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            result[index] = (byte) (array2.length & 0xFF);
852433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            index++;
852533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            for (byte b : array2) {
852633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                result[index] = b;
852733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                index++;
852833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            }
852933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
853033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
853133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (array3.length != 0) {
853233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            result[index] = (byte) (array3.length & 0xFF);
853333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            index++;
853433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            for (byte b : array3) {
853533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                result[index] = b;
853633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                index++;
853733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            }
853833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
853933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        return result;
854033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
854133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
8542dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande    void handleGsmAuthRequest(SimAuthRequestData requestData) {
854333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (targetWificonfiguration == null
854433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                || targetWificonfiguration.networkId == requestData.networkId) {
854533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            logd("id matches targetWifiConfiguration");
854633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        } else {
854733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            logd("id does not match targetWifiConfiguration");
854833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            return;
854933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
855033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
855133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        TelephonyManager tm = (TelephonyManager)
855233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande                mContext.getSystemService(Context.TELEPHONY_SERVICE);
855333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
855433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        if (tm != null) {
8555dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande            StringBuilder sb = new StringBuilder();
8556dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande            for (String challenge : requestData.challenges) {
855733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
8558dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                logd("RAND = " + challenge);
855933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
8560dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                byte[] rand = null;
8561dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                try {
8562dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    rand = parseHex(challenge);
8563dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                } catch (NumberFormatException e) {
8564dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    loge("malformed challenge");
8565dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    continue;
8566dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                }
8567dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande
8568dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                String base64Challenge = android.util.Base64.encodeToString(
8569dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                        rand, android.util.Base64.NO_WRAP);
8570dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                /*
8571dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                 * appType = 1 => SIM, 2 => USIM according to
8572dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                 * com.android.internal.telephony.PhoneConstants#APPTYPE_xxx
8573dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                 */
8574dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                int appType = 2;
8575dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                String tmResponse = tm.getIccSimChallengeResponse(appType, base64Challenge);
8576dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                logv("Raw Response - " + tmResponse);
8577dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande
8578dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                if (tmResponse != null && tmResponse.length() > 4) {
85798c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                    byte[] result = android.util.Base64.decode(tmResponse,
85808c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle                            android.util.Base64.DEFAULT);
8581dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    logv("Hex Response -" + makeHex(result));
8582dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    int sres_len = result[0];
8583dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    String sres = makeHex(result, 1, sres_len);
8584dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    int kc_offset = 1+sres_len;
8585dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    int kc_len = result[kc_offset];
8586dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    String kc = makeHex(result, 1+kc_offset, kc_len);
8587dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    sb.append(":" + kc + ":" + sres);
8588dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    logv("kc:" + kc + " sres:" + sres);
8589dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                } else {
8590dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                    loge("bad response - " + tmResponse);
8591dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande                }
859233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            }
859333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
8594dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande            String response = sb.toString();
8595dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande            logv("Supplicant Response -" + response);
8596dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande            mWifiNative.simAuthResponse(requestData.networkId, response);
859733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        } else {
859833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande            loge("could not get telephony manager");
859933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande        }
8600dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande    }
8601dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande
8602dbd6933aae99302b75683f8463cd17df554dc599Vinit Deshpande    void handle3GAuthRequest(SimAuthRequestData requestData) {
860333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
860433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
8605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
8606