1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 20 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; 21 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 22 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; 23 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; 24 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; 25 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; 26 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; 27 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; 28 import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; 29 30 import android.Manifest; 31 import android.app.ActivityManager; 32 import android.app.AlarmManager; 33 import android.app.PendingIntent; 34 import android.bluetooth.BluetoothAdapter; 35 import android.content.BroadcastReceiver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.pm.ApplicationInfo; 40 import android.content.pm.IPackageManager; 41 import android.content.pm.PackageManager; 42 import android.database.ContentObserver; 43 import android.net.ConnectivityManager; 44 import android.net.DhcpResults; 45 import android.net.LinkProperties; 46 import android.net.Network; 47 import android.net.NetworkAgent; 48 import android.net.NetworkCapabilities; 49 import android.net.NetworkFactory; 50 import android.net.NetworkInfo; 51 import android.net.NetworkInfo.DetailedState; 52 import android.net.NetworkMisc; 53 import android.net.NetworkRequest; 54 import android.net.NetworkUtils; 55 import android.net.RouteInfo; 56 import android.net.StaticIpConfiguration; 57 import android.net.dhcp.DhcpClient; 58 import android.net.ip.IpManager; 59 import android.net.wifi.PasspointManagementObjectDefinition; 60 import android.net.wifi.RssiPacketCountInfo; 61 import android.net.wifi.ScanResult; 62 import android.net.wifi.ScanSettings; 63 import android.net.wifi.SupplicantState; 64 import android.net.wifi.WifiChannel; 65 import android.net.wifi.WifiConfiguration; 66 import android.net.wifi.WifiConnectionStatistics; 67 import android.net.wifi.WifiEnterpriseConfig; 68 import android.net.wifi.WifiInfo; 69 import android.net.wifi.WifiLinkLayerStats; 70 import android.net.wifi.WifiManager; 71 import android.net.wifi.WifiScanner; 72 import android.net.wifi.WifiSsid; 73 import android.net.wifi.WpsInfo; 74 import android.net.wifi.WpsResult; 75 import android.net.wifi.WpsResult.Status; 76 import android.net.wifi.p2p.IWifiP2pManager; 77 import android.os.BatteryStats; 78 import android.os.Binder; 79 import android.os.Bundle; 80 import android.os.IBinder; 81 import android.os.INetworkManagementService; 82 import android.os.Looper; 83 import android.os.Message; 84 import android.os.Messenger; 85 import android.os.PowerManager; 86 import android.os.Process; 87 import android.os.RemoteException; 88 import android.os.SystemClock; 89 import android.os.UserHandle; 90 import android.os.UserManager; 91 import android.os.WorkSource; 92 import android.provider.Settings; 93 import android.telephony.TelephonyManager; 94 import android.text.TextUtils; 95 import android.util.Log; 96 import android.util.SparseArray; 97 98 import com.android.internal.R; 99 import com.android.internal.annotations.VisibleForTesting; 100 import com.android.internal.app.IBatteryStats; 101 import com.android.internal.util.AsyncChannel; 102 import com.android.internal.util.MessageUtils; 103 import com.android.internal.util.Protocol; 104 import com.android.internal.util.State; 105 import com.android.internal.util.StateMachine; 106 import com.android.server.connectivity.KeepalivePacketData; 107 import com.android.server.wifi.hotspot2.IconEvent; 108 import com.android.server.wifi.hotspot2.NetworkDetail; 109 import com.android.server.wifi.hotspot2.Utils; 110 import com.android.server.wifi.p2p.WifiP2pServiceImpl; 111 import com.android.server.wifi.util.TelephonyUtil; 112 113 import java.io.BufferedReader; 114 import java.io.FileDescriptor; 115 import java.io.FileNotFoundException; 116 import java.io.FileReader; 117 import java.io.IOException; 118 import java.io.PrintWriter; 119 import java.net.Inet4Address; 120 import java.net.InetAddress; 121 import java.util.ArrayList; 122 import java.util.Arrays; 123 import java.util.Calendar; 124 import java.util.HashSet; 125 import java.util.LinkedList; 126 import java.util.List; 127 import java.util.Queue; 128 import java.util.Random; 129 import java.util.Set; 130 import java.util.concurrent.atomic.AtomicBoolean; 131 import java.util.concurrent.atomic.AtomicInteger; 132 133 /** 134 * TODO: 135 * Deprecate WIFI_STATE_UNKNOWN 136 */ 137 138 /** 139 * Track the state of Wifi connectivity. All event handling is done here, 140 * and all changes in connectivity state are initiated here. 141 * 142 * Wi-Fi now supports three modes of operation: Client, SoftAp and p2p 143 * In the current implementation, we support concurrent wifi p2p and wifi operation. 144 * The WifiStateMachine handles SoftAp and Client operations while WifiP2pService 145 * handles p2p operation. 146 * 147 * @hide 148 */ 149 public class WifiStateMachine extends StateMachine implements WifiNative.WifiRssiEventHandler { 150 151 private static final String NETWORKTYPE = "WIFI"; 152 private static final String NETWORKTYPE_UNTRUSTED = "WIFI_UT"; 153 @VisibleForTesting public static final short NUM_LOG_RECS_NORMAL = 100; 154 @VisibleForTesting public static final short NUM_LOG_RECS_VERBOSE_LOW_MEMORY = 200; 155 @VisibleForTesting public static final short NUM_LOG_RECS_VERBOSE = 3000; 156 private static boolean DBG = false; 157 private static boolean USE_PAUSE_SCANS = false; 158 private static final String TAG = "WifiStateMachine"; 159 160 private static final int ONE_HOUR_MILLI = 1000 * 60 * 60; 161 162 private static final String GOOGLE_OUI = "DA-A1-19"; 163 164 private int mVerboseLoggingLevel = 0; 165 /* debug flag, indicating if handling of ASSOCIATION_REJECT ended up blacklisting 166 * the corresponding BSSID. 167 */ 168 private boolean didBlackListBSSID = false; 169 170 /** 171 * Log with error attribute 172 * 173 * @param s is string log 174 */ 175 protected void loge(String s) { 176 Log.e(getName(), s); 177 } 178 protected void logd(String s) { 179 Log.d(getName(), s); 180 } 181 protected void log(String s) {; 182 Log.d(getName(), s); 183 } 184 private WifiLastResortWatchdog mWifiLastResortWatchdog; 185 private WifiMetrics mWifiMetrics; 186 private WifiInjector mWifiInjector; 187 private WifiMonitor mWifiMonitor; 188 private WifiNative mWifiNative; 189 private WifiConfigManager mWifiConfigManager; 190 private WifiConnectivityManager mWifiConnectivityManager; 191 private WifiQualifiedNetworkSelector mWifiQualifiedNetworkSelector; 192 private INetworkManagementService mNwService; 193 private ConnectivityManager mCm; 194 private BaseWifiLogger mWifiLogger; 195 private WifiApConfigStore mWifiApConfigStore; 196 private final boolean mP2pSupported; 197 private final AtomicBoolean mP2pConnected = new AtomicBoolean(false); 198 private boolean mTemporarilyDisconnectWifi = false; 199 private final String mPrimaryDeviceType; 200 private final Clock mClock; 201 private final PropertyService mPropertyService; 202 private final BuildProperties mBuildProperties; 203 private final WifiCountryCode mCountryCode; 204 205 /* Scan results handling */ 206 private List<ScanDetail> mScanResults = new ArrayList<>(); 207 private final Object mScanResultsLock = new Object(); 208 209 // For debug, number of known scan results that were found as part of last scan result event, 210 // as well the number of scans results returned by the supplicant with that message 211 private int mNumScanResultsKnown; 212 private int mNumScanResultsReturned; 213 214 private boolean mScreenOn = false; 215 216 /* Chipset supports background scan */ 217 private final boolean mBackgroundScanSupported; 218 219 private final String mInterfaceName; 220 /* Tethering interface could be separate from wlan interface */ 221 private String mTetherInterfaceName; 222 223 private int mLastSignalLevel = -1; 224 private String mLastBssid; 225 private int mLastNetworkId; // The network Id we successfully joined 226 private boolean linkDebouncing = false; 227 228 @Override 229 public void onRssiThresholdBreached(byte curRssi) { 230 if (DBG) { 231 Log.e(TAG, "onRssiThresholdBreach event. Cur Rssi = " + curRssi); 232 } 233 sendMessage(CMD_RSSI_THRESHOLD_BREACH, curRssi); 234 } 235 236 public void processRssiThreshold(byte curRssi, int reason) { 237 if (curRssi == Byte.MAX_VALUE || curRssi == Byte.MIN_VALUE) { 238 Log.wtf(TAG, "processRssiThreshold: Invalid rssi " + curRssi); 239 return; 240 } 241 for (int i = 0; i < mRssiRanges.length; i++) { 242 if (curRssi < mRssiRanges[i]) { 243 // Assume sorted values(ascending order) for rssi, 244 // bounded by high(127) and low(-128) at extremeties 245 byte maxRssi = mRssiRanges[i]; 246 byte minRssi = mRssiRanges[i-1]; 247 // This value of hw has to be believed as this value is averaged and has breached 248 // the rssi thresholds and raised event to host. This would be eggregious if this 249 // value is invalid 250 mWifiInfo.setRssi((int) curRssi); 251 updateCapabilities(getCurrentWifiConfiguration()); 252 int ret = startRssiMonitoringOffload(maxRssi, minRssi); 253 Log.d(TAG, "Re-program RSSI thresholds for " + smToString(reason) + 254 ": [" + minRssi + ", " + maxRssi + "], curRssi=" + curRssi + " ret=" + ret); 255 break; 256 } 257 } 258 } 259 260 // Testing various network disconnect cases by sending lots of spurious 261 // disconnect to supplicant 262 private boolean testNetworkDisconnect = false; 263 264 private boolean mEnableRssiPolling = false; 265 private int mRssiPollToken = 0; 266 /* 3 operational states for STA operation: CONNECT_MODE, SCAN_ONLY_MODE, SCAN_ONLY_WIFI_OFF_MODE 267 * In CONNECT_MODE, the STA can scan and connect to an access point 268 * In SCAN_ONLY_MODE, the STA can only scan for access points 269 * In SCAN_ONLY_WIFI_OFF_MODE, the STA can only scan for access points with wifi toggle being off 270 */ 271 private int mOperationalMode = CONNECT_MODE; 272 private boolean mIsScanOngoing = false; 273 private boolean mIsFullScanOngoing = false; 274 private boolean mSendScanResultsBroadcast = false; 275 276 private final Queue<Message> mBufferedScanMsg = new LinkedList<Message>(); 277 private WorkSource mScanWorkSource = null; 278 private static final int UNKNOWN_SCAN_SOURCE = -1; 279 private static final int ADD_OR_UPDATE_SOURCE = -3; 280 private static final int SET_ALLOW_UNTRUSTED_SOURCE = -4; 281 private static final int ENABLE_WIFI = -5; 282 public static final int DFS_RESTRICTED_SCAN_REQUEST = -6; 283 284 private static final int SCAN_REQUEST_BUFFER_MAX_SIZE = 10; 285 private static final String CUSTOMIZED_SCAN_SETTING = "customized_scan_settings"; 286 private static final String CUSTOMIZED_SCAN_WORKSOURCE = "customized_scan_worksource"; 287 private static final String SCAN_REQUEST_TIME = "scan_request_time"; 288 289 /* Tracks if state machine has received any screen state change broadcast yet. 290 * We can miss one of these at boot. 291 */ 292 private AtomicBoolean mScreenBroadcastReceived = new AtomicBoolean(false); 293 294 private boolean mBluetoothConnectionActive = false; 295 296 private PowerManager.WakeLock mSuspendWakeLock; 297 298 /** 299 * Interval in milliseconds between polling for RSSI 300 * and linkspeed information 301 */ 302 private static final int POLL_RSSI_INTERVAL_MSECS = 3000; 303 304 /** 305 * Interval in milliseconds between receiving a disconnect event 306 * while connected to a good AP, and handling the disconnect proper 307 */ 308 private static final int LINK_FLAPPING_DEBOUNCE_MSEC = 4000; 309 310 /** 311 * Delay between supplicant restarts upon failure to establish connection 312 */ 313 private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000; 314 315 /** 316 * Number of times we attempt to restart supplicant 317 */ 318 private static final int SUPPLICANT_RESTART_TRIES = 5; 319 320 private int mSupplicantRestartCount = 0; 321 /* Tracks sequence number on stop failure message */ 322 private int mSupplicantStopFailureToken = 0; 323 324 /** 325 * Tether state change notification time out 326 */ 327 private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000; 328 329 /* Tracks sequence number on a tether notification time out */ 330 private int mTetherToken = 0; 331 332 /** 333 * Driver start time out. 334 */ 335 private static final int DRIVER_START_TIME_OUT_MSECS = 10000; 336 337 /* Tracks sequence number on a driver time out */ 338 private int mDriverStartToken = 0; 339 340 /** 341 * Don't select new network when previous network selection is 342 * pending connection for this much time 343 */ 344 private static final int CONNECT_TIMEOUT_MSEC = 3000; 345 346 /** 347 * The link properties of the wifi interface. 348 * Do not modify this directly; use updateLinkProperties instead. 349 */ 350 private LinkProperties mLinkProperties; 351 352 /* Tracks sequence number on a periodic scan message */ 353 private int mPeriodicScanToken = 0; 354 355 // Wakelock held during wifi start/stop and driver load/unload 356 private PowerManager.WakeLock mWakeLock; 357 358 private Context mContext; 359 360 private final Object mDhcpResultsLock = new Object(); 361 private DhcpResults mDhcpResults; 362 363 // NOTE: Do not return to clients - use #getWiFiInfoForUid(int) 364 private final WifiInfo mWifiInfo; 365 private NetworkInfo mNetworkInfo; 366 private final NetworkCapabilities mDfltNetworkCapabilities; 367 private SupplicantStateTracker mSupplicantStateTracker; 368 369 private int mWifiLinkLayerStatsSupported = 4; // Temporary disable 370 371 // Whether the state machine goes thru the Disconnecting->Disconnected->ObtainingIpAddress 372 private boolean mAutoRoaming = false; 373 374 // Roaming failure count 375 private int mRoamFailCount = 0; 376 377 // This is the BSSID we are trying to associate to, it can be set to "any" 378 // if we havent selected a BSSID for joining. 379 // if we havent selected a BSSID for joining. 380 // The BSSID we are associated to is found in mWifiInfo 381 private String mTargetRoamBSSID = "any"; 382 //This one is used to track whta is the current target network ID. This is used for error 383 // handling during connection setup since many error message from supplicant does not report 384 // SSID Once connected, it will be set to invalid 385 private int mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID; 386 387 private long mLastDriverRoamAttempt = 0; 388 389 private WifiConfiguration targetWificonfiguration = null; 390 391 // Used as debug to indicate which configuration last was saved 392 private WifiConfiguration lastSavedConfigurationAttempt = null; 393 394 // Used as debug to indicate which configuration last was removed 395 private WifiConfiguration lastForgetConfigurationAttempt = null; 396 397 //Random used by softAP channel Selection 398 private static Random mRandom = new Random(Calendar.getInstance().getTimeInMillis()); 399 400 boolean isRoaming() { 401 return mAutoRoaming; 402 } 403 404 public void autoRoamSetBSSID(int netId, String bssid) { 405 autoRoamSetBSSID(mWifiConfigManager.getWifiConfiguration(netId), bssid); 406 } 407 408 public boolean autoRoamSetBSSID(WifiConfiguration config, String bssid) { 409 boolean ret = true; 410 if (mTargetRoamBSSID == null) mTargetRoamBSSID = "any"; 411 if (bssid == null) bssid = "any"; 412 if (config == null) return false; // Nothing to do 413 414 if (mTargetRoamBSSID != null 415 && bssid.equals(mTargetRoamBSSID) && bssid.equals(config.BSSID)) { 416 return false; // We didnt change anything 417 } 418 if (!mTargetRoamBSSID.equals("any") && bssid.equals("any")) { 419 // Changing to ANY 420 if (!mWifiConfigManager.ROAM_ON_ANY) { 421 ret = false; // Nothing to do 422 } 423 } 424 if (config.BSSID != null) { 425 bssid = config.BSSID; 426 if (DBG) { 427 Log.d(TAG, "force BSSID to " + bssid + "due to config"); 428 } 429 } 430 431 if (DBG) { 432 logd("autoRoamSetBSSID " + bssid + " key=" + config.configKey()); 433 } 434 mTargetRoamBSSID = bssid; 435 mWifiConfigManager.saveWifiConfigBSSID(config, bssid); 436 return ret; 437 } 438 439 /** 440 * set Config's default BSSID (for association purpose) 441 * @param config config need set BSSID 442 * @param bssid default BSSID to assocaite with when connect to this network 443 * @return false -- does not change the current default BSSID of the configure 444 * true -- change the current default BSSID of the configur 445 */ 446 private boolean setTargetBssid(WifiConfiguration config, String bssid) { 447 if (config == null) { 448 return false; 449 } 450 451 if (config.BSSID != null) { 452 bssid = config.BSSID; 453 if (DBG) { 454 Log.d(TAG, "force BSSID to " + bssid + "due to config"); 455 } 456 } 457 458 if (bssid == null) { 459 bssid = "any"; 460 } 461 462 String networkSelectionBSSID = config.getNetworkSelectionStatus() 463 .getNetworkSelectionBSSID(); 464 if (networkSelectionBSSID != null && networkSelectionBSSID.equals(bssid)) { 465 if (DBG) { 466 Log.d(TAG, "Current preferred BSSID is the same as the target one"); 467 } 468 return false; 469 } 470 471 if (DBG) { 472 Log.d(TAG, "target set to " + config.SSID + ":" + bssid); 473 } 474 mTargetRoamBSSID = bssid; 475 mWifiConfigManager.saveWifiConfigBSSID(config, bssid); 476 return true; 477 } 478 /** 479 * Save the UID correctly depending on if this is a new or existing network. 480 * @return true if operation is authorized, false otherwise 481 */ 482 boolean recordUidIfAuthorized(WifiConfiguration config, int uid, boolean onlyAnnotate) { 483 if (!mWifiConfigManager.isNetworkConfigured(config)) { 484 config.creatorUid = uid; 485 config.creatorName = mContext.getPackageManager().getNameForUid(uid); 486 } else if (!mWifiConfigManager.canModifyNetwork(uid, config, onlyAnnotate)) { 487 return false; 488 } 489 490 config.lastUpdateUid = uid; 491 config.lastUpdateName = mContext.getPackageManager().getNameForUid(uid); 492 493 return true; 494 495 } 496 497 /** 498 * Checks to see if user has specified if the apps configuration is connectable. 499 * If the user hasn't specified we query the user and return true. 500 * 501 * @param message The message to be deferred 502 * @param netId Network id of the configuration to check against 503 * @param allowOverride If true we won't defer to the user if the uid of the message holds the 504 * CONFIG_OVERRIDE_PERMISSION 505 * @return True if we are waiting for user feedback or netId is invalid. False otherwise. 506 */ 507 boolean deferForUserInput(Message message, int netId, boolean allowOverride){ 508 final WifiConfiguration config = mWifiConfigManager.getWifiConfiguration(netId); 509 510 // We can only evaluate saved configurations. 511 if (config == null) { 512 logd("deferForUserInput: configuration for netId=" + netId + " not stored"); 513 return true; 514 } 515 516 switch (config.userApproved) { 517 case WifiConfiguration.USER_APPROVED: 518 case WifiConfiguration.USER_BANNED: 519 return false; 520 case WifiConfiguration.USER_PENDING: 521 default: // USER_UNSPECIFIED 522 /* the intention was to ask user here; but a dialog box is * 523 * too invasive; so we are going to allow connection for now */ 524 config.userApproved = WifiConfiguration.USER_APPROVED; 525 return false; 526 } 527 } 528 529 private final IpManager mIpManager; 530 531 private AlarmManager mAlarmManager; 532 private PendingIntent mScanIntent; 533 534 /* Tracks current frequency mode */ 535 private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO); 536 537 // Channel for sending replies. 538 private AsyncChannel mReplyChannel = new AsyncChannel(); 539 540 private WifiP2pServiceImpl mWifiP2pServiceImpl; 541 542 // Used to initiate a connection with WifiP2pService 543 private AsyncChannel mWifiP2pChannel; 544 545 private WifiScanner mWifiScanner; 546 547 private int mConnectionRequests = 0; 548 private WifiNetworkFactory mNetworkFactory; 549 private UntrustedWifiNetworkFactory mUntrustedNetworkFactory; 550 private WifiNetworkAgent mNetworkAgent; 551 552 private String[] mWhiteListedSsids = null; 553 554 private byte[] mRssiRanges; 555 556 // Keep track of various statistics, for retrieval by System Apps, i.e. under @SystemApi 557 // We should really persist that into the networkHistory.txt file, and read it back when 558 // WifiStateMachine starts up 559 private WifiConnectionStatistics mWifiConnectionStatistics = new WifiConnectionStatistics(); 560 561 // Used to filter out requests we couldn't possibly satisfy. 562 private final NetworkCapabilities mNetworkCapabilitiesFilter = new NetworkCapabilities(); 563 564 // Provide packet filter capabilities to ConnectivityService. 565 private final NetworkMisc mNetworkMisc = new NetworkMisc(); 566 567 /* The base for wifi message types */ 568 static final int BASE = Protocol.BASE_WIFI; 569 /* Start the supplicant */ 570 static final int CMD_START_SUPPLICANT = BASE + 11; 571 /* Stop the supplicant */ 572 static final int CMD_STOP_SUPPLICANT = BASE + 12; 573 /* Start the driver */ 574 static final int CMD_START_DRIVER = BASE + 13; 575 /* Stop the driver */ 576 static final int CMD_STOP_DRIVER = BASE + 14; 577 /* Indicates Static IP succeeded */ 578 static final int CMD_STATIC_IP_SUCCESS = BASE + 15; 579 /* Indicates Static IP failed */ 580 static final int CMD_STATIC_IP_FAILURE = BASE + 16; 581 /* Indicates supplicant stop failed */ 582 static final int CMD_STOP_SUPPLICANT_FAILED = BASE + 17; 583 /* A delayed message sent to start driver when it fail to come up */ 584 static final int CMD_DRIVER_START_TIMED_OUT = BASE + 19; 585 586 /* Start the soft access point */ 587 static final int CMD_START_AP = BASE + 21; 588 /* Indicates soft ap start failed */ 589 static final int CMD_START_AP_FAILURE = BASE + 22; 590 /* Stop the soft access point */ 591 static final int CMD_STOP_AP = BASE + 23; 592 /* Soft access point teardown is completed. */ 593 static final int CMD_AP_STOPPED = BASE + 24; 594 595 static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 31; 596 597 /* Supplicant commands */ 598 /* Is supplicant alive ? */ 599 static final int CMD_PING_SUPPLICANT = BASE + 51; 600 /* Add/update a network configuration */ 601 static final int CMD_ADD_OR_UPDATE_NETWORK = BASE + 52; 602 /* Delete a network */ 603 static final int CMD_REMOVE_NETWORK = BASE + 53; 604 /* Enable a network. The device will attempt a connection to the given network. */ 605 static final int CMD_ENABLE_NETWORK = BASE + 54; 606 /* Enable all networks */ 607 static final int CMD_ENABLE_ALL_NETWORKS = BASE + 55; 608 /* Blacklist network. De-prioritizes the given BSSID for connection. */ 609 static final int CMD_BLACKLIST_NETWORK = BASE + 56; 610 /* Clear the blacklist network list */ 611 static final int CMD_CLEAR_BLACKLIST = BASE + 57; 612 /* Save configuration */ 613 static final int CMD_SAVE_CONFIG = BASE + 58; 614 /* Get configured networks */ 615 static final int CMD_GET_CONFIGURED_NETWORKS = BASE + 59; 616 /* Get available frequencies */ 617 static final int CMD_GET_CAPABILITY_FREQ = BASE + 60; 618 /* Get adaptors */ 619 static final int CMD_GET_SUPPORTED_FEATURES = BASE + 61; 620 /* Get configured networks with real preSharedKey */ 621 static final int CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS = BASE + 62; 622 /* Get Link Layer Stats thru HAL */ 623 static final int CMD_GET_LINK_LAYER_STATS = BASE + 63; 624 /* Supplicant commands after driver start*/ 625 /* Initiate a scan */ 626 static final int CMD_START_SCAN = BASE + 71; 627 /* Set operational mode. CONNECT, SCAN ONLY, SCAN_ONLY with Wi-Fi off mode */ 628 static final int CMD_SET_OPERATIONAL_MODE = BASE + 72; 629 /* Disconnect from a network */ 630 static final int CMD_DISCONNECT = BASE + 73; 631 /* Reconnect to a network */ 632 static final int CMD_RECONNECT = BASE + 74; 633 /* Reassociate to a network */ 634 static final int CMD_REASSOCIATE = BASE + 75; 635 /* Get Connection Statistis */ 636 static final int CMD_GET_CONNECTION_STATISTICS = BASE + 76; 637 638 /* Controls suspend mode optimizations 639 * 640 * When high perf mode is enabled, suspend mode optimizations are disabled 641 * 642 * When high perf mode is disabled, suspend mode optimizations are enabled 643 * 644 * Suspend mode optimizations include: 645 * - packet filtering 646 * - turn off roaming 647 * - DTIM wake up settings 648 */ 649 static final int CMD_SET_HIGH_PERF_MODE = BASE + 77; 650 /* Enables RSSI poll */ 651 static final int CMD_ENABLE_RSSI_POLL = BASE + 82; 652 /* RSSI poll */ 653 static final int CMD_RSSI_POLL = BASE + 83; 654 /* Enable suspend mode optimizations in the driver */ 655 static final int CMD_SET_SUSPEND_OPT_ENABLED = BASE + 86; 656 /* Delayed NETWORK_DISCONNECT */ 657 static final int CMD_DELAYED_NETWORK_DISCONNECT = BASE + 87; 658 /* When there are no saved networks, we do a periodic scan to notify user of 659 * an open network */ 660 static final int CMD_NO_NETWORKS_PERIODIC_SCAN = BASE + 88; 661 /* Test network Disconnection NETWORK_DISCONNECT */ 662 static final int CMD_TEST_NETWORK_DISCONNECT = BASE + 89; 663 664 private int testNetworkDisconnectCounter = 0; 665 666 /* Set the frequency band */ 667 static final int CMD_SET_FREQUENCY_BAND = BASE + 90; 668 /* Enable TDLS on a specific MAC address */ 669 static final int CMD_ENABLE_TDLS = BASE + 92; 670 /* DHCP/IP configuration watchdog */ 671 static final int CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER = BASE + 93; 672 673 /** 674 * Watchdog for protecting against b/16823537 675 * Leave time for 4-way handshake to succeed 676 */ 677 static final int ROAM_GUARD_TIMER_MSEC = 15000; 678 679 int roamWatchdogCount = 0; 680 /* Roam state watchdog */ 681 static final int CMD_ROAM_WATCHDOG_TIMER = BASE + 94; 682 /* Screen change intent handling */ 683 static final int CMD_SCREEN_STATE_CHANGED = BASE + 95; 684 685 /* Disconnecting state watchdog */ 686 static final int CMD_DISCONNECTING_WATCHDOG_TIMER = BASE + 96; 687 688 /* Remove a packages associated configrations */ 689 static final int CMD_REMOVE_APP_CONFIGURATIONS = BASE + 97; 690 691 /* Disable an ephemeral network */ 692 static final int CMD_DISABLE_EPHEMERAL_NETWORK = BASE + 98; 693 694 /* Get matching network */ 695 static final int CMD_GET_MATCHING_CONFIG = BASE + 99; 696 697 /* alert from firmware */ 698 static final int CMD_FIRMWARE_ALERT = BASE + 100; 699 700 /* SIM is removed; reset any cached data for it */ 701 static final int CMD_RESET_SIM_NETWORKS = BASE + 101; 702 703 /* OSU APIs */ 704 static final int CMD_ADD_PASSPOINT_MO = BASE + 102; 705 static final int CMD_MODIFY_PASSPOINT_MO = BASE + 103; 706 static final int CMD_QUERY_OSU_ICON = BASE + 104; 707 708 /* try to match a provider with current network */ 709 static final int CMD_MATCH_PROVIDER_NETWORK = BASE + 105; 710 711 /** 712 * Make this timer 40 seconds, which is about the normal DHCP timeout. 713 * In no valid case, the WiFiStateMachine should remain stuck in ObtainingIpAddress 714 * for more than 30 seconds. 715 */ 716 static final int OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC = 40000; 717 718 int obtainingIpWatchdogCount = 0; 719 720 /* Commands from/to the SupplicantStateTracker */ 721 /* Reset the supplicant state tracker */ 722 static final int CMD_RESET_SUPPLICANT_STATE = BASE + 111; 723 724 int disconnectingWatchdogCount = 0; 725 static final int DISCONNECTING_GUARD_TIMER_MSEC = 5000; 726 727 /* P2p commands */ 728 /* We are ok with no response here since we wont do much with it anyway */ 729 public static final int CMD_ENABLE_P2P = BASE + 131; 730 /* In order to shut down supplicant cleanly, we wait till p2p has 731 * been disabled */ 732 public static final int CMD_DISABLE_P2P_REQ = BASE + 132; 733 public static final int CMD_DISABLE_P2P_RSP = BASE + 133; 734 735 public static final int CMD_BOOT_COMPLETED = BASE + 134; 736 737 /* We now have a valid IP configuration. */ 738 static final int CMD_IP_CONFIGURATION_SUCCESSFUL = BASE + 138; 739 /* We no longer have a valid IP configuration. */ 740 static final int CMD_IP_CONFIGURATION_LOST = BASE + 139; 741 /* Link configuration (IP address, DNS, ...) changes notified via netlink */ 742 static final int CMD_UPDATE_LINKPROPERTIES = BASE + 140; 743 744 /* Supplicant is trying to associate to a given BSSID */ 745 static final int CMD_TARGET_BSSID = BASE + 141; 746 747 /* Reload all networks and reconnect */ 748 static final int CMD_RELOAD_TLS_AND_RECONNECT = BASE + 142; 749 750 static final int CMD_AUTO_CONNECT = BASE + 143; 751 752 private static final int NETWORK_STATUS_UNWANTED_DISCONNECT = 0; 753 private static final int NETWORK_STATUS_UNWANTED_VALIDATION_FAILED = 1; 754 private static final int NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN = 2; 755 756 static final int CMD_UNWANTED_NETWORK = BASE + 144; 757 758 static final int CMD_AUTO_ROAM = BASE + 145; 759 760 static final int CMD_AUTO_SAVE_NETWORK = BASE + 146; 761 762 static final int CMD_ASSOCIATED_BSSID = BASE + 147; 763 764 static final int CMD_NETWORK_STATUS = BASE + 148; 765 766 /* A layer 3 neighbor on the Wi-Fi link became unreachable. */ 767 static final int CMD_IP_REACHABILITY_LOST = BASE + 149; 768 769 /* Remove a packages associated configrations */ 770 static final int CMD_REMOVE_USER_CONFIGURATIONS = BASE + 152; 771 772 static final int CMD_ACCEPT_UNVALIDATED = BASE + 153; 773 774 /* used to log if PNO was started */ 775 static final int CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION = BASE + 158; 776 777 /* used to offload sending IP packet */ 778 static final int CMD_START_IP_PACKET_OFFLOAD = BASE + 160; 779 780 /* used to stop offload sending IP packet */ 781 static final int CMD_STOP_IP_PACKET_OFFLOAD = BASE + 161; 782 783 /* used to start rssi monitoring in hw */ 784 static final int CMD_START_RSSI_MONITORING_OFFLOAD = BASE + 162; 785 786 /* used to stop rssi moniroting in hw */ 787 static final int CMD_STOP_RSSI_MONITORING_OFFLOAD = BASE + 163; 788 789 /* used to indicated RSSI threshold breach in hw */ 790 static final int CMD_RSSI_THRESHOLD_BREACH = BASE + 164; 791 792 /* used to indicate that the foreground user was switched */ 793 static final int CMD_USER_SWITCH = BASE + 165; 794 795 /* Enable/Disable WifiConnectivityManager */ 796 static final int CMD_ENABLE_WIFI_CONNECTIVITY_MANAGER = BASE + 166; 797 798 /* Enable/Disable AutoJoin when associated */ 799 static final int CMD_ENABLE_AUTOJOIN_WHEN_ASSOCIATED = BASE + 167; 800 801 /** 802 * Used to handle messages bounced between WifiStateMachine and IpManager. 803 */ 804 static final int CMD_IPV4_PROVISIONING_SUCCESS = BASE + 200; 805 static final int CMD_IPV4_PROVISIONING_FAILURE = BASE + 201; 806 807 /* Push a new APF program to the HAL */ 808 static final int CMD_INSTALL_PACKET_FILTER = BASE + 202; 809 810 /* Enable/disable fallback packet filtering */ 811 static final int CMD_SET_FALLBACK_PACKET_FILTERING = BASE + 203; 812 813 /* Enable/disable Neighbor Discovery offload functionality. */ 814 static final int CMD_CONFIG_ND_OFFLOAD = BASE + 204; 815 816 // For message logging. 817 private static final Class[] sMessageClasses = { 818 AsyncChannel.class, WifiStateMachine.class, DhcpClient.class }; 819 private static final SparseArray<String> sSmToString = 820 MessageUtils.findMessageNames(sMessageClasses); 821 822 823 /* Wifi state machine modes of operation */ 824 /* CONNECT_MODE - connect to any 'known' AP when it becomes available */ 825 public static final int CONNECT_MODE = 1; 826 /* SCAN_ONLY_MODE - don't connect to any APs; scan, but only while apps hold lock */ 827 public static final int SCAN_ONLY_MODE = 2; 828 /* SCAN_ONLY_WITH_WIFI_OFF - scan, but don't connect to any APs */ 829 public static final int SCAN_ONLY_WITH_WIFI_OFF_MODE = 3; 830 831 private static final int SUCCESS = 1; 832 private static final int FAILURE = -1; 833 834 /* Tracks if suspend optimizations need to be disabled by DHCP, 835 * screen or due to high perf mode. 836 * When any of them needs to disable it, we keep the suspend optimizations 837 * disabled 838 */ 839 private int mSuspendOptNeedsDisabled = 0; 840 841 private static final int SUSPEND_DUE_TO_DHCP = 1; 842 private static final int SUSPEND_DUE_TO_HIGH_PERF = 1 << 1; 843 private static final int SUSPEND_DUE_TO_SCREEN = 1 << 2; 844 845 /* Tracks if user has enabled suspend optimizations through settings */ 846 private AtomicBoolean mUserWantsSuspendOpt = new AtomicBoolean(true); 847 848 /** 849 * Default framework scan interval in milliseconds. This is used in the scenario in which 850 * wifi chipset does not support background scanning to set up a 851 * periodic wake up scan so that the device can connect to a new access 852 * point on the move. {@link Settings.Global#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can 853 * override this. 854 */ 855 private final int mDefaultFrameworkScanIntervalMs; 856 857 858 /** 859 * Scan period for the NO_NETWORKS_PERIIDOC_SCAN_FEATURE 860 */ 861 private final int mNoNetworksPeriodicScan; 862 863 /** 864 * Supplicant scan interval in milliseconds. 865 * Comes from {@link Settings.Global#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} or 866 * from the default config if the setting is not set 867 */ 868 private long mSupplicantScanIntervalMs; 869 870 /** 871 * Minimum time interval between enabling all networks. 872 * A device can end up repeatedly connecting to a bad network on screen on/off toggle 873 * due to enabling every time. We add a threshold to avoid this. 874 */ 875 private static final int MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS = 10 * 60 * 1000; /* 10 minutes */ 876 private long mLastEnableAllNetworksTime; 877 878 int mRunningBeaconCount = 0; 879 880 /* Default parent state */ 881 private State mDefaultState = new DefaultState(); 882 /* Temporary initial state */ 883 private State mInitialState = new InitialState(); 884 /* Driver loaded, waiting for supplicant to start */ 885 private State mSupplicantStartingState = new SupplicantStartingState(); 886 /* Driver loaded and supplicant ready */ 887 private State mSupplicantStartedState = new SupplicantStartedState(); 888 /* Waiting for supplicant to stop and monitor to exit */ 889 private State mSupplicantStoppingState = new SupplicantStoppingState(); 890 /* Driver start issued, waiting for completed event */ 891 private State mDriverStartingState = new DriverStartingState(); 892 /* Driver started */ 893 private State mDriverStartedState = new DriverStartedState(); 894 /* Wait until p2p is disabled 895 * This is a special state which is entered right after we exit out of DriverStartedState 896 * before transitioning to another state. 897 */ 898 private State mWaitForP2pDisableState = new WaitForP2pDisableState(); 899 /* Driver stopping */ 900 private State mDriverStoppingState = new DriverStoppingState(); 901 /* Driver stopped */ 902 private State mDriverStoppedState = new DriverStoppedState(); 903 /* Scan for networks, no connection will be established */ 904 private State mScanModeState = new ScanModeState(); 905 /* Connecting to an access point */ 906 private State mConnectModeState = new ConnectModeState(); 907 /* Connected at 802.11 (L2) level */ 908 private State mL2ConnectedState = new L2ConnectedState(); 909 /* fetching IP after connection to access point (assoc+auth complete) */ 910 private State mObtainingIpState = new ObtainingIpState(); 911 /* Connected with IP addr */ 912 private State mConnectedState = new ConnectedState(); 913 /* Roaming */ 914 private State mRoamingState = new RoamingState(); 915 /* disconnect issued, waiting for network disconnect confirmation */ 916 private State mDisconnectingState = new DisconnectingState(); 917 /* Network is not connected, supplicant assoc+auth is not complete */ 918 private State mDisconnectedState = new DisconnectedState(); 919 /* Waiting for WPS to be completed*/ 920 private State mWpsRunningState = new WpsRunningState(); 921 /* Soft ap state */ 922 private State mSoftApState = new SoftApState(); 923 924 public static class SimAuthRequestData { 925 int networkId; 926 int protocol; 927 String ssid; 928 // EAP-SIM: data[] contains the 3 rand, one for each of the 3 challenges 929 // EAP-AKA/AKA': data[] contains rand & authn couple for the single challenge 930 String[] data; 931 } 932 933 /** 934 * One of {@link WifiManager#WIFI_STATE_DISABLED}, 935 * {@link WifiManager#WIFI_STATE_DISABLING}, 936 * {@link WifiManager#WIFI_STATE_ENABLED}, 937 * {@link WifiManager#WIFI_STATE_ENABLING}, 938 * {@link WifiManager#WIFI_STATE_UNKNOWN} 939 */ 940 private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED); 941 942 /** 943 * One of {@link WifiManager#WIFI_AP_STATE_DISABLED}, 944 * {@link WifiManager#WIFI_AP_STATE_DISABLING}, 945 * {@link WifiManager#WIFI_AP_STATE_ENABLED}, 946 * {@link WifiManager#WIFI_AP_STATE_ENABLING}, 947 * {@link WifiManager#WIFI_AP_STATE_FAILED} 948 */ 949 private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED); 950 951 private static final int SCAN_REQUEST = 0; 952 953 /** 954 * Work source to use to blame usage on the WiFi service 955 */ 956 public static final WorkSource WIFI_WORK_SOURCE = new WorkSource(Process.WIFI_UID); 957 958 /** 959 * Keep track of whether WIFI is running. 960 */ 961 private boolean mIsRunning = false; 962 963 /** 964 * Keep track of whether we last told the battery stats we had started. 965 */ 966 private boolean mReportedRunning = false; 967 968 /** 969 * Most recently set source of starting WIFI. 970 */ 971 private final WorkSource mRunningWifiUids = new WorkSource(); 972 973 /** 974 * The last reported UIDs that were responsible for starting WIFI. 975 */ 976 private final WorkSource mLastRunningWifiUids = new WorkSource(); 977 978 private final IBatteryStats mBatteryStats; 979 980 private final String mTcpBufferSizes; 981 982 // Used for debug and stats gathering 983 private static int sScanAlarmIntentCount = 0; 984 985 private static final int sFrameworkMinScanIntervalSaneValue = 10000; 986 987 private long mGScanStartTimeMilli; 988 private long mGScanPeriodMilli; 989 990 private FrameworkFacade mFacade; 991 992 private final BackupManagerProxy mBackupManagerProxy; 993 994 private int mSystemUiUid = -1; 995 996 public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper, 997 UserManager userManager, WifiInjector wifiInjector, 998 BackupManagerProxy backupManagerProxy, 999 WifiCountryCode countryCode) { 1000 super("WifiStateMachine", looper); 1001 mWifiInjector = wifiInjector; 1002 mWifiMetrics = mWifiInjector.getWifiMetrics(); 1003 mWifiLastResortWatchdog = wifiInjector.getWifiLastResortWatchdog(); 1004 mClock = wifiInjector.getClock(); 1005 mPropertyService = wifiInjector.getPropertyService(); 1006 mBuildProperties = wifiInjector.getBuildProperties(); 1007 mContext = context; 1008 mFacade = facade; 1009 mWifiNative = WifiNative.getWlanNativeInterface(); 1010 mBackupManagerProxy = backupManagerProxy; 1011 1012 // TODO refactor WifiNative use of context out into it's own class 1013 mWifiNative.initContext(mContext); 1014 mInterfaceName = mWifiNative.getInterfaceName(); 1015 mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, ""); 1016 mBatteryStats = IBatteryStats.Stub.asInterface(mFacade.getService( 1017 BatteryStats.SERVICE_NAME)); 1018 1019 IBinder b = mFacade.getService(Context.NETWORKMANAGEMENT_SERVICE); 1020 mNwService = INetworkManagementService.Stub.asInterface(b); 1021 1022 mP2pSupported = mContext.getPackageManager().hasSystemFeature( 1023 PackageManager.FEATURE_WIFI_DIRECT); 1024 1025 mWifiConfigManager = mFacade.makeWifiConfigManager(context, mWifiNative, facade, 1026 mWifiInjector.getClock(), userManager, mWifiInjector.getKeyStore()); 1027 1028 mWifiMonitor = WifiMonitor.getInstance(); 1029 1030 boolean enableFirmwareLogs = mContext.getResources().getBoolean( 1031 R.bool.config_wifi_enable_wifi_firmware_debugging); 1032 1033 if (enableFirmwareLogs) { 1034 mWifiLogger = facade.makeRealLogger(mContext, this, mWifiNative, mBuildProperties); 1035 } else { 1036 mWifiLogger = facade.makeBaseLogger(); 1037 } 1038 1039 mWifiInfo = new WifiInfo(); 1040 mWifiQualifiedNetworkSelector = new WifiQualifiedNetworkSelector(mWifiConfigManager, 1041 mContext, mWifiInfo, mWifiInjector.getClock()); 1042 mSupplicantStateTracker = mFacade.makeSupplicantStateTracker( 1043 context, mWifiConfigManager, getHandler()); 1044 1045 mLinkProperties = new LinkProperties(); 1046 1047 IBinder s1 = mFacade.getService(Context.WIFI_P2P_SERVICE); 1048 mWifiP2pServiceImpl = (WifiP2pServiceImpl) IWifiP2pManager.Stub.asInterface(s1); 1049 1050 mNetworkInfo.setIsAvailable(false); 1051 mLastBssid = null; 1052 mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID; 1053 mLastSignalLevel = -1; 1054 1055 mIpManager = mFacade.makeIpManager(mContext, mInterfaceName, new IpManagerCallback()); 1056 mIpManager.setMulticastFilter(true); 1057 1058 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 1059 1060 // Make sure the interval is not configured less than 10 seconds 1061 int period = mContext.getResources().getInteger( 1062 R.integer.config_wifi_framework_scan_interval); 1063 if (period < sFrameworkMinScanIntervalSaneValue) { 1064 period = sFrameworkMinScanIntervalSaneValue; 1065 } 1066 mDefaultFrameworkScanIntervalMs = period; 1067 1068 mNoNetworksPeriodicScan = mContext.getResources().getInteger( 1069 R.integer.config_wifi_no_network_periodic_scan_interval); 1070 1071 mBackgroundScanSupported = mContext.getResources().getBoolean( 1072 R.bool.config_wifi_background_scan_support); 1073 1074 mPrimaryDeviceType = mContext.getResources().getString( 1075 R.string.config_wifi_p2p_device_type); 1076 1077 mCountryCode = countryCode; 1078 1079 mUserWantsSuspendOpt.set(mFacade.getIntegerSetting(mContext, 1080 Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1); 1081 1082 mNetworkCapabilitiesFilter.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 1083 mNetworkCapabilitiesFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1084 mNetworkCapabilitiesFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1085 mNetworkCapabilitiesFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1086 mNetworkCapabilitiesFilter.setLinkUpstreamBandwidthKbps(1024 * 1024); 1087 mNetworkCapabilitiesFilter.setLinkDownstreamBandwidthKbps(1024 * 1024); 1088 // TODO - needs to be a bit more dynamic 1089 mDfltNetworkCapabilities = new NetworkCapabilities(mNetworkCapabilitiesFilter); 1090 1091 IntentFilter filter = new IntentFilter(); 1092 filter.addAction(Intent.ACTION_SCREEN_ON); 1093 filter.addAction(Intent.ACTION_SCREEN_OFF); 1094 mContext.registerReceiver( 1095 new BroadcastReceiver() { 1096 @Override 1097 public void onReceive(Context context, Intent intent) { 1098 String action = intent.getAction(); 1099 1100 if (action.equals(Intent.ACTION_SCREEN_ON)) { 1101 sendMessage(CMD_SCREEN_STATE_CHANGED, 1); 1102 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 1103 sendMessage(CMD_SCREEN_STATE_CHANGED, 0); 1104 } 1105 } 1106 }, filter); 1107 1108 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( 1109 Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED), false, 1110 new ContentObserver(getHandler()) { 1111 @Override 1112 public void onChange(boolean selfChange) { 1113 mUserWantsSuspendOpt.set(mFacade.getIntegerSetting(mContext, 1114 Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1); 1115 } 1116 }); 1117 1118 mContext.registerReceiver( 1119 new BroadcastReceiver() { 1120 @Override 1121 public void onReceive(Context context, Intent intent) { 1122 sendMessage(CMD_BOOT_COMPLETED); 1123 } 1124 }, 1125 new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); 1126 1127 PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 1128 mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getName()); 1129 1130 mSuspendWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WifiSuspend"); 1131 mSuspendWakeLock.setReferenceCounted(false); 1132 1133 mTcpBufferSizes = mContext.getResources().getString( 1134 com.android.internal.R.string.config_wifi_tcp_buffers); 1135 1136 // CHECKSTYLE:OFF IndentationCheck 1137 addState(mDefaultState); 1138 addState(mInitialState, mDefaultState); 1139 addState(mSupplicantStartingState, mDefaultState); 1140 addState(mSupplicantStartedState, mDefaultState); 1141 addState(mDriverStartingState, mSupplicantStartedState); 1142 addState(mDriverStartedState, mSupplicantStartedState); 1143 addState(mScanModeState, mDriverStartedState); 1144 addState(mConnectModeState, mDriverStartedState); 1145 addState(mL2ConnectedState, mConnectModeState); 1146 addState(mObtainingIpState, mL2ConnectedState); 1147 addState(mConnectedState, mL2ConnectedState); 1148 addState(mRoamingState, mL2ConnectedState); 1149 addState(mDisconnectingState, mConnectModeState); 1150 addState(mDisconnectedState, mConnectModeState); 1151 addState(mWpsRunningState, mConnectModeState); 1152 addState(mWaitForP2pDisableState, mSupplicantStartedState); 1153 addState(mDriverStoppingState, mSupplicantStartedState); 1154 addState(mDriverStoppedState, mSupplicantStartedState); 1155 addState(mSupplicantStoppingState, mDefaultState); 1156 addState(mSoftApState, mDefaultState); 1157 // CHECKSTYLE:ON IndentationCheck 1158 1159 setInitialState(mInitialState); 1160 1161 setLogRecSize(NUM_LOG_RECS_NORMAL); 1162 setLogOnlyTransitions(false); 1163 1164 //start the state machine 1165 start(); 1166 1167 mWifiMonitor.registerHandler(mInterfaceName, CMD_TARGET_BSSID, getHandler()); 1168 mWifiMonitor.registerHandler(mInterfaceName, CMD_ASSOCIATED_BSSID, getHandler()); 1169 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ANQP_DONE_EVENT, getHandler()); 1170 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ASSOCIATION_REJECTION_EVENT, 1171 getHandler()); 1172 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1173 getHandler()); 1174 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.DRIVER_HUNG_EVENT, getHandler()); 1175 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.GAS_QUERY_DONE_EVENT, getHandler()); 1176 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.GAS_QUERY_START_EVENT, 1177 getHandler()); 1178 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.HS20_REMEDIATION_EVENT, 1179 getHandler()); 1180 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.NETWORK_CONNECTION_EVENT, 1181 getHandler()); 1182 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.NETWORK_DISCONNECTION_EVENT, 1183 getHandler()); 1184 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.RX_HS20_ANQP_ICON_EVENT, 1185 getHandler()); 1186 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SCAN_FAILED_EVENT, getHandler()); 1187 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SCAN_RESULTS_EVENT, getHandler()); 1188 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SSID_REENABLED, getHandler()); 1189 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SSID_TEMP_DISABLED, getHandler()); 1190 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_CONNECTION_EVENT, getHandler()); 1191 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_DISCONNECTION_EVENT, 1192 getHandler()); 1193 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 1194 getHandler()); 1195 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_REQUEST_IDENTITY, getHandler()); 1196 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_REQUEST_SIM_AUTH, getHandler()); 1197 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.WPS_FAIL_EVENT, getHandler()); 1198 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.WPS_OVERLAP_EVENT, getHandler()); 1199 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.WPS_SUCCESS_EVENT, getHandler()); 1200 mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.WPS_TIMEOUT_EVENT, getHandler()); 1201 1202 final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE); 1203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1204 intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED); 1205 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1206 1207 try { 1208 mSystemUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui", 1209 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); 1210 } catch (PackageManager.NameNotFoundException e) { 1211 loge("Unable to resolve SystemUI's UID."); 1212 } 1213 1214 mVerboseLoggingLevel = mFacade.getIntegerSetting( 1215 mContext, Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0); 1216 updateLoggingLevel(); 1217 } 1218 1219 class IpManagerCallback extends IpManager.Callback { 1220 @Override 1221 public void onPreDhcpAction() { 1222 sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION); 1223 } 1224 1225 @Override 1226 public void onPostDhcpAction() { 1227 sendMessage(DhcpClient.CMD_POST_DHCP_ACTION); 1228 } 1229 1230 @Override 1231 public void onNewDhcpResults(DhcpResults dhcpResults) { 1232 if (dhcpResults != null) { 1233 sendMessage(CMD_IPV4_PROVISIONING_SUCCESS, dhcpResults); 1234 } else { 1235 sendMessage(CMD_IPV4_PROVISIONING_FAILURE); 1236 mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(), 1237 mTargetRoamBSSID, 1238 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1239 } 1240 } 1241 1242 @Override 1243 public void onProvisioningSuccess(LinkProperties newLp) { 1244 sendMessage(CMD_UPDATE_LINKPROPERTIES, newLp); 1245 sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL); 1246 } 1247 1248 @Override 1249 public void onProvisioningFailure(LinkProperties newLp) { 1250 sendMessage(CMD_IP_CONFIGURATION_LOST); 1251 } 1252 1253 @Override 1254 public void onLinkPropertiesChange(LinkProperties newLp) { 1255 sendMessage(CMD_UPDATE_LINKPROPERTIES, newLp); 1256 } 1257 1258 @Override 1259 public void onReachabilityLost(String logMsg) { 1260 sendMessage(CMD_IP_REACHABILITY_LOST, logMsg); 1261 } 1262 1263 @Override 1264 public void installPacketFilter(byte[] filter) { 1265 sendMessage(CMD_INSTALL_PACKET_FILTER, filter); 1266 } 1267 1268 @Override 1269 public void setFallbackMulticastFilter(boolean enabled) { 1270 sendMessage(CMD_SET_FALLBACK_PACKET_FILTERING, enabled); 1271 } 1272 1273 @Override 1274 public void setNeighborDiscoveryOffload(boolean enabled) { 1275 sendMessage(CMD_CONFIG_ND_OFFLOAD, (enabled ? 1 : 0)); 1276 } 1277 } 1278 1279 private void stopIpManager() { 1280 /* Restore power save and suspend optimizations */ 1281 handlePostDhcpSetup(); 1282 mIpManager.stop(); 1283 } 1284 1285 PendingIntent getPrivateBroadcast(String action, int requestCode) { 1286 Intent intent = new Intent(action, null); 1287 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1288 intent.setPackage("android"); 1289 return mFacade.getBroadcast(mContext, requestCode, intent, 0); 1290 } 1291 1292 int getVerboseLoggingLevel() { 1293 return mVerboseLoggingLevel; 1294 } 1295 1296 void enableVerboseLogging(int verbose) { 1297 if (mVerboseLoggingLevel == verbose) { 1298 // We are already at the desired verbosity, avoid resetting StateMachine log records by 1299 // returning here until underlying bug is fixed (b/28027593) 1300 return; 1301 } 1302 mVerboseLoggingLevel = verbose; 1303 mFacade.setIntegerSetting( 1304 mContext, Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, verbose); 1305 updateLoggingLevel(); 1306 } 1307 1308 /** 1309 * Set wpa_supplicant log level using |mVerboseLoggingLevel| flag. 1310 */ 1311 void setSupplicantLogLevel() { 1312 if (mVerboseLoggingLevel > 0) { 1313 mWifiNative.setSupplicantLogLevel("DEBUG"); 1314 } else { 1315 mWifiNative.setSupplicantLogLevel("INFO"); 1316 } 1317 } 1318 1319 void updateLoggingLevel() { 1320 if (mVerboseLoggingLevel > 0) { 1321 DBG = true; 1322 setLogRecSize(ActivityManager.isLowRamDeviceStatic() 1323 ? NUM_LOG_RECS_VERBOSE_LOW_MEMORY : NUM_LOG_RECS_VERBOSE); 1324 } else { 1325 DBG = false; 1326 setLogRecSize(NUM_LOG_RECS_NORMAL); 1327 } 1328 configureVerboseHalLogging(mVerboseLoggingLevel > 0); 1329 setSupplicantLogLevel(); 1330 mCountryCode.enableVerboseLogging(mVerboseLoggingLevel); 1331 mWifiLogger.startLogging(DBG); 1332 mWifiMonitor.enableVerboseLogging(mVerboseLoggingLevel); 1333 mWifiNative.enableVerboseLogging(mVerboseLoggingLevel); 1334 mWifiConfigManager.enableVerboseLogging(mVerboseLoggingLevel); 1335 mSupplicantStateTracker.enableVerboseLogging(mVerboseLoggingLevel); 1336 mWifiQualifiedNetworkSelector.enableVerboseLogging(mVerboseLoggingLevel); 1337 if (mWifiConnectivityManager != null) { 1338 mWifiConnectivityManager.enableVerboseLogging(mVerboseLoggingLevel); 1339 } 1340 } 1341 1342 private static final String SYSTEM_PROPERTY_LOG_CONTROL_WIFIHAL = "log.tag.WifiHAL"; 1343 private static final String LOGD_LEVEL_DEBUG = "D"; 1344 private static final String LOGD_LEVEL_VERBOSE = "V"; 1345 private void configureVerboseHalLogging(boolean enableVerbose) { 1346 if (mBuildProperties.isUserBuild()) { // Verbose HAL logging not supported on user builds. 1347 return; 1348 } 1349 mPropertyService.set(SYSTEM_PROPERTY_LOG_CONTROL_WIFIHAL, 1350 enableVerbose ? LOGD_LEVEL_VERBOSE : LOGD_LEVEL_DEBUG); 1351 } 1352 1353 long mLastScanPermissionUpdate = 0; 1354 boolean mConnectedModeGScanOffloadStarted = false; 1355 // Don't do a G-scan enable/re-enable cycle more than once within 20seconds 1356 // The function updateAssociatedScanPermission() can be called quite frequently, hence 1357 // we want to throttle the GScan Stop->Start transition 1358 static final long SCAN_PERMISSION_UPDATE_THROTTLE_MILLI = 20000; 1359 void updateAssociatedScanPermission() { 1360 } 1361 1362 private int mAggressiveHandover = 0; 1363 1364 int getAggressiveHandover() { 1365 return mAggressiveHandover; 1366 } 1367 1368 void enableAggressiveHandover(int enabled) { 1369 mAggressiveHandover = enabled; 1370 } 1371 1372 public void clearANQPCache() { 1373 mWifiConfigManager.trimANQPCache(true); 1374 } 1375 1376 public void setAllowScansWithTraffic(int enabled) { 1377 mWifiConfigManager.mAlwaysEnableScansWhileAssociated.set(enabled); 1378 } 1379 1380 public int getAllowScansWithTraffic() { 1381 return mWifiConfigManager.mAlwaysEnableScansWhileAssociated.get(); 1382 } 1383 1384 /* 1385 * Dynamically turn on/off if switching networks while connected is allowd. 1386 */ 1387 public boolean setEnableAutoJoinWhenAssociated(boolean enabled) { 1388 sendMessage(CMD_ENABLE_AUTOJOIN_WHEN_ASSOCIATED, enabled ? 1 : 0); 1389 return true; 1390 } 1391 1392 public boolean getEnableAutoJoinWhenAssociated() { 1393 return mWifiConfigManager.getEnableAutoJoinWhenAssociated(); 1394 } 1395 1396 private boolean setRandomMacOui() { 1397 String oui = mContext.getResources().getString(R.string.config_wifi_random_mac_oui); 1398 if (TextUtils.isEmpty(oui)) { 1399 oui = GOOGLE_OUI; 1400 } 1401 String[] ouiParts = oui.split("-"); 1402 byte[] ouiBytes = new byte[3]; 1403 ouiBytes[0] = (byte) (Integer.parseInt(ouiParts[0], 16) & 0xFF); 1404 ouiBytes[1] = (byte) (Integer.parseInt(ouiParts[1], 16) & 0xFF); 1405 ouiBytes[2] = (byte) (Integer.parseInt(ouiParts[2], 16) & 0xFF); 1406 1407 logd("Setting OUI to " + oui); 1408 return mWifiNative.setScanningMacOui(ouiBytes); 1409 } 1410 1411 /** 1412 * ****************************************************** 1413 * Methods exposed for public use 1414 * ****************************************************** 1415 */ 1416 1417 public Messenger getMessenger() { 1418 return new Messenger(getHandler()); 1419 } 1420 1421 /** 1422 * TODO: doc 1423 */ 1424 public boolean syncPingSupplicant(AsyncChannel channel) { 1425 Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT); 1426 boolean result = (resultMsg.arg1 != FAILURE); 1427 resultMsg.recycle(); 1428 return result; 1429 } 1430 1431 /** 1432 * Initiate a wifi scan. If workSource is not null, blame is given to it, otherwise blame is 1433 * given to callingUid. 1434 * 1435 * @param callingUid The uid initiating the wifi scan. Blame will be given here unless 1436 * workSource is specified. 1437 * @param workSource If not null, blame is given to workSource. 1438 * @param settings Scan settings, see {@link ScanSettings}. 1439 */ 1440 public void startScan(int callingUid, int scanCounter, 1441 ScanSettings settings, WorkSource workSource) { 1442 Bundle bundle = new Bundle(); 1443 bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, settings); 1444 bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource); 1445 bundle.putLong(SCAN_REQUEST_TIME, System.currentTimeMillis()); 1446 sendMessage(CMD_START_SCAN, callingUid, scanCounter, bundle); 1447 } 1448 1449 // called from BroadcastListener 1450 1451 /** 1452 * Start reading new scan data 1453 * Data comes in as: 1454 * "scancount=5\n" 1455 * "nextcount=5\n" 1456 * "apcount=3\n" 1457 * "trunc\n" (optional) 1458 * "bssid=...\n" 1459 * "ssid=...\n" 1460 * "freq=...\n" (in Mhz) 1461 * "level=...\n" 1462 * "dist=...\n" (in cm) 1463 * "distsd=...\n" (standard deviation, in cm) 1464 * "====" 1465 * "bssid=...\n" 1466 * etc 1467 * "====" 1468 * "bssid=...\n" 1469 * etc 1470 * "%%%%" 1471 * "apcount=2\n" 1472 * "bssid=...\n" 1473 * etc 1474 * "%%%% 1475 * etc 1476 * "----" 1477 */ 1478 private final static boolean DEBUG_PARSE = false; 1479 1480 private long mDisconnectedTimeStamp = 0; 1481 1482 public long getDisconnectedTimeMilli() { 1483 if (getCurrentState() == mDisconnectedState 1484 && mDisconnectedTimeStamp != 0) { 1485 long now_ms = System.currentTimeMillis(); 1486 return now_ms - mDisconnectedTimeStamp; 1487 } 1488 return 0; 1489 } 1490 1491 // Last connect attempt is used to prevent scan requests: 1492 // - for a period of 10 seconds after attempting to connect 1493 private long lastConnectAttemptTimestamp = 0; 1494 private Set<Integer> lastScanFreqs = null; 1495 1496 // For debugging, keep track of last message status handling 1497 // TODO, find an equivalent mechanism as part of parent class 1498 private static int MESSAGE_HANDLING_STATUS_PROCESSED = 2; 1499 private static int MESSAGE_HANDLING_STATUS_OK = 1; 1500 private static int MESSAGE_HANDLING_STATUS_UNKNOWN = 0; 1501 private static int MESSAGE_HANDLING_STATUS_REFUSED = -1; 1502 private static int MESSAGE_HANDLING_STATUS_FAIL = -2; 1503 private static int MESSAGE_HANDLING_STATUS_OBSOLETE = -3; 1504 private static int MESSAGE_HANDLING_STATUS_DEFERRED = -4; 1505 private static int MESSAGE_HANDLING_STATUS_DISCARD = -5; 1506 private static int MESSAGE_HANDLING_STATUS_LOOPED = -6; 1507 private static int MESSAGE_HANDLING_STATUS_HANDLING_ERROR = -7; 1508 1509 private int messageHandlingStatus = 0; 1510 1511 //TODO: this is used only to track connection attempts, however the link state and packet per 1512 //TODO: second logic should be folded into that 1513 private boolean checkOrDeferScanAllowed(Message msg) { 1514 long now = System.currentTimeMillis(); 1515 if (lastConnectAttemptTimestamp != 0 && (now - lastConnectAttemptTimestamp) < 10000) { 1516 Message dmsg = Message.obtain(msg); 1517 sendMessageDelayed(dmsg, 11000 - (now - lastConnectAttemptTimestamp)); 1518 return false; 1519 } 1520 return true; 1521 } 1522 1523 private int mOnTime = 0; 1524 private int mTxTime = 0; 1525 private int mRxTime = 0; 1526 1527 private int mOnTimeScreenStateChange = 0; 1528 private long lastOntimeReportTimeStamp = 0; 1529 private long lastScreenStateChangeTimeStamp = 0; 1530 private int mOnTimeLastReport = 0; 1531 private int mTxTimeLastReport = 0; 1532 private int mRxTimeLastReport = 0; 1533 1534 private long lastLinkLayerStatsUpdate = 0; 1535 1536 String reportOnTime() { 1537 long now = System.currentTimeMillis(); 1538 StringBuilder sb = new StringBuilder(); 1539 // Report stats since last report 1540 int on = mOnTime - mOnTimeLastReport; 1541 mOnTimeLastReport = mOnTime; 1542 int tx = mTxTime - mTxTimeLastReport; 1543 mTxTimeLastReport = mTxTime; 1544 int rx = mRxTime - mRxTimeLastReport; 1545 mRxTimeLastReport = mRxTime; 1546 int period = (int) (now - lastOntimeReportTimeStamp); 1547 lastOntimeReportTimeStamp = now; 1548 sb.append(String.format("[on:%d tx:%d rx:%d period:%d]", on, tx, rx, period)); 1549 // Report stats since Screen State Changed 1550 on = mOnTime - mOnTimeScreenStateChange; 1551 period = (int) (now - lastScreenStateChangeTimeStamp); 1552 sb.append(String.format(" from screen [on:%d period:%d]", on, period)); 1553 return sb.toString(); 1554 } 1555 1556 WifiLinkLayerStats getWifiLinkLayerStats(boolean dbg) { 1557 WifiLinkLayerStats stats = null; 1558 if (mWifiLinkLayerStatsSupported > 0) { 1559 String name = "wlan0"; 1560 stats = mWifiNative.getWifiLinkLayerStats(name); 1561 if (name != null && stats == null && mWifiLinkLayerStatsSupported > 0) { 1562 mWifiLinkLayerStatsSupported -= 1; 1563 } else if (stats != null) { 1564 lastLinkLayerStatsUpdate = System.currentTimeMillis(); 1565 mOnTime = stats.on_time; 1566 mTxTime = stats.tx_time; 1567 mRxTime = stats.rx_time; 1568 mRunningBeaconCount = stats.beacon_rx; 1569 } 1570 } 1571 if (stats == null || mWifiLinkLayerStatsSupported <= 0) { 1572 long mTxPkts = mFacade.getTxPackets(mInterfaceName); 1573 long mRxPkts = mFacade.getRxPackets(mInterfaceName); 1574 mWifiInfo.updatePacketRates(mTxPkts, mRxPkts); 1575 } else { 1576 mWifiInfo.updatePacketRates(stats); 1577 } 1578 return stats; 1579 } 1580 1581 int startWifiIPPacketOffload(int slot, KeepalivePacketData packetData, int intervalSeconds) { 1582 int ret = mWifiNative.startSendingOffloadedPacket(slot, packetData, intervalSeconds * 1000); 1583 if (ret != 0) { 1584 loge("startWifiIPPacketOffload(" + slot + ", " + intervalSeconds + 1585 "): hardware error " + ret); 1586 return ConnectivityManager.PacketKeepalive.ERROR_HARDWARE_ERROR; 1587 } else { 1588 return ConnectivityManager.PacketKeepalive.SUCCESS; 1589 } 1590 } 1591 1592 int stopWifiIPPacketOffload(int slot) { 1593 int ret = mWifiNative.stopSendingOffloadedPacket(slot); 1594 if (ret != 0) { 1595 loge("stopWifiIPPacketOffload(" + slot + "): hardware error " + ret); 1596 return ConnectivityManager.PacketKeepalive.ERROR_HARDWARE_ERROR; 1597 } else { 1598 return ConnectivityManager.PacketKeepalive.SUCCESS; 1599 } 1600 } 1601 1602 int startRssiMonitoringOffload(byte maxRssi, byte minRssi) { 1603 return mWifiNative.startRssiMonitoring(maxRssi, minRssi, WifiStateMachine.this); 1604 } 1605 1606 int stopRssiMonitoringOffload() { 1607 return mWifiNative.stopRssiMonitoring(); 1608 } 1609 1610 private void handleScanRequest(Message message) { 1611 ScanSettings settings = null; 1612 WorkSource workSource = null; 1613 1614 // unbundle parameters 1615 Bundle bundle = (Bundle) message.obj; 1616 1617 if (bundle != null) { 1618 settings = bundle.getParcelable(CUSTOMIZED_SCAN_SETTING); 1619 workSource = bundle.getParcelable(CUSTOMIZED_SCAN_WORKSOURCE); 1620 } 1621 1622 Set<Integer> freqs = null; 1623 if (settings != null && settings.channelSet != null) { 1624 freqs = new HashSet<Integer>(); 1625 for (WifiChannel channel : settings.channelSet) { 1626 freqs.add(channel.freqMHz); 1627 } 1628 } 1629 1630 // Retrieve the list of hidden networkId's to scan for. 1631 Set<Integer> hiddenNetworkIds = mWifiConfigManager.getHiddenConfiguredNetworkIds(); 1632 1633 // call wifi native to start the scan 1634 if (startScanNative(freqs, hiddenNetworkIds, workSource)) { 1635 // a full scan covers everything, clearing scan request buffer 1636 if (freqs == null) 1637 mBufferedScanMsg.clear(); 1638 messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK; 1639 if (workSource != null) { 1640 // External worksource was passed along the scan request, 1641 // hence always send a broadcast 1642 mSendScanResultsBroadcast = true; 1643 } 1644 return; 1645 } 1646 1647 // if reach here, scan request is rejected 1648 1649 if (!mIsScanOngoing) { 1650 // if rejection is NOT due to ongoing scan (e.g. bad scan parameters), 1651 1652 // discard this request and pop up the next one 1653 if (mBufferedScanMsg.size() > 0) { 1654 sendMessage(mBufferedScanMsg.remove()); 1655 } 1656 messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; 1657 } else if (!mIsFullScanOngoing) { 1658 // if rejection is due to an ongoing scan, and the ongoing one is NOT a full scan, 1659 // buffer the scan request to make sure specified channels will be scanned eventually 1660 if (freqs == null) 1661 mBufferedScanMsg.clear(); 1662 if (mBufferedScanMsg.size() < SCAN_REQUEST_BUFFER_MAX_SIZE) { 1663 Message msg = obtainMessage(CMD_START_SCAN, 1664 message.arg1, message.arg2, bundle); 1665 mBufferedScanMsg.add(msg); 1666 } else { 1667 // if too many requests in buffer, combine them into a single full scan 1668 bundle = new Bundle(); 1669 bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, null); 1670 bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource); 1671 Message msg = obtainMessage(CMD_START_SCAN, message.arg1, message.arg2, bundle); 1672 mBufferedScanMsg.clear(); 1673 mBufferedScanMsg.add(msg); 1674 } 1675 messageHandlingStatus = MESSAGE_HANDLING_STATUS_LOOPED; 1676 } else { 1677 // mIsScanOngoing and mIsFullScanOngoing 1678 messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; 1679 } 1680 } 1681 1682 1683 // TODO this is a temporary measure to bridge between WifiScanner and WifiStateMachine until 1684 // scan functionality is refactored out of WifiStateMachine. 1685 /** 1686 * return true iff scan request is accepted 1687 */ 1688 private boolean startScanNative(final Set<Integer> freqs, Set<Integer> hiddenNetworkIds, 1689 WorkSource workSource) { 1690 WifiScanner.ScanSettings settings = new WifiScanner.ScanSettings(); 1691 if (freqs == null) { 1692 settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; 1693 } else { 1694 settings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 1695 int index = 0; 1696 settings.channels = new WifiScanner.ChannelSpec[freqs.size()]; 1697 for (Integer freq : freqs) { 1698 settings.channels[index++] = new WifiScanner.ChannelSpec(freq); 1699 } 1700 } 1701 settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 1702 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; 1703 if (hiddenNetworkIds != null && hiddenNetworkIds.size() > 0) { 1704 int i = 0; 1705 settings.hiddenNetworkIds = new int[hiddenNetworkIds.size()]; 1706 for (Integer netId : hiddenNetworkIds) { 1707 settings.hiddenNetworkIds[i++] = netId; 1708 } 1709 } 1710 WifiScanner.ScanListener nativeScanListener = new WifiScanner.ScanListener() { 1711 // ignore all events since WifiStateMachine is registered for the supplicant events 1712 public void onSuccess() { 1713 } 1714 public void onFailure(int reason, String description) { 1715 mIsScanOngoing = false; 1716 mIsFullScanOngoing = false; 1717 } 1718 public void onResults(WifiScanner.ScanData[] results) { 1719 } 1720 public void onFullResult(ScanResult fullScanResult) { 1721 } 1722 public void onPeriodChanged(int periodInMs) { 1723 } 1724 }; 1725 mWifiScanner.startScan(settings, nativeScanListener, workSource); 1726 mIsScanOngoing = true; 1727 mIsFullScanOngoing = (freqs == null); 1728 lastScanFreqs = freqs; 1729 return true; 1730 } 1731 1732 /** 1733 * TODO: doc 1734 */ 1735 public void setSupplicantRunning(boolean enable) { 1736 if (enable) { 1737 sendMessage(CMD_START_SUPPLICANT); 1738 } else { 1739 sendMessage(CMD_STOP_SUPPLICANT); 1740 } 1741 } 1742 1743 /** 1744 * TODO: doc 1745 */ 1746 public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) { 1747 if (enable) { 1748 sendMessage(CMD_START_AP, wifiConfig); 1749 } else { 1750 sendMessage(CMD_STOP_AP); 1751 } 1752 } 1753 1754 public void setWifiApConfiguration(WifiConfiguration config) { 1755 mWifiApConfigStore.setApConfiguration(config); 1756 } 1757 1758 public WifiConfiguration syncGetWifiApConfiguration() { 1759 return mWifiApConfigStore.getApConfiguration(); 1760 } 1761 1762 /** 1763 * TODO: doc 1764 */ 1765 public int syncGetWifiState() { 1766 return mWifiState.get(); 1767 } 1768 1769 /** 1770 * TODO: doc 1771 */ 1772 public String syncGetWifiStateByName() { 1773 switch (mWifiState.get()) { 1774 case WIFI_STATE_DISABLING: 1775 return "disabling"; 1776 case WIFI_STATE_DISABLED: 1777 return "disabled"; 1778 case WIFI_STATE_ENABLING: 1779 return "enabling"; 1780 case WIFI_STATE_ENABLED: 1781 return "enabled"; 1782 case WIFI_STATE_UNKNOWN: 1783 return "unknown state"; 1784 default: 1785 return "[invalid state]"; 1786 } 1787 } 1788 1789 /** 1790 * TODO: doc 1791 */ 1792 public int syncGetWifiApState() { 1793 return mWifiApState.get(); 1794 } 1795 1796 /** 1797 * TODO: doc 1798 */ 1799 public String syncGetWifiApStateByName() { 1800 switch (mWifiApState.get()) { 1801 case WIFI_AP_STATE_DISABLING: 1802 return "disabling"; 1803 case WIFI_AP_STATE_DISABLED: 1804 return "disabled"; 1805 case WIFI_AP_STATE_ENABLING: 1806 return "enabling"; 1807 case WIFI_AP_STATE_ENABLED: 1808 return "enabled"; 1809 case WIFI_AP_STATE_FAILED: 1810 return "failed"; 1811 default: 1812 return "[invalid state]"; 1813 } 1814 } 1815 1816 public boolean isConnected() { 1817 return getCurrentState() == mConnectedState; 1818 } 1819 1820 public boolean isDisconnected() { 1821 return getCurrentState() == mDisconnectedState; 1822 } 1823 1824 public boolean isSupplicantTransientState() { 1825 SupplicantState SupplicantState = mWifiInfo.getSupplicantState(); 1826 if (SupplicantState == SupplicantState.ASSOCIATING 1827 || SupplicantState == SupplicantState.AUTHENTICATING 1828 || SupplicantState == SupplicantState.FOUR_WAY_HANDSHAKE 1829 || SupplicantState == SupplicantState.GROUP_HANDSHAKE) { 1830 1831 if (DBG) { 1832 Log.d(TAG, "Supplicant is under transient state: " + SupplicantState); 1833 } 1834 return true; 1835 } else { 1836 if (DBG) { 1837 Log.d(TAG, "Supplicant is under steady state: " + SupplicantState); 1838 } 1839 } 1840 1841 return false; 1842 } 1843 1844 public boolean isLinkDebouncing() { 1845 return linkDebouncing; 1846 } 1847 1848 /** 1849 * Get status information for the current connection, if any. 1850 * 1851 * @return a {@link WifiInfo} object containing information about the current connection 1852 */ 1853 public WifiInfo syncRequestConnectionInfo() { 1854 return getWiFiInfoForUid(Binder.getCallingUid()); 1855 } 1856 1857 public WifiInfo getWifiInfo() { 1858 return mWifiInfo; 1859 } 1860 1861 public DhcpResults syncGetDhcpResults() { 1862 synchronized (mDhcpResultsLock) { 1863 return new DhcpResults(mDhcpResults); 1864 } 1865 } 1866 1867 /** 1868 * TODO: doc 1869 */ 1870 public void setDriverStart(boolean enable) { 1871 if (enable) { 1872 sendMessage(CMD_START_DRIVER); 1873 } else { 1874 sendMessage(CMD_STOP_DRIVER); 1875 } 1876 } 1877 1878 /** 1879 * TODO: doc 1880 */ 1881 public void setOperationalMode(int mode) { 1882 if (DBG) log("setting operational mode to " + String.valueOf(mode)); 1883 sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0); 1884 } 1885 1886 /** 1887 * Allow tests to confirm the operational mode for WSM. 1888 */ 1889 @VisibleForTesting 1890 protected int getOperationalModeForTest() { 1891 return mOperationalMode; 1892 } 1893 1894 /** 1895 * TODO: doc 1896 */ 1897 public List<ScanResult> syncGetScanResultsList() { 1898 synchronized (mScanResultsLock) { 1899 List<ScanResult> scanList = new ArrayList<ScanResult>(); 1900 for (ScanDetail result : mScanResults) { 1901 scanList.add(new ScanResult(result.getScanResult())); 1902 } 1903 return scanList; 1904 } 1905 } 1906 1907 public int syncAddPasspointManagementObject(AsyncChannel channel, String managementObject) { 1908 Message resultMsg = 1909 channel.sendMessageSynchronously(CMD_ADD_PASSPOINT_MO, managementObject); 1910 int result = resultMsg.arg1; 1911 resultMsg.recycle(); 1912 return result; 1913 } 1914 1915 public int syncModifyPasspointManagementObject(AsyncChannel channel, String fqdn, 1916 List<PasspointManagementObjectDefinition> 1917 managementObjectDefinitions) { 1918 Bundle bundle = new Bundle(); 1919 bundle.putString("FQDN", fqdn); 1920 bundle.putParcelableList("MOS", managementObjectDefinitions); 1921 Message resultMsg = channel.sendMessageSynchronously(CMD_MODIFY_PASSPOINT_MO, bundle); 1922 int result = resultMsg.arg1; 1923 resultMsg.recycle(); 1924 return result; 1925 } 1926 1927 public boolean syncQueryPasspointIcon(AsyncChannel channel, long bssid, String fileName) { 1928 Bundle bundle = new Bundle(); 1929 bundle.putLong("BSSID", bssid); 1930 bundle.putString("FILENAME", fileName); 1931 Message resultMsg = channel.sendMessageSynchronously(CMD_QUERY_OSU_ICON, bundle); 1932 int result = resultMsg.arg1; 1933 resultMsg.recycle(); 1934 return result == 1; 1935 } 1936 1937 public int matchProviderWithCurrentNetwork(AsyncChannel channel, String fqdn) { 1938 Message resultMsg = channel.sendMessageSynchronously(CMD_MATCH_PROVIDER_NETWORK, fqdn); 1939 int result = resultMsg.arg1; 1940 resultMsg.recycle(); 1941 return result; 1942 } 1943 1944 /** 1945 * Deauthenticate and set the re-authentication hold off time for the current network 1946 * @param holdoff hold off time in milliseconds 1947 * @param ess set if the hold off pertains to an ESS rather than a BSS 1948 */ 1949 public void deauthenticateNetwork(AsyncChannel channel, long holdoff, boolean ess) { 1950 // TODO: This needs an implementation 1951 } 1952 1953 public void disableEphemeralNetwork(String SSID) { 1954 if (SSID != null) { 1955 sendMessage(CMD_DISABLE_EPHEMERAL_NETWORK, SSID); 1956 } 1957 } 1958 1959 /** 1960 * Disconnect from Access Point 1961 */ 1962 public void disconnectCommand() { 1963 sendMessage(CMD_DISCONNECT); 1964 } 1965 1966 public void disconnectCommand(int uid, int reason) { 1967 sendMessage(CMD_DISCONNECT, uid, reason); 1968 } 1969 1970 /** 1971 * Initiate a reconnection to AP 1972 */ 1973 public void reconnectCommand() { 1974 sendMessage(CMD_RECONNECT); 1975 } 1976 1977 /** 1978 * Initiate a re-association to AP 1979 */ 1980 public void reassociateCommand() { 1981 sendMessage(CMD_REASSOCIATE); 1982 } 1983 1984 /** 1985 * Reload networks and then reconnect; helps load correct data for TLS networks 1986 */ 1987 1988 public void reloadTlsNetworksAndReconnect() { 1989 sendMessage(CMD_RELOAD_TLS_AND_RECONNECT); 1990 } 1991 1992 /** 1993 * Add a network synchronously 1994 * 1995 * @return network id of the new network 1996 */ 1997 public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) { 1998 Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config); 1999 int result = resultMsg.arg1; 2000 resultMsg.recycle(); 2001 return result; 2002 } 2003 2004 /** 2005 * Get configured networks synchronously 2006 * 2007 * @param channel 2008 * @return 2009 */ 2010 2011 public List<WifiConfiguration> syncGetConfiguredNetworks(int uuid, AsyncChannel channel) { 2012 Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONFIGURED_NETWORKS, uuid); 2013 List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj; 2014 resultMsg.recycle(); 2015 return result; 2016 } 2017 2018 public List<WifiConfiguration> syncGetPrivilegedConfiguredNetwork(AsyncChannel channel) { 2019 Message resultMsg = channel.sendMessageSynchronously( 2020 CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS); 2021 List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj; 2022 resultMsg.recycle(); 2023 return result; 2024 } 2025 2026 public WifiConfiguration syncGetMatchingWifiConfig(ScanResult scanResult, AsyncChannel channel) { 2027 Message resultMsg = channel.sendMessageSynchronously(CMD_GET_MATCHING_CONFIG, scanResult); 2028 return (WifiConfiguration) resultMsg.obj; 2029 } 2030 2031 /** 2032 * Get connection statistics synchronously 2033 * 2034 * @param channel 2035 * @return 2036 */ 2037 2038 public WifiConnectionStatistics syncGetConnectionStatistics(AsyncChannel channel) { 2039 Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONNECTION_STATISTICS); 2040 WifiConnectionStatistics result = (WifiConnectionStatistics) resultMsg.obj; 2041 resultMsg.recycle(); 2042 return result; 2043 } 2044 2045 /** 2046 * Get adaptors synchronously 2047 */ 2048 2049 public int syncGetSupportedFeatures(AsyncChannel channel) { 2050 Message resultMsg = channel.sendMessageSynchronously(CMD_GET_SUPPORTED_FEATURES); 2051 int supportedFeatureSet = resultMsg.arg1; 2052 resultMsg.recycle(); 2053 return supportedFeatureSet; 2054 } 2055 2056 /** 2057 * Get link layers stats for adapter synchronously 2058 */ 2059 public WifiLinkLayerStats syncGetLinkLayerStats(AsyncChannel channel) { 2060 Message resultMsg = channel.sendMessageSynchronously(CMD_GET_LINK_LAYER_STATS); 2061 WifiLinkLayerStats result = (WifiLinkLayerStats) resultMsg.obj; 2062 resultMsg.recycle(); 2063 return result; 2064 } 2065 2066 /** 2067 * Delete a network 2068 * 2069 * @param networkId id of the network to be removed 2070 */ 2071 public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) { 2072 Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId); 2073 boolean result = (resultMsg.arg1 != FAILURE); 2074 resultMsg.recycle(); 2075 return result; 2076 } 2077 2078 /** 2079 * Enable a network 2080 * 2081 * @param netId network id of the network 2082 * @param disableOthers true, if all other networks have to be disabled 2083 * @return {@code true} if the operation succeeds, {@code false} otherwise 2084 */ 2085 public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) { 2086 Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId, 2087 disableOthers ? 1 : 0); 2088 boolean result = (resultMsg.arg1 != FAILURE); 2089 resultMsg.recycle(); 2090 return result; 2091 } 2092 2093 /** 2094 * Disable a network 2095 * 2096 * @param netId network id of the network 2097 * @return {@code true} if the operation succeeds, {@code false} otherwise 2098 */ 2099 public boolean syncDisableNetwork(AsyncChannel channel, int netId) { 2100 Message resultMsg = channel.sendMessageSynchronously(WifiManager.DISABLE_NETWORK, netId); 2101 boolean result = (resultMsg.arg1 != WifiManager.DISABLE_NETWORK_FAILED); 2102 resultMsg.recycle(); 2103 return result; 2104 } 2105 2106 /** 2107 * Retrieves a WPS-NFC configuration token for the specified network 2108 * 2109 * @return a hex string representation of the WPS-NFC configuration token 2110 */ 2111 public String syncGetWpsNfcConfigurationToken(int netId) { 2112 return mWifiNative.getNfcWpsConfigurationToken(netId); 2113 } 2114 2115 /** 2116 * Blacklist a BSSID. This will avoid the AP if there are 2117 * alternate APs to connect 2118 * 2119 * @param bssid BSSID of the network 2120 */ 2121 public void addToBlacklist(String bssid) { 2122 sendMessage(CMD_BLACKLIST_NETWORK, bssid); 2123 } 2124 2125 /** 2126 * Clear the blacklist list 2127 */ 2128 public void clearBlacklist() { 2129 sendMessage(CMD_CLEAR_BLACKLIST); 2130 } 2131 2132 public void enableRssiPolling(boolean enabled) { 2133 sendMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0); 2134 } 2135 2136 public void enableAllNetworks() { 2137 sendMessage(CMD_ENABLE_ALL_NETWORKS); 2138 } 2139 2140 /** 2141 * Start filtering Multicast v4 packets 2142 */ 2143 public void startFilteringMulticastPackets() { 2144 mIpManager.setMulticastFilter(true); 2145 } 2146 2147 /** 2148 * Stop filtering Multicast v4 packets 2149 */ 2150 public void stopFilteringMulticastPackets() { 2151 mIpManager.setMulticastFilter(false); 2152 } 2153 2154 /** 2155 * Set high performance mode of operation. 2156 * Enabling would set active power mode and disable suspend optimizations; 2157 * disabling would set auto power mode and enable suspend optimizations 2158 * 2159 * @param enable true if enable, false otherwise 2160 */ 2161 public void setHighPerfModeEnabled(boolean enable) { 2162 sendMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0); 2163 } 2164 2165 2166 /** 2167 * reset cached SIM credential data 2168 */ 2169 public synchronized void resetSimAuthNetworks(boolean simPresent) { 2170 sendMessage(CMD_RESET_SIM_NETWORKS, simPresent ? 1 : 0); 2171 } 2172 2173 /** 2174 * Get Network object of current wifi network 2175 * @return Network object of current wifi network 2176 */ 2177 public Network getCurrentNetwork() { 2178 if (mNetworkAgent != null) { 2179 return new Network(mNetworkAgent.netId); 2180 } else { 2181 return null; 2182 } 2183 } 2184 2185 2186 /** 2187 * Set the operational frequency band 2188 * 2189 * @param band 2190 * @param persist {@code true} if the setting should be remembered. 2191 */ 2192 public void setFrequencyBand(int band, boolean persist) { 2193 if (persist) { 2194 Settings.Global.putInt(mContext.getContentResolver(), 2195 Settings.Global.WIFI_FREQUENCY_BAND, 2196 band); 2197 } 2198 sendMessage(CMD_SET_FREQUENCY_BAND, band, 0); 2199 } 2200 2201 /** 2202 * Enable TDLS for a specific MAC address 2203 */ 2204 public void enableTdls(String remoteMacAddress, boolean enable) { 2205 int enabler = enable ? 1 : 0; 2206 sendMessage(CMD_ENABLE_TDLS, enabler, 0, remoteMacAddress); 2207 } 2208 2209 /** 2210 * Returns the operational frequency band 2211 */ 2212 public int getFrequencyBand() { 2213 return mFrequencyBand.get(); 2214 } 2215 2216 /** 2217 * Returns the wifi configuration file 2218 */ 2219 public String getConfigFile() { 2220 return mWifiConfigManager.getConfigFile(); 2221 } 2222 2223 /** 2224 * Send a message indicating bluetooth adapter connection state changed 2225 */ 2226 public void sendBluetoothAdapterStateChange(int state) { 2227 sendMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0); 2228 } 2229 2230 /** 2231 * Send a message indicating a package has been uninstalled. 2232 */ 2233 public void removeAppConfigs(String packageName, int uid) { 2234 // Build partial AppInfo manually - package may not exist in database any more 2235 ApplicationInfo ai = new ApplicationInfo(); 2236 ai.packageName = packageName; 2237 ai.uid = uid; 2238 sendMessage(CMD_REMOVE_APP_CONFIGURATIONS, ai); 2239 } 2240 2241 /** 2242 * Send a message indicating a user has been removed. 2243 */ 2244 public void removeUserConfigs(int userId) { 2245 sendMessage(CMD_REMOVE_USER_CONFIGURATIONS, userId); 2246 } 2247 2248 /** 2249 * Save configuration on supplicant 2250 * 2251 * @return {@code true} if the operation succeeds, {@code false} otherwise 2252 * <p/> 2253 * TODO: deprecate this 2254 */ 2255 public boolean syncSaveConfig(AsyncChannel channel) { 2256 Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG); 2257 boolean result = (resultMsg.arg1 != FAILURE); 2258 resultMsg.recycle(); 2259 return result; 2260 } 2261 2262 public void updateBatteryWorkSource(WorkSource newSource) { 2263 synchronized (mRunningWifiUids) { 2264 try { 2265 if (newSource != null) { 2266 mRunningWifiUids.set(newSource); 2267 } 2268 if (mIsRunning) { 2269 if (mReportedRunning) { 2270 // If the work source has changed since last time, need 2271 // to remove old work from battery stats. 2272 if (mLastRunningWifiUids.diff(mRunningWifiUids)) { 2273 mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids, 2274 mRunningWifiUids); 2275 mLastRunningWifiUids.set(mRunningWifiUids); 2276 } 2277 } else { 2278 // Now being started, report it. 2279 mBatteryStats.noteWifiRunning(mRunningWifiUids); 2280 mLastRunningWifiUids.set(mRunningWifiUids); 2281 mReportedRunning = true; 2282 } 2283 } else { 2284 if (mReportedRunning) { 2285 // Last reported we were running, time to stop. 2286 mBatteryStats.noteWifiStopped(mLastRunningWifiUids); 2287 mLastRunningWifiUids.clear(); 2288 mReportedRunning = false; 2289 } 2290 } 2291 mWakeLock.setWorkSource(newSource); 2292 } catch (RemoteException ignore) { 2293 } 2294 } 2295 } 2296 2297 public void dumpIpManager(FileDescriptor fd, PrintWriter pw, String[] args) { 2298 mIpManager.dump(fd, pw, args); 2299 } 2300 2301 @Override 2302 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2303 super.dump(fd, pw, args); 2304 mSupplicantStateTracker.dump(fd, pw, args); 2305 pw.println("mLinkProperties " + mLinkProperties); 2306 pw.println("mWifiInfo " + mWifiInfo); 2307 pw.println("mDhcpResults " + mDhcpResults); 2308 pw.println("mNetworkInfo " + mNetworkInfo); 2309 pw.println("mLastSignalLevel " + mLastSignalLevel); 2310 pw.println("mLastBssid " + mLastBssid); 2311 pw.println("mLastNetworkId " + mLastNetworkId); 2312 pw.println("mOperationalMode " + mOperationalMode); 2313 pw.println("mUserWantsSuspendOpt " + mUserWantsSuspendOpt); 2314 pw.println("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled); 2315 pw.println("Supplicant status " + mWifiNative.status(true)); 2316 if (mCountryCode.getCountryCodeSentToDriver() != null) { 2317 pw.println("CountryCode sent to driver " + mCountryCode.getCountryCodeSentToDriver()); 2318 } else { 2319 if (mCountryCode.getCountryCode() != null) { 2320 pw.println("CountryCode: " + 2321 mCountryCode.getCountryCode() + " was not sent to driver"); 2322 } else { 2323 pw.println("CountryCode was not initialized"); 2324 } 2325 } 2326 pw.println("mConnectedModeGScanOffloadStarted " + mConnectedModeGScanOffloadStarted); 2327 pw.println("mGScanPeriodMilli " + mGScanPeriodMilli); 2328 if (mWhiteListedSsids != null && mWhiteListedSsids.length > 0) { 2329 pw.println("SSID whitelist :" ); 2330 for (int i=0; i < mWhiteListedSsids.length; i++) { 2331 pw.println(" " + mWhiteListedSsids[i]); 2332 } 2333 } 2334 if (mNetworkFactory != null) { 2335 mNetworkFactory.dump(fd, pw, args); 2336 } else { 2337 pw.println("mNetworkFactory is not initialized"); 2338 } 2339 2340 if (mUntrustedNetworkFactory != null) { 2341 mUntrustedNetworkFactory.dump(fd, pw, args); 2342 } else { 2343 pw.println("mUntrustedNetworkFactory is not initialized"); 2344 } 2345 pw.println("Wlan Wake Reasons:" + mWifiNative.getWlanWakeReasonCount()); 2346 pw.println(); 2347 updateWifiMetrics(); 2348 mWifiMetrics.dump(fd, pw, args); 2349 pw.println(); 2350 2351 mWifiConfigManager.dump(fd, pw, args); 2352 pw.println(); 2353 mWifiLogger.captureBugReportData(WifiLogger.REPORT_REASON_USER_ACTION); 2354 mWifiLogger.dump(fd, pw, args); 2355 mWifiQualifiedNetworkSelector.dump(fd, pw, args); 2356 dumpIpManager(fd, pw, args); 2357 if (mWifiConnectivityManager != null) { 2358 mWifiConnectivityManager.dump(fd, pw, args); 2359 } 2360 } 2361 2362 public void handleUserSwitch(int userId) { 2363 sendMessage(CMD_USER_SWITCH, userId); 2364 } 2365 2366 /** 2367 * ****************************************************** 2368 * Internal private functions 2369 * ****************************************************** 2370 */ 2371 2372 private void logStateAndMessage(Message message, State state) { 2373 messageHandlingStatus = 0; 2374 if (DBG) { 2375 logd(" " + state.getClass().getSimpleName() + " " + getLogRecString(message)); 2376 } 2377 } 2378 2379 /** 2380 * helper, prints the milli time since boot wi and w/o suspended time 2381 */ 2382 String printTime() { 2383 StringBuilder sb = new StringBuilder(); 2384 sb.append(" rt=").append(SystemClock.uptimeMillis()); 2385 sb.append("/").append(SystemClock.elapsedRealtime()); 2386 return sb.toString(); 2387 } 2388 2389 /** 2390 * Return the additional string to be logged by LogRec, default 2391 * 2392 * @param msg that was processed 2393 * @return information to be logged as a String 2394 */ 2395 protected String getLogRecString(Message msg) { 2396 WifiConfiguration config; 2397 Long now; 2398 String report; 2399 String key; 2400 StringBuilder sb = new StringBuilder(); 2401 if (mScreenOn) { 2402 sb.append("!"); 2403 } 2404 if (messageHandlingStatus != MESSAGE_HANDLING_STATUS_UNKNOWN) { 2405 sb.append("(").append(messageHandlingStatus).append(")"); 2406 } 2407 sb.append(smToString(msg)); 2408 if (msg.sendingUid > 0 && msg.sendingUid != Process.WIFI_UID) { 2409 sb.append(" uid=" + msg.sendingUid); 2410 } 2411 sb.append(" ").append(printTime()); 2412 switch (msg.what) { 2413 case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION: 2414 sb.append(" "); 2415 sb.append(Integer.toString(msg.arg1)); 2416 sb.append(" "); 2417 sb.append(Integer.toString(msg.arg2)); 2418 sb.append(" autojoinAllowed="); 2419 sb.append(mWifiConfigManager.getEnableAutoJoinWhenAssociated()); 2420 sb.append(" withTraffic=").append(getAllowScansWithTraffic()); 2421 sb.append(" tx=").append(mWifiInfo.txSuccessRate); 2422 sb.append("/").append(mWifiConfigManager.MAX_TX_PACKET_FOR_FULL_SCANS); 2423 sb.append(" rx=").append(mWifiInfo.rxSuccessRate); 2424 sb.append("/").append(mWifiConfigManager.MAX_RX_PACKET_FOR_FULL_SCANS); 2425 sb.append(" -> ").append(mConnectedModeGScanOffloadStarted); 2426 break; 2427 case CMD_START_SCAN: 2428 now = System.currentTimeMillis(); 2429 sb.append(" "); 2430 sb.append(Integer.toString(msg.arg1)); 2431 sb.append(" "); 2432 sb.append(Integer.toString(msg.arg2)); 2433 sb.append(" ic="); 2434 sb.append(Integer.toString(sScanAlarmIntentCount)); 2435 if (msg.obj != null) { 2436 Bundle bundle = (Bundle) msg.obj; 2437 Long request = bundle.getLong(SCAN_REQUEST_TIME, 0); 2438 if (request != 0) { 2439 sb.append(" proc(ms):").append(now - request); 2440 } 2441 } 2442 if (mIsScanOngoing) sb.append(" onGoing"); 2443 if (mIsFullScanOngoing) sb.append(" full"); 2444 sb.append(" rssi=").append(mWifiInfo.getRssi()); 2445 sb.append(" f=").append(mWifiInfo.getFrequency()); 2446 sb.append(" sc=").append(mWifiInfo.score); 2447 sb.append(" link=").append(mWifiInfo.getLinkSpeed()); 2448 sb.append(String.format(" tx=%.1f,", mWifiInfo.txSuccessRate)); 2449 sb.append(String.format(" %.1f,", mWifiInfo.txRetriesRate)); 2450 sb.append(String.format(" %.1f ", mWifiInfo.txBadRate)); 2451 sb.append(String.format(" rx=%.1f", mWifiInfo.rxSuccessRate)); 2452 if (lastScanFreqs != null) { 2453 sb.append(" list="); 2454 for(int freq : lastScanFreqs) { 2455 sb.append(freq).append(","); 2456 } 2457 } 2458 report = reportOnTime(); 2459 if (report != null) { 2460 sb.append(" ").append(report); 2461 } 2462 break; 2463 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 2464 sb.append(" "); 2465 sb.append(Integer.toString(msg.arg1)); 2466 sb.append(" "); 2467 sb.append(Integer.toString(msg.arg2)); 2468 StateChangeResult stateChangeResult = (StateChangeResult) msg.obj; 2469 if (stateChangeResult != null) { 2470 sb.append(stateChangeResult.toString()); 2471 } 2472 break; 2473 case WifiManager.SAVE_NETWORK: 2474 case WifiStateMachine.CMD_AUTO_SAVE_NETWORK: 2475 sb.append(" "); 2476 sb.append(Integer.toString(msg.arg1)); 2477 sb.append(" "); 2478 sb.append(Integer.toString(msg.arg2)); 2479 if (lastSavedConfigurationAttempt != null) { 2480 sb.append(" ").append(lastSavedConfigurationAttempt.configKey()); 2481 sb.append(" nid=").append(lastSavedConfigurationAttempt.networkId); 2482 if (lastSavedConfigurationAttempt.hiddenSSID) { 2483 sb.append(" hidden"); 2484 } 2485 if (lastSavedConfigurationAttempt.preSharedKey != null 2486 && !lastSavedConfigurationAttempt.preSharedKey.equals("*")) { 2487 sb.append(" hasPSK"); 2488 } 2489 if (lastSavedConfigurationAttempt.ephemeral) { 2490 sb.append(" ephemeral"); 2491 } 2492 if (lastSavedConfigurationAttempt.selfAdded) { 2493 sb.append(" selfAdded"); 2494 } 2495 sb.append(" cuid=").append(lastSavedConfigurationAttempt.creatorUid); 2496 sb.append(" suid=").append(lastSavedConfigurationAttempt.lastUpdateUid); 2497 } 2498 break; 2499 case WifiManager.FORGET_NETWORK: 2500 sb.append(" "); 2501 sb.append(Integer.toString(msg.arg1)); 2502 sb.append(" "); 2503 sb.append(Integer.toString(msg.arg2)); 2504 if (lastForgetConfigurationAttempt != null) { 2505 sb.append(" ").append(lastForgetConfigurationAttempt.configKey()); 2506 sb.append(" nid=").append(lastForgetConfigurationAttempt.networkId); 2507 if (lastForgetConfigurationAttempt.hiddenSSID) { 2508 sb.append(" hidden"); 2509 } 2510 if (lastForgetConfigurationAttempt.preSharedKey != null) { 2511 sb.append(" hasPSK"); 2512 } 2513 if (lastForgetConfigurationAttempt.ephemeral) { 2514 sb.append(" ephemeral"); 2515 } 2516 if (lastForgetConfigurationAttempt.selfAdded) { 2517 sb.append(" selfAdded"); 2518 } 2519 sb.append(" cuid=").append(lastForgetConfigurationAttempt.creatorUid); 2520 sb.append(" suid=").append(lastForgetConfigurationAttempt.lastUpdateUid); 2521 WifiConfiguration.NetworkSelectionStatus netWorkSelectionStatus = 2522 lastForgetConfigurationAttempt.getNetworkSelectionStatus(); 2523 sb.append(" ajst=").append( 2524 netWorkSelectionStatus.getNetworkStatusString()); 2525 } 2526 break; 2527 case WifiMonitor.ASSOCIATION_REJECTION_EVENT: 2528 sb.append(" "); 2529 sb.append(Integer.toString(msg.arg1)); 2530 sb.append(" "); 2531 sb.append(Integer.toString(msg.arg2)); 2532 String bssid = (String) msg.obj; 2533 if (bssid != null && bssid.length() > 0) { 2534 sb.append(" "); 2535 sb.append(bssid); 2536 } 2537 sb.append(" blacklist=" + Boolean.toString(didBlackListBSSID)); 2538 break; 2539 case WifiMonitor.SCAN_RESULTS_EVENT: 2540 sb.append(" "); 2541 sb.append(Integer.toString(msg.arg1)); 2542 sb.append(" "); 2543 sb.append(Integer.toString(msg.arg2)); 2544 if (mScanResults != null) { 2545 sb.append(" found="); 2546 sb.append(mScanResults.size()); 2547 } 2548 sb.append(" known=").append(mNumScanResultsKnown); 2549 sb.append(" got=").append(mNumScanResultsReturned); 2550 sb.append(String.format(" bcn=%d", mRunningBeaconCount)); 2551 sb.append(String.format(" con=%d", mConnectionRequests)); 2552 key = mWifiConfigManager.getLastSelectedConfiguration(); 2553 if (key != null) { 2554 sb.append(" last=").append(key); 2555 } 2556 break; 2557 case WifiMonitor.SCAN_FAILED_EVENT: 2558 break; 2559 case WifiMonitor.NETWORK_CONNECTION_EVENT: 2560 sb.append(" "); 2561 sb.append(Integer.toString(msg.arg1)); 2562 sb.append(" "); 2563 sb.append(Integer.toString(msg.arg2)); 2564 sb.append(" ").append(mLastBssid); 2565 sb.append(" nid=").append(mLastNetworkId); 2566 config = getCurrentWifiConfiguration(); 2567 if (config != null) { 2568 sb.append(" ").append(config.configKey()); 2569 } 2570 key = mWifiConfigManager.getLastSelectedConfiguration(); 2571 if (key != null) { 2572 sb.append(" last=").append(key); 2573 } 2574 break; 2575 case CMD_TARGET_BSSID: 2576 case CMD_ASSOCIATED_BSSID: 2577 sb.append(" "); 2578 sb.append(Integer.toString(msg.arg1)); 2579 sb.append(" "); 2580 sb.append(Integer.toString(msg.arg2)); 2581 if (msg.obj != null) { 2582 sb.append(" BSSID=").append((String) msg.obj); 2583 } 2584 if (mTargetRoamBSSID != null) { 2585 sb.append(" Target=").append(mTargetRoamBSSID); 2586 } 2587 sb.append(" roam=").append(Boolean.toString(mAutoRoaming)); 2588 break; 2589 case WifiMonitor.NETWORK_DISCONNECTION_EVENT: 2590 if (msg.obj != null) { 2591 sb.append(" ").append((String) msg.obj); 2592 } 2593 sb.append(" nid=").append(msg.arg1); 2594 sb.append(" reason=").append(msg.arg2); 2595 if (mLastBssid != null) { 2596 sb.append(" lastbssid=").append(mLastBssid); 2597 } 2598 if (mWifiInfo.getFrequency() != -1) { 2599 sb.append(" freq=").append(mWifiInfo.getFrequency()); 2600 sb.append(" rssi=").append(mWifiInfo.getRssi()); 2601 } 2602 if (linkDebouncing) { 2603 sb.append(" debounce"); 2604 } 2605 break; 2606 case WifiMonitor.SSID_TEMP_DISABLED: 2607 case WifiMonitor.SSID_REENABLED: 2608 sb.append(" nid=").append(msg.arg1); 2609 if (msg.obj != null) { 2610 sb.append(" ").append((String) msg.obj); 2611 } 2612 config = getCurrentWifiConfiguration(); 2613 if (config != null) { 2614 WifiConfiguration.NetworkSelectionStatus netWorkSelectionStatus = 2615 config.getNetworkSelectionStatus(); 2616 sb.append(" cur=").append(config.configKey()); 2617 sb.append(" ajst=").append(netWorkSelectionStatus.getNetworkStatusString()); 2618 if (config.selfAdded) { 2619 sb.append(" selfAdded"); 2620 } 2621 if (config.status != 0) { 2622 sb.append(" st=").append(config.status); 2623 sb.append(" rs=").append( 2624 netWorkSelectionStatus.getNetworkDisableReasonString()); 2625 } 2626 if (config.lastConnected != 0) { 2627 now = System.currentTimeMillis(); 2628 sb.append(" lastconn=").append(now - config.lastConnected).append("(ms)"); 2629 } 2630 if (mLastBssid != null) { 2631 sb.append(" lastbssid=").append(mLastBssid); 2632 } 2633 if (mWifiInfo.getFrequency() != -1) { 2634 sb.append(" freq=").append(mWifiInfo.getFrequency()); 2635 sb.append(" rssi=").append(mWifiInfo.getRssi()); 2636 sb.append(" bssid=").append(mWifiInfo.getBSSID()); 2637 } 2638 } 2639 break; 2640 case CMD_RSSI_POLL: 2641 case CMD_UNWANTED_NETWORK: 2642 case WifiManager.RSSI_PKTCNT_FETCH: 2643 sb.append(" "); 2644 sb.append(Integer.toString(msg.arg1)); 2645 sb.append(" "); 2646 sb.append(Integer.toString(msg.arg2)); 2647 if (mWifiInfo.getSSID() != null) 2648 if (mWifiInfo.getSSID() != null) 2649 sb.append(" ").append(mWifiInfo.getSSID()); 2650 if (mWifiInfo.getBSSID() != null) 2651 sb.append(" ").append(mWifiInfo.getBSSID()); 2652 sb.append(" rssi=").append(mWifiInfo.getRssi()); 2653 sb.append(" f=").append(mWifiInfo.getFrequency()); 2654 sb.append(" sc=").append(mWifiInfo.score); 2655 sb.append(" link=").append(mWifiInfo.getLinkSpeed()); 2656 sb.append(String.format(" tx=%.1f,", mWifiInfo.txSuccessRate)); 2657 sb.append(String.format(" %.1f,", mWifiInfo.txRetriesRate)); 2658 sb.append(String.format(" %.1f ", mWifiInfo.txBadRate)); 2659 sb.append(String.format(" rx=%.1f", mWifiInfo.rxSuccessRate)); 2660 sb.append(String.format(" bcn=%d", mRunningBeaconCount)); 2661 report = reportOnTime(); 2662 if (report != null) { 2663 sb.append(" ").append(report); 2664 } 2665 if (mWifiScoreReport != null) { 2666 sb.append(mWifiScoreReport.getReport()); 2667 } 2668 if (mConnectedModeGScanOffloadStarted) { 2669 sb.append(" offload-started periodMilli " + mGScanPeriodMilli); 2670 } else { 2671 sb.append(" offload-stopped"); 2672 } 2673 break; 2674 case CMD_AUTO_CONNECT: 2675 case WifiManager.CONNECT_NETWORK: 2676 sb.append(" "); 2677 sb.append(Integer.toString(msg.arg1)); 2678 sb.append(" "); 2679 sb.append(Integer.toString(msg.arg2)); 2680 config = mWifiConfigManager.getWifiConfiguration(msg.arg1); 2681 if (config != null) { 2682 sb.append(" ").append(config.configKey()); 2683 if (config.visibility != null) { 2684 sb.append(" ").append(config.visibility.toString()); 2685 } 2686 } 2687 if (mTargetRoamBSSID != null) { 2688 sb.append(" ").append(mTargetRoamBSSID); 2689 } 2690 sb.append(" roam=").append(Boolean.toString(mAutoRoaming)); 2691 config = getCurrentWifiConfiguration(); 2692 if (config != null) { 2693 sb.append(config.configKey()); 2694 if (config.visibility != null) { 2695 sb.append(" ").append(config.visibility.toString()); 2696 } 2697 } 2698 break; 2699 case CMD_AUTO_ROAM: 2700 sb.append(" "); 2701 sb.append(Integer.toString(msg.arg1)); 2702 sb.append(" "); 2703 sb.append(Integer.toString(msg.arg2)); 2704 ScanResult result = (ScanResult) msg.obj; 2705 if (result != null) { 2706 now = System.currentTimeMillis(); 2707 sb.append(" bssid=").append(result.BSSID); 2708 sb.append(" rssi=").append(result.level); 2709 sb.append(" freq=").append(result.frequency); 2710 if (result.seen > 0 && result.seen < now) { 2711 sb.append(" seen=").append(now - result.seen); 2712 } else { 2713 // Somehow the timestamp for this scan result is inconsistent 2714 sb.append(" !seen=").append(result.seen); 2715 } 2716 } 2717 if (mTargetRoamBSSID != null) { 2718 sb.append(" ").append(mTargetRoamBSSID); 2719 } 2720 sb.append(" roam=").append(Boolean.toString(mAutoRoaming)); 2721 sb.append(" fail count=").append(Integer.toString(mRoamFailCount)); 2722 break; 2723 case CMD_ADD_OR_UPDATE_NETWORK: 2724 sb.append(" "); 2725 sb.append(Integer.toString(msg.arg1)); 2726 sb.append(" "); 2727 sb.append(Integer.toString(msg.arg2)); 2728 if (msg.obj != null) { 2729 config = (WifiConfiguration) msg.obj; 2730 sb.append(" ").append(config.configKey()); 2731 sb.append(" prio=").append(config.priority); 2732 sb.append(" status=").append(config.status); 2733 if (config.BSSID != null) { 2734 sb.append(" ").append(config.BSSID); 2735 } 2736 WifiConfiguration curConfig = getCurrentWifiConfiguration(); 2737 if (curConfig != null) { 2738 if (curConfig.configKey().equals(config.configKey())) { 2739 sb.append(" is current"); 2740 } else { 2741 sb.append(" current=").append(curConfig.configKey()); 2742 sb.append(" prio=").append(curConfig.priority); 2743 sb.append(" status=").append(curConfig.status); 2744 } 2745 } 2746 } 2747 break; 2748 case WifiManager.DISABLE_NETWORK: 2749 case CMD_ENABLE_NETWORK: 2750 sb.append(" "); 2751 sb.append(Integer.toString(msg.arg1)); 2752 sb.append(" "); 2753 sb.append(Integer.toString(msg.arg2)); 2754 key = mWifiConfigManager.getLastSelectedConfiguration(); 2755 if (key != null) { 2756 sb.append(" last=").append(key); 2757 } 2758 config = mWifiConfigManager.getWifiConfiguration(msg.arg1); 2759 if (config != null && (key == null || !config.configKey().equals(key))) { 2760 sb.append(" target=").append(key); 2761 } 2762 break; 2763 case CMD_GET_CONFIGURED_NETWORKS: 2764 sb.append(" "); 2765 sb.append(Integer.toString(msg.arg1)); 2766 sb.append(" "); 2767 sb.append(Integer.toString(msg.arg2)); 2768 sb.append(" num=").append(mWifiConfigManager.getConfiguredNetworksSize()); 2769 break; 2770 case DhcpClient.CMD_PRE_DHCP_ACTION: 2771 sb.append(" "); 2772 sb.append(Integer.toString(msg.arg1)); 2773 sb.append(" "); 2774 sb.append(Integer.toString(msg.arg2)); 2775 sb.append(" txpkts=").append(mWifiInfo.txSuccess); 2776 sb.append(",").append(mWifiInfo.txBad); 2777 sb.append(",").append(mWifiInfo.txRetries); 2778 break; 2779 case DhcpClient.CMD_POST_DHCP_ACTION: 2780 sb.append(" "); 2781 sb.append(Integer.toString(msg.arg1)); 2782 sb.append(" "); 2783 sb.append(Integer.toString(msg.arg2)); 2784 if (msg.arg1 == DhcpClient.DHCP_SUCCESS) { 2785 sb.append(" OK "); 2786 } else if (msg.arg1 == DhcpClient.DHCP_FAILURE) { 2787 sb.append(" FAIL "); 2788 } 2789 if (mLinkProperties != null) { 2790 sb.append(" "); 2791 sb.append(getLinkPropertiesSummary(mLinkProperties)); 2792 } 2793 break; 2794 case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED: 2795 sb.append(" "); 2796 sb.append(Integer.toString(msg.arg1)); 2797 sb.append(" "); 2798 sb.append(Integer.toString(msg.arg2)); 2799 if (msg.obj != null) { 2800 NetworkInfo info = (NetworkInfo) msg.obj; 2801 NetworkInfo.State state = info.getState(); 2802 NetworkInfo.DetailedState detailedState = info.getDetailedState(); 2803 if (state != null) { 2804 sb.append(" st=").append(state); 2805 } 2806 if (detailedState != null) { 2807 sb.append("/").append(detailedState); 2808 } 2809 } 2810 break; 2811 case CMD_IP_CONFIGURATION_LOST: 2812 int count = -1; 2813 WifiConfiguration c = getCurrentWifiConfiguration(); 2814 if (c != null) { 2815 count = c.getNetworkSelectionStatus().getDisableReasonCounter( 2816 WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE); 2817 } 2818 sb.append(" "); 2819 sb.append(Integer.toString(msg.arg1)); 2820 sb.append(" "); 2821 sb.append(Integer.toString(msg.arg2)); 2822 sb.append(" failures: "); 2823 sb.append(Integer.toString(count)); 2824 sb.append("/"); 2825 sb.append(Integer.toString(mWifiConfigManager.getMaxDhcpRetries())); 2826 if (mWifiInfo.getBSSID() != null) { 2827 sb.append(" ").append(mWifiInfo.getBSSID()); 2828 } 2829 sb.append(String.format(" bcn=%d", mRunningBeaconCount)); 2830 break; 2831 case CMD_UPDATE_LINKPROPERTIES: 2832 sb.append(" "); 2833 sb.append(Integer.toString(msg.arg1)); 2834 sb.append(" "); 2835 sb.append(Integer.toString(msg.arg2)); 2836 if (mLinkProperties != null) { 2837 sb.append(" "); 2838 sb.append(getLinkPropertiesSummary(mLinkProperties)); 2839 } 2840 break; 2841 case CMD_IP_REACHABILITY_LOST: 2842 if (msg.obj != null) { 2843 sb.append(" ").append((String) msg.obj); 2844 } 2845 break; 2846 case CMD_INSTALL_PACKET_FILTER: 2847 sb.append(" len=" + ((byte[])msg.obj).length); 2848 break; 2849 case CMD_SET_FALLBACK_PACKET_FILTERING: 2850 sb.append(" enabled=" + (boolean)msg.obj); 2851 break; 2852 case CMD_ROAM_WATCHDOG_TIMER: 2853 sb.append(" "); 2854 sb.append(Integer.toString(msg.arg1)); 2855 sb.append(" "); 2856 sb.append(Integer.toString(msg.arg2)); 2857 sb.append(" cur=").append(roamWatchdogCount); 2858 break; 2859 case CMD_DISCONNECTING_WATCHDOG_TIMER: 2860 sb.append(" "); 2861 sb.append(Integer.toString(msg.arg1)); 2862 sb.append(" "); 2863 sb.append(Integer.toString(msg.arg2)); 2864 sb.append(" cur=").append(disconnectingWatchdogCount); 2865 break; 2866 case CMD_START_RSSI_MONITORING_OFFLOAD: 2867 case CMD_STOP_RSSI_MONITORING_OFFLOAD: 2868 case CMD_RSSI_THRESHOLD_BREACH: 2869 sb.append(" rssi="); 2870 sb.append(Integer.toString(msg.arg1)); 2871 sb.append(" thresholds="); 2872 sb.append(Arrays.toString(mRssiRanges)); 2873 break; 2874 case CMD_USER_SWITCH: 2875 sb.append(" userId="); 2876 sb.append(Integer.toString(msg.arg1)); 2877 break; 2878 case CMD_IPV4_PROVISIONING_SUCCESS: 2879 sb.append(" "); 2880 if (msg.arg1 == DhcpClient.DHCP_SUCCESS) { 2881 sb.append("DHCP_OK"); 2882 } else if (msg.arg1 == CMD_STATIC_IP_SUCCESS) { 2883 sb.append("STATIC_OK"); 2884 } else { 2885 sb.append(Integer.toString(msg.arg1)); 2886 } 2887 break; 2888 case CMD_IPV4_PROVISIONING_FAILURE: 2889 sb.append(" "); 2890 if (msg.arg1 == DhcpClient.DHCP_FAILURE) { 2891 sb.append("DHCP_FAIL"); 2892 } else if (msg.arg1 == CMD_STATIC_IP_FAILURE) { 2893 sb.append("STATIC_FAIL"); 2894 } else { 2895 sb.append(Integer.toString(msg.arg1)); 2896 } 2897 break; 2898 default: 2899 sb.append(" "); 2900 sb.append(Integer.toString(msg.arg1)); 2901 sb.append(" "); 2902 sb.append(Integer.toString(msg.arg2)); 2903 break; 2904 } 2905 2906 return sb.toString(); 2907 } 2908 2909 private void handleScreenStateChanged(boolean screenOn) { 2910 mScreenOn = screenOn; 2911 if (DBG) { 2912 logd(" handleScreenStateChanged Enter: screenOn=" + screenOn 2913 + " mUserWantsSuspendOpt=" + mUserWantsSuspendOpt 2914 + " state " + getCurrentState().getName() 2915 + " suppState:" + mSupplicantStateTracker.getSupplicantStateName()); 2916 } 2917 enableRssiPolling(screenOn); 2918 if (mUserWantsSuspendOpt.get()) { 2919 int shouldReleaseWakeLock = 0; 2920 if (screenOn) { 2921 sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 0, shouldReleaseWakeLock); 2922 } else { 2923 if (isConnected()) { 2924 // Allow 2s for suspend optimizations to be set 2925 mSuspendWakeLock.acquire(2000); 2926 shouldReleaseWakeLock = 1; 2927 } 2928 sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 1, shouldReleaseWakeLock); 2929 } 2930 } 2931 mScreenBroadcastReceived.set(true); 2932 2933 getWifiLinkLayerStats(false); 2934 mOnTimeScreenStateChange = mOnTime; 2935 lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate; 2936 2937 mWifiMetrics.setScreenState(screenOn); 2938 2939 if (mWifiConnectivityManager != null) { 2940 mWifiConnectivityManager.handleScreenStateChanged(screenOn); 2941 } 2942 2943 if (DBG) log("handleScreenStateChanged Exit: " + screenOn); 2944 } 2945 2946 private void checkAndSetConnectivityInstance() { 2947 if (mCm == null) { 2948 mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 2949 } 2950 } 2951 2952 2953 /** 2954 * Set the frequency band from the system setting value, if any. 2955 */ 2956 private void setFrequencyBand() { 2957 int band = WifiManager.WIFI_FREQUENCY_BAND_AUTO; 2958 2959 if (mWifiNative.setBand(band)) { 2960 mFrequencyBand.set(band); 2961 if (mWifiConnectivityManager != null) { 2962 mWifiConnectivityManager.setUserPreferredBand(band); 2963 } 2964 if (DBG) { 2965 logd("done set frequency band " + band); 2966 } 2967 } else { 2968 loge("Failed to set frequency band " + band); 2969 } 2970 } 2971 2972 private void setSuspendOptimizationsNative(int reason, boolean enabled) { 2973 if (DBG) { 2974 log("setSuspendOptimizationsNative: " + reason + " " + enabled 2975 + " -want " + mUserWantsSuspendOpt.get() 2976 + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName() 2977 + " - " + Thread.currentThread().getStackTrace()[3].getMethodName() 2978 + " - " + Thread.currentThread().getStackTrace()[4].getMethodName() 2979 + " - " + Thread.currentThread().getStackTrace()[5].getMethodName()); 2980 } 2981 //mWifiNative.setSuspendOptimizations(enabled); 2982 2983 if (enabled) { 2984 mSuspendOptNeedsDisabled &= ~reason; 2985 /* None of dhcp, screen or highperf need it disabled and user wants it enabled */ 2986 if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) { 2987 if (DBG) { 2988 log("setSuspendOptimizationsNative do it " + reason + " " + enabled 2989 + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName() 2990 + " - " + Thread.currentThread().getStackTrace()[3].getMethodName() 2991 + " - " + Thread.currentThread().getStackTrace()[4].getMethodName() 2992 + " - " + Thread.currentThread().getStackTrace()[5].getMethodName()); 2993 } 2994 mWifiNative.setSuspendOptimizations(true); 2995 } 2996 } else { 2997 mSuspendOptNeedsDisabled |= reason; 2998 mWifiNative.setSuspendOptimizations(false); 2999 } 3000 } 3001 3002 private void setSuspendOptimizations(int reason, boolean enabled) { 3003 if (DBG) log("setSuspendOptimizations: " + reason + " " + enabled); 3004 if (enabled) { 3005 mSuspendOptNeedsDisabled &= ~reason; 3006 } else { 3007 mSuspendOptNeedsDisabled |= reason; 3008 } 3009 if (DBG) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled); 3010 } 3011 3012 private void setWifiState(int wifiState) { 3013 final int previousWifiState = mWifiState.get(); 3014 3015 try { 3016 if (wifiState == WIFI_STATE_ENABLED) { 3017 mBatteryStats.noteWifiOn(); 3018 } else if (wifiState == WIFI_STATE_DISABLED) { 3019 mBatteryStats.noteWifiOff(); 3020 } 3021 } catch (RemoteException e) { 3022 loge("Failed to note battery stats in wifi"); 3023 } 3024 3025 mWifiState.set(wifiState); 3026 3027 if (DBG) log("setWifiState: " + syncGetWifiStateByName()); 3028 3029 final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION); 3030 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3031 intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState); 3032 intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState); 3033 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3034 } 3035 3036 private void setWifiApState(int wifiApState, int reason) { 3037 final int previousWifiApState = mWifiApState.get(); 3038 3039 try { 3040 if (wifiApState == WIFI_AP_STATE_ENABLED) { 3041 mBatteryStats.noteWifiOn(); 3042 } else if (wifiApState == WIFI_AP_STATE_DISABLED) { 3043 mBatteryStats.noteWifiOff(); 3044 } 3045 } catch (RemoteException e) { 3046 loge("Failed to note battery stats in wifi"); 3047 } 3048 3049 // Update state 3050 mWifiApState.set(wifiApState); 3051 3052 if (DBG) log("setWifiApState: " + syncGetWifiApStateByName()); 3053 3054 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 3055 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3056 intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState); 3057 intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState); 3058 if (wifiApState == WifiManager.WIFI_AP_STATE_FAILED) { 3059 //only set reason number when softAP start failed 3060 intent.putExtra(WifiManager.EXTRA_WIFI_AP_FAILURE_REASON, reason); 3061 } 3062 3063 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3064 } 3065 3066 private void setScanResults() { 3067 mNumScanResultsKnown = 0; 3068 mNumScanResultsReturned = 0; 3069 3070 ArrayList<ScanDetail> scanResults = mWifiNative.getScanResults(); 3071 3072 if (scanResults.isEmpty()) { 3073 mScanResults = new ArrayList<>(); 3074 return; 3075 } 3076 3077 mWifiConfigManager.trimANQPCache(false); 3078 3079 boolean connected = mLastBssid != null; 3080 long activeBssid = 0L; 3081 if (connected) { 3082 try { 3083 activeBssid = Utils.parseMac(mLastBssid); 3084 } catch (IllegalArgumentException iae) { 3085 connected = false; 3086 } 3087 } 3088 3089 synchronized (mScanResultsLock) { 3090 ScanDetail activeScanDetail = null; 3091 mScanResults = scanResults; 3092 mNumScanResultsReturned = mScanResults.size(); 3093 for (ScanDetail resultDetail : mScanResults) { 3094 if (connected && resultDetail.getNetworkDetail().getBSSID() == activeBssid) { 3095 if (activeScanDetail == null 3096 || activeScanDetail.getNetworkDetail().getBSSID() != activeBssid 3097 || activeScanDetail.getNetworkDetail().getANQPElements() == null) { 3098 activeScanDetail = resultDetail; 3099 } 3100 } 3101 // Cache DTIM values parsed from the beacon frame Traffic Indication Map (TIM) 3102 // Information Element (IE), into the associated WifiConfigurations. Most of the 3103 // time there is no TIM IE in the scan result (Probe Response instead of Beacon 3104 // Frame), these scanResult DTIM's are negative and ignored. 3105 // <TODO> Cache these per BSSID, since dtim can change vary 3106 NetworkDetail networkDetail = resultDetail.getNetworkDetail(); 3107 if (networkDetail != null && networkDetail.getDtimInterval() > 0) { 3108 List<WifiConfiguration> associatedWifiConfigurations = 3109 mWifiConfigManager.getSavedNetworkFromScanDetail(resultDetail); 3110 if (associatedWifiConfigurations != null) { 3111 for (WifiConfiguration associatedConf : associatedWifiConfigurations) { 3112 if (associatedConf != null) { 3113 associatedConf.dtimInterval = networkDetail.getDtimInterval(); 3114 } 3115 } 3116 } 3117 } 3118 } 3119 mWifiConfigManager.setActiveScanDetail(activeScanDetail); 3120 } 3121 3122 if (linkDebouncing) { 3123 // If debouncing, we dont re-select a SSID or BSSID hence 3124 // there is no need to call the network selection code 3125 // in WifiAutoJoinController, instead, 3126 // just try to reconnect to the same SSID by triggering a roam 3127 // The third parameter 1 means roam not from network selection but debouncing 3128 sendMessage(CMD_AUTO_ROAM, mLastNetworkId, 1, null); 3129 } 3130 } 3131 3132 /* 3133 * Fetch RSSI, linkspeed, and frequency on current connection 3134 */ 3135 private void fetchRssiLinkSpeedAndFrequencyNative() { 3136 Integer newRssi = null; 3137 Integer newLinkSpeed = null; 3138 Integer newFrequency = null; 3139 3140 String signalPoll = mWifiNative.signalPoll(); 3141 3142 if (signalPoll != null) { 3143 String[] lines = signalPoll.split("\n"); 3144 for (String line : lines) { 3145 String[] prop = line.split("="); 3146 if (prop.length < 2) continue; 3147 try { 3148 if (prop[0].equals("RSSI")) { 3149 newRssi = Integer.parseInt(prop[1]); 3150 } else if (prop[0].equals("LINKSPEED")) { 3151 newLinkSpeed = Integer.parseInt(prop[1]); 3152 } else if (prop[0].equals("FREQUENCY")) { 3153 newFrequency = Integer.parseInt(prop[1]); 3154 } 3155 } catch (NumberFormatException e) { 3156 //Ignore, defaults on rssi and linkspeed are assigned 3157 } 3158 } 3159 } 3160 3161 if (DBG) { 3162 logd("fetchRssiLinkSpeedAndFrequencyNative rssi=" + newRssi + 3163 " linkspeed=" + newLinkSpeed + " freq=" + newFrequency); 3164 } 3165 3166 if (newRssi != null && newRssi > WifiInfo.INVALID_RSSI && newRssi < WifiInfo.MAX_RSSI) { 3167 // screen out invalid values 3168 /* some implementations avoid negative values by adding 256 3169 * so we need to adjust for that here. 3170 */ 3171 if (newRssi > 0) newRssi -= 256; 3172 mWifiInfo.setRssi(newRssi); 3173 /* 3174 * Log the rssi poll value in metrics 3175 */ 3176 mWifiMetrics.incrementRssiPollRssiCount(newRssi); 3177 /* 3178 * Rather then sending the raw RSSI out every time it 3179 * changes, we precalculate the signal level that would 3180 * be displayed in the status bar, and only send the 3181 * broadcast if that much more coarse-grained number 3182 * changes. This cuts down greatly on the number of 3183 * broadcasts, at the cost of not informing others 3184 * interested in RSSI of all the changes in signal 3185 * level. 3186 */ 3187 int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, WifiManager.RSSI_LEVELS); 3188 if (newSignalLevel != mLastSignalLevel) { 3189 updateCapabilities(getCurrentWifiConfiguration()); 3190 sendRssiChangeBroadcast(newRssi); 3191 } 3192 mLastSignalLevel = newSignalLevel; 3193 } else { 3194 mWifiInfo.setRssi(WifiInfo.INVALID_RSSI); 3195 updateCapabilities(getCurrentWifiConfiguration()); 3196 } 3197 3198 if (newLinkSpeed != null) { 3199 mWifiInfo.setLinkSpeed(newLinkSpeed); 3200 } 3201 if (newFrequency != null && newFrequency > 0) { 3202 if (ScanResult.is5GHz(newFrequency)) { 3203 mWifiConnectionStatistics.num5GhzConnected++; 3204 } 3205 if (ScanResult.is24GHz(newFrequency)) { 3206 mWifiConnectionStatistics.num24GhzConnected++; 3207 } 3208 mWifiInfo.setFrequency(newFrequency); 3209 } 3210 mWifiConfigManager.updateConfiguration(mWifiInfo); 3211 } 3212 3213 // Polling has completed, hence we wont have a score anymore 3214 private void cleanWifiScore() { 3215 mWifiInfo.txBadRate = 0; 3216 mWifiInfo.txSuccessRate = 0; 3217 mWifiInfo.txRetriesRate = 0; 3218 mWifiInfo.rxSuccessRate = 0; 3219 mWifiScoreReport = null; 3220 } 3221 3222 // Object holding most recent wifi score report and bad Linkspeed count 3223 WifiScoreReport mWifiScoreReport = null; 3224 3225 public double getTxPacketRate() { 3226 return mWifiInfo.txSuccessRate; 3227 } 3228 3229 public double getRxPacketRate() { 3230 return mWifiInfo.rxSuccessRate; 3231 } 3232 3233 /** 3234 * Fetch TX packet counters on current connection 3235 */ 3236 private void fetchPktcntNative(RssiPacketCountInfo info) { 3237 String pktcntPoll = mWifiNative.pktcntPoll(); 3238 3239 if (pktcntPoll != null) { 3240 String[] lines = pktcntPoll.split("\n"); 3241 for (String line : lines) { 3242 String[] prop = line.split("="); 3243 if (prop.length < 2) continue; 3244 try { 3245 if (prop[0].equals("TXGOOD")) { 3246 info.txgood = Integer.parseInt(prop[1]); 3247 } else if (prop[0].equals("TXBAD")) { 3248 info.txbad = Integer.parseInt(prop[1]); 3249 } 3250 } catch (NumberFormatException e) { 3251 // Ignore 3252 } 3253 } 3254 } 3255 } 3256 3257 private void updateLinkProperties(LinkProperties newLp) { 3258 if (DBG) { 3259 log("Link configuration changed for netId: " + mLastNetworkId 3260 + " old: " + mLinkProperties + " new: " + newLp); 3261 } 3262 // We own this instance of LinkProperties because IpManager passes us a copy. 3263 mLinkProperties = newLp; 3264 if (mNetworkAgent != null) { 3265 mNetworkAgent.sendLinkProperties(mLinkProperties); 3266 } 3267 3268 if (getNetworkDetailedState() == DetailedState.CONNECTED) { 3269 // If anything has changed and we're already connected, send out a notification. 3270 // TODO: Update all callers to use NetworkCallbacks and delete this. 3271 sendLinkConfigurationChangedBroadcast(); 3272 } 3273 3274 if (DBG) { 3275 StringBuilder sb = new StringBuilder(); 3276 sb.append("updateLinkProperties nid: " + mLastNetworkId); 3277 sb.append(" state: " + getNetworkDetailedState()); 3278 3279 if (mLinkProperties != null) { 3280 sb.append(" "); 3281 sb.append(getLinkPropertiesSummary(mLinkProperties)); 3282 } 3283 logd(sb.toString()); 3284 } 3285 } 3286 3287 /** 3288 * Clears all our link properties. 3289 */ 3290 private void clearLinkProperties() { 3291 // Clear the link properties obtained from DHCP. The only caller of this 3292 // function has already called IpManager#stop(), which clears its state. 3293 synchronized (mDhcpResultsLock) { 3294 if (mDhcpResults != null) { 3295 mDhcpResults.clear(); 3296 } 3297 } 3298 3299 // Now clear the merged link properties. 3300 mLinkProperties.clear(); 3301 if (mNetworkAgent != null) mNetworkAgent.sendLinkProperties(mLinkProperties); 3302 } 3303 3304 /** 3305 * try to update default route MAC address. 3306 */ 3307 private String updateDefaultRouteMacAddress(int timeout) { 3308 String address = null; 3309 for (RouteInfo route : mLinkProperties.getRoutes()) { 3310 if (route.isDefaultRoute() && route.hasGateway()) { 3311 InetAddress gateway = route.getGateway(); 3312 if (gateway instanceof Inet4Address) { 3313 if (DBG) { 3314 logd("updateDefaultRouteMacAddress found Ipv4 default :" 3315 + gateway.getHostAddress()); 3316 } 3317 address = macAddressFromRoute(gateway.getHostAddress()); 3318 /* The gateway's MAC address is known */ 3319 if ((address == null) && (timeout > 0)) { 3320 boolean reachable = false; 3321 try { 3322 reachable = gateway.isReachable(timeout); 3323 } catch (Exception e) { 3324 loge("updateDefaultRouteMacAddress exception reaching :" 3325 + gateway.getHostAddress()); 3326 3327 } finally { 3328 if (reachable == true) { 3329 3330 address = macAddressFromRoute(gateway.getHostAddress()); 3331 if (DBG) { 3332 logd("updateDefaultRouteMacAddress reachable (tried again) :" 3333 + gateway.getHostAddress() + " found " + address); 3334 } 3335 } 3336 } 3337 } 3338 if (address != null) { 3339 mWifiConfigManager.setDefaultGwMacAddress(mLastNetworkId, address); 3340 } 3341 } 3342 } 3343 } 3344 return address; 3345 } 3346 3347 void sendScanResultsAvailableBroadcast(boolean scanSucceeded) { 3348 Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 3349 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3350 intent.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, scanSucceeded); 3351 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3352 } 3353 3354 private void sendRssiChangeBroadcast(final int newRssi) { 3355 try { 3356 mBatteryStats.noteWifiRssiChanged(newRssi); 3357 } catch (RemoteException e) { 3358 // Won't happen. 3359 } 3360 Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION); 3361 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3362 intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi); 3363 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3364 } 3365 3366 private void sendNetworkStateChangeBroadcast(String bssid) { 3367 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION); 3368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3369 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo)); 3370 intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties)); 3371 if (bssid != null) 3372 intent.putExtra(WifiManager.EXTRA_BSSID, bssid); 3373 if (mNetworkInfo.getDetailedState() == DetailedState.VERIFYING_POOR_LINK || 3374 mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) { 3375 // We no longer report MAC address to third-parties and our code does 3376 // not rely on this broadcast, so just send the default MAC address. 3377 fetchRssiLinkSpeedAndFrequencyNative(); 3378 WifiInfo sentWifiInfo = new WifiInfo(mWifiInfo); 3379 sentWifiInfo.setMacAddress(WifiInfo.DEFAULT_MAC_ADDRESS); 3380 intent.putExtra(WifiManager.EXTRA_WIFI_INFO, sentWifiInfo); 3381 } 3382 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3383 } 3384 3385 private WifiInfo getWiFiInfoForUid(int uid) { 3386 if (Binder.getCallingUid() == Process.myUid()) { 3387 return mWifiInfo; 3388 } 3389 3390 WifiInfo result = new WifiInfo(mWifiInfo); 3391 result.setMacAddress(WifiInfo.DEFAULT_MAC_ADDRESS); 3392 3393 IBinder binder = mFacade.getService("package"); 3394 IPackageManager packageManager = IPackageManager.Stub.asInterface(binder); 3395 3396 try { 3397 if (packageManager.checkUidPermission(Manifest.permission.LOCAL_MAC_ADDRESS, 3398 uid) == PackageManager.PERMISSION_GRANTED) { 3399 result.setMacAddress(mWifiInfo.getMacAddress()); 3400 } 3401 } catch (RemoteException e) { 3402 Log.e(TAG, "Error checking receiver permission", e); 3403 } 3404 3405 return result; 3406 } 3407 3408 private void sendLinkConfigurationChangedBroadcast() { 3409 Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); 3410 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3411 intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties)); 3412 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3413 } 3414 3415 private void sendSupplicantConnectionChangedBroadcast(boolean connected) { 3416 Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); 3417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3418 intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected); 3419 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3420 } 3421 3422 /** 3423 * Record the detailed state of a network. 3424 * 3425 * @param state the new {@code DetailedState} 3426 */ 3427 private boolean setNetworkDetailedState(NetworkInfo.DetailedState state) { 3428 boolean hidden = false; 3429 3430 if (linkDebouncing || isRoaming()) { 3431 // There is generally a confusion in the system about colluding 3432 // WiFi Layer 2 state (as reported by supplicant) and the Network state 3433 // which leads to multiple confusion. 3434 // 3435 // If link is de-bouncing or roaming, we already have an IP address 3436 // as well we were connected and are doing L2 cycles of 3437 // reconnecting or renewing IP address to check that we still have it 3438 // This L2 link flapping should ne be reflected into the Network state 3439 // which is the state of the WiFi Network visible to Layer 3 and applications 3440 // Note that once debouncing and roaming are completed, we will 3441 // set the Network state to where it should be, or leave it as unchanged 3442 // 3443 hidden = true; 3444 } 3445 if (DBG) { 3446 log("setDetailed state, old =" 3447 + mNetworkInfo.getDetailedState() + " and new state=" + state 3448 + " hidden=" + hidden); 3449 } 3450 if (mNetworkInfo.getExtraInfo() != null && mWifiInfo.getSSID() != null 3451 && !mWifiInfo.getSSID().equals(WifiSsid.NONE)) { 3452 // Always indicate that SSID has changed 3453 if (!mNetworkInfo.getExtraInfo().equals(mWifiInfo.getSSID())) { 3454 if (DBG) { 3455 log("setDetailed state send new extra info" + mWifiInfo.getSSID()); 3456 } 3457 mNetworkInfo.setExtraInfo(mWifiInfo.getSSID()); 3458 sendNetworkStateChangeBroadcast(null); 3459 } 3460 } 3461 if (hidden == true) { 3462 return false; 3463 } 3464 3465 if (state != mNetworkInfo.getDetailedState()) { 3466 mNetworkInfo.setDetailedState(state, null, mWifiInfo.getSSID()); 3467 if (mNetworkAgent != null) { 3468 mNetworkAgent.sendNetworkInfo(mNetworkInfo); 3469 } 3470 sendNetworkStateChangeBroadcast(null); 3471 return true; 3472 } 3473 return false; 3474 } 3475 3476 private DetailedState getNetworkDetailedState() { 3477 return mNetworkInfo.getDetailedState(); 3478 } 3479 3480 private SupplicantState handleSupplicantStateChange(Message message) { 3481 StateChangeResult stateChangeResult = (StateChangeResult) message.obj; 3482 SupplicantState state = stateChangeResult.state; 3483 // Supplicant state change 3484 // [31-13] Reserved for future use 3485 // [8 - 0] Supplicant state (as defined in SupplicantState.java) 3486 // 50023 supplicant_state_changed (custom|1|5) 3487 mWifiInfo.setSupplicantState(state); 3488 // If we receive a supplicant state change with an empty SSID, 3489 // this implies that wpa_supplicant is already disconnected. 3490 // We should pretend we are still connected when linkDebouncing is on. 3491 if ((stateChangeResult.wifiSsid == null 3492 || stateChangeResult.wifiSsid.toString().isEmpty()) && linkDebouncing) { 3493 return state; 3494 } 3495 // Network id is only valid when we start connecting 3496 if (SupplicantState.isConnecting(state)) { 3497 mWifiInfo.setNetworkId(stateChangeResult.networkId); 3498 } else { 3499 mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID); 3500 } 3501 3502 mWifiInfo.setBSSID(stateChangeResult.BSSID); 3503 3504 if (mWhiteListedSsids != null 3505 && mWhiteListedSsids.length > 0 3506 && stateChangeResult.wifiSsid != null) { 3507 String SSID = stateChangeResult.wifiSsid.toString(); 3508 String currentSSID = mWifiInfo.getSSID(); 3509 if (SSID != null && currentSSID != null && !SSID.equals(WifiSsid.NONE)) { 3510 // Remove quote before comparing 3511 if (SSID.length() >= 2 && SSID.charAt(0) == '"' 3512 && SSID.charAt(SSID.length() - 1) == '"') { 3513 SSID = SSID.substring(1, SSID.length() - 1); 3514 } 3515 if (currentSSID.length() >= 2 && currentSSID.charAt(0) == '"' 3516 && currentSSID.charAt(currentSSID.length() - 1) == '"') { 3517 currentSSID = currentSSID.substring(1, currentSSID.length() - 1); 3518 } 3519 if ((!SSID.equals(currentSSID)) && (getCurrentState() == mConnectedState)) { 3520 lastConnectAttemptTimestamp = System.currentTimeMillis(); 3521 targetWificonfiguration = 3522 mWifiConfigManager.getWifiConfiguration(mWifiInfo.getNetworkId()); 3523 transitionTo(mRoamingState); 3524 } 3525 } 3526 } 3527 3528 mWifiInfo.setSSID(stateChangeResult.wifiSsid); 3529 mWifiInfo.setEphemeral(mWifiConfigManager.isEphemeral(mWifiInfo.getNetworkId())); 3530 if (!mWifiInfo.getMeteredHint()) { // don't override the value if already set. 3531 mWifiInfo.setMeteredHint(mWifiConfigManager.getMeteredHint(mWifiInfo.getNetworkId())); 3532 } 3533 3534 mSupplicantStateTracker.sendMessage(Message.obtain(message)); 3535 3536 return state; 3537 } 3538 3539 /** 3540 * Resets the Wi-Fi Connections by clearing any state, resetting any sockets 3541 * using the interface, stopping DHCP & disabling interface 3542 */ 3543 private void handleNetworkDisconnect() { 3544 if (DBG) log("handleNetworkDisconnect: Stopping DHCP and clearing IP" 3545 + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName() 3546 + " - " + Thread.currentThread().getStackTrace()[3].getMethodName() 3547 + " - " + Thread.currentThread().getStackTrace()[4].getMethodName() 3548 + " - " + Thread.currentThread().getStackTrace()[5].getMethodName()); 3549 3550 stopRssiMonitoringOffload(); 3551 3552 clearCurrentConfigBSSID("handleNetworkDisconnect"); 3553 3554 stopIpManager(); 3555 3556 /* Reset data structures */ 3557 mWifiScoreReport = null; 3558 mWifiInfo.reset(); 3559 linkDebouncing = false; 3560 /* Reset roaming parameters */ 3561 mAutoRoaming = false; 3562 3563 setNetworkDetailedState(DetailedState.DISCONNECTED); 3564 if (mNetworkAgent != null) { 3565 mNetworkAgent.sendNetworkInfo(mNetworkInfo); 3566 mNetworkAgent = null; 3567 } 3568 mWifiConfigManager.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED); 3569 3570 /* Clear network properties */ 3571 clearLinkProperties(); 3572 3573 /* Cend event to CM & network change broadcast */ 3574 sendNetworkStateChangeBroadcast(mLastBssid); 3575 3576 /* Cancel auto roam requests */ 3577 autoRoamSetBSSID(mLastNetworkId, "any"); 3578 mLastBssid = null; 3579 registerDisconnected(); 3580 mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID; 3581 } 3582 3583 private void handleSupplicantConnectionLoss(boolean killSupplicant) { 3584 /* Socket connection can be lost when we do a graceful shutdown 3585 * or when the driver is hung. Ensure supplicant is stopped here. 3586 */ 3587 if (killSupplicant) { 3588 mWifiMonitor.killSupplicant(mP2pSupported); 3589 } 3590 mWifiNative.closeSupplicantConnection(); 3591 sendSupplicantConnectionChangedBroadcast(false); 3592 setWifiState(WIFI_STATE_DISABLED); 3593 } 3594 3595 void handlePreDhcpSetup() { 3596 if (!mBluetoothConnectionActive) { 3597 /* 3598 * There are problems setting the Wi-Fi driver's power 3599 * mode to active when bluetooth coexistence mode is 3600 * enabled or sense. 3601 * <p> 3602 * We set Wi-Fi to active mode when 3603 * obtaining an IP address because we've found 3604 * compatibility issues with some routers with low power 3605 * mode. 3606 * <p> 3607 * In order for this active power mode to properly be set, 3608 * we disable coexistence mode until we're done with 3609 * obtaining an IP address. One exception is if we 3610 * are currently connected to a headset, since disabling 3611 * coexistence would interrupt that connection. 3612 */ 3613 // Disable the coexistence mode 3614 mWifiNative.setBluetoothCoexistenceMode( 3615 mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED); 3616 } 3617 3618 // Disable power save and suspend optimizations during DHCP 3619 // Note: The order here is important for now. Brcm driver changes 3620 // power settings when we control suspend mode optimizations. 3621 // TODO: Remove this comment when the driver is fixed. 3622 setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false); 3623 mWifiNative.setPowerSave(false); 3624 3625 // Update link layer stats 3626 getWifiLinkLayerStats(false); 3627 3628 /* P2p discovery breaks dhcp, shut it down in order to get through this */ 3629 Message msg = new Message(); 3630 msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY; 3631 msg.arg1 = WifiP2pServiceImpl.ENABLED; 3632 msg.arg2 = DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE; 3633 msg.obj = WifiStateMachine.this; 3634 mWifiP2pChannel.sendMessage(msg); 3635 } 3636 3637 void handlePostDhcpSetup() { 3638 /* Restore power save and suspend optimizations */ 3639 setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true); 3640 mWifiNative.setPowerSave(true); 3641 3642 mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, 3643 WifiP2pServiceImpl.DISABLED); 3644 3645 // Set the coexistence mode back to its default value 3646 mWifiNative.setBluetoothCoexistenceMode( 3647 mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE); 3648 } 3649 3650 /** 3651 * Inform other components (WifiMetrics, WifiLogger, etc.) that the current connection attempt 3652 * has concluded. 3653 */ 3654 private void reportConnectionAttemptEnd(int level2FailureCode, int connectivityFailureCode) { 3655 mWifiMetrics.endConnectionEvent(level2FailureCode, connectivityFailureCode); 3656 switch (level2FailureCode) { 3657 case WifiMetrics.ConnectionEvent.FAILURE_NONE: 3658 case WifiMetrics.ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT: 3659 // WifiLogger doesn't care about success, or pre-empted connections. 3660 break; 3661 default: 3662 mWifiLogger.reportConnectionFailure(); 3663 } 3664 } 3665 3666 private void handleIPv4Success(DhcpResults dhcpResults) { 3667 if (DBG) { 3668 logd("handleIPv4Success <" + dhcpResults.toString() + ">"); 3669 logd("link address " + dhcpResults.ipAddress); 3670 } 3671 3672 Inet4Address addr; 3673 synchronized (mDhcpResultsLock) { 3674 mDhcpResults = dhcpResults; 3675 addr = (Inet4Address) dhcpResults.ipAddress.getAddress(); 3676 } 3677 3678 if (isRoaming()) { 3679 int previousAddress = mWifiInfo.getIpAddress(); 3680 int newAddress = NetworkUtils.inetAddressToInt(addr); 3681 if (previousAddress != newAddress) { 3682 logd("handleIPv4Success, roaming and address changed" + 3683 mWifiInfo + " got: " + addr); 3684 } 3685 } 3686 mWifiInfo.setInetAddress(addr); 3687 if (!mWifiInfo.getMeteredHint()) { // don't override the value if already set. 3688 mWifiInfo.setMeteredHint(dhcpResults.hasMeteredHint()); 3689 updateCapabilities(getCurrentWifiConfiguration()); 3690 } 3691 } 3692 3693 private void handleSuccessfulIpConfiguration() { 3694 mLastSignalLevel = -1; // Force update of signal strength 3695 WifiConfiguration c = getCurrentWifiConfiguration(); 3696 if (c != null) { 3697 // Reset IP failure tracking 3698 c.getNetworkSelectionStatus().clearDisableReasonCounter( 3699 WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE); 3700 3701 // Tell the framework whether the newly connected network is trusted or untrusted. 3702 updateCapabilities(c); 3703 } 3704 if (c != null) { 3705 ScanResult result = getCurrentScanResult(); 3706 if (result == null) { 3707 logd("WifiStateMachine: handleSuccessfulIpConfiguration and no scan results" + 3708 c.configKey()); 3709 } else { 3710 // Clear the per BSSID failure count 3711 result.numIpConfigFailures = 0; 3712 // Clear the WHOLE BSSID blacklist, which means supplicant is free to retry 3713 // any BSSID, even though it may already have a non zero ip failure count, 3714 // this will typically happen if the user walks away and come back to his arrea 3715 // TODO: implement blacklisting based on a timer, i.e. keep BSSID blacklisted 3716 // in supplicant for a couple of hours or a day 3717 mWifiConfigManager.clearBssidBlacklist(); 3718 } 3719 } 3720 } 3721 3722 private void handleIPv4Failure() { 3723 // TODO: Move this to provisioning failure, not DHCP failure. 3724 // DHCPv4 failure is expected on an IPv6-only network. 3725 mWifiLogger.captureBugReportData(WifiLogger.REPORT_REASON_DHCP_FAILURE); 3726 if (DBG) { 3727 int count = -1; 3728 WifiConfiguration config = getCurrentWifiConfiguration(); 3729 if (config != null) { 3730 count = config.getNetworkSelectionStatus().getDisableReasonCounter( 3731 WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE); 3732 } 3733 log("DHCP failure count=" + count); 3734 } 3735 reportConnectionAttemptEnd( 3736 WifiMetrics.ConnectionEvent.FAILURE_DHCP, 3737 WifiMetricsProto.ConnectionEvent.HLF_DHCP); 3738 synchronized(mDhcpResultsLock) { 3739 if (mDhcpResults != null) { 3740 mDhcpResults.clear(); 3741 } 3742 } 3743 if (DBG) { 3744 logd("handleIPv4Failure"); 3745 } 3746 } 3747 3748 private void handleIpConfigurationLost() { 3749 mWifiInfo.setInetAddress(null); 3750 mWifiInfo.setMeteredHint(false); 3751 3752 mWifiConfigManager.updateNetworkSelectionStatus(mLastNetworkId, 3753 WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE); 3754 3755 /* DHCP times out after about 30 seconds, we do a 3756 * disconnect thru supplicant, we will let autojoin retry connecting to the network 3757 */ 3758 mWifiNative.disconnect(); 3759 } 3760 3761 // TODO: De-duplicated this and handleIpConfigurationLost(). 3762 private void handleIpReachabilityLost() { 3763 mWifiInfo.setInetAddress(null); 3764 mWifiInfo.setMeteredHint(false); 3765 3766 // TODO: Determine whether to call some form of mWifiConfigManager.handleSSIDStateChange(). 3767 3768 // Disconnect via supplicant, and let autojoin retry connecting to the network. 3769 mWifiNative.disconnect(); 3770 } 3771 3772 private int convertFrequencyToChannelNumber(int frequency) { 3773 if (frequency >= 2412 && frequency <= 2484) { 3774 return (frequency -2412) / 5 + 1; 3775 } else if (frequency >= 5170 && frequency <=5825) { 3776 //DFS is included 3777 return (frequency -5170) / 5 + 34; 3778 } else { 3779 return 0; 3780 } 3781 } 3782 3783 private int chooseApChannel(int apBand) { 3784 int apChannel; 3785 int[] channel; 3786 3787 if (apBand == 0) { 3788 ArrayList<Integer> allowed2GChannel = 3789 mWifiApConfigStore.getAllowed2GChannel(); 3790 if (allowed2GChannel == null || allowed2GChannel.size() == 0) { 3791 //most safe channel to use 3792 if (DBG) { 3793 Log.d(TAG, "No specified 2G allowed channel list"); 3794 } 3795 apChannel = 6; 3796 } else { 3797 int index = mRandom.nextInt(allowed2GChannel.size()); 3798 apChannel = allowed2GChannel.get(index).intValue(); 3799 } 3800 } else { 3801 //5G without DFS 3802 channel = mWifiNative.getChannelsForBand(2); 3803 if (channel != null && channel.length > 0) { 3804 apChannel = channel[mRandom.nextInt(channel.length)]; 3805 apChannel = convertFrequencyToChannelNumber(apChannel); 3806 } else { 3807 Log.e(TAG, "SoftAp do not get available channel list"); 3808 apChannel = 0; 3809 } 3810 } 3811 3812 if (DBG) { 3813 Log.d(TAG, "SoftAp set on channel " + apChannel); 3814 } 3815 3816 return apChannel; 3817 } 3818 3819 /* Driver/firmware setup for soft AP. */ 3820 private boolean setupDriverForSoftAp() { 3821 if (!mWifiNative.loadDriver()) { 3822 Log.e(TAG, "Failed to load driver for softap"); 3823 return false; 3824 } 3825 3826 int index = mWifiNative.queryInterfaceIndex(mInterfaceName); 3827 if (index != -1) { 3828 if (!mWifiNative.setInterfaceUp(false)) { 3829 Log.e(TAG, "toggleInterface failed"); 3830 return false; 3831 } 3832 } else { 3833 if (DBG) Log.d(TAG, "No interfaces to bring down"); 3834 } 3835 3836 try { 3837 mNwService.wifiFirmwareReload(mInterfaceName, "AP"); 3838 if (DBG) Log.d(TAG, "Firmware reloaded in AP mode"); 3839 } catch (Exception e) { 3840 Log.e(TAG, "Failed to reload AP firmware " + e); 3841 } 3842 3843 if (!mWifiNative.startHal()) { 3844 /* starting HAL is optional */ 3845 Log.e(TAG, "Failed to start HAL"); 3846 } 3847 return true; 3848 } 3849 3850 private byte[] macAddressFromString(String macString) { 3851 String[] macBytes = macString.split(":"); 3852 if (macBytes.length != 6) { 3853 throw new IllegalArgumentException("MAC address should be 6 bytes long!"); 3854 } 3855 byte[] mac = new byte[6]; 3856 for (int i = 0; i < macBytes.length; i++) { 3857 Integer hexVal = Integer.parseInt(macBytes[i], 16); 3858 mac[i] = hexVal.byteValue(); 3859 } 3860 return mac; 3861 } 3862 3863 /* 3864 * Read a MAC address in /proc/arp/table, used by WifistateMachine 3865 * so as to record MAC address of default gateway. 3866 **/ 3867 private String macAddressFromRoute(String ipAddress) { 3868 String macAddress = null; 3869 BufferedReader reader = null; 3870 try { 3871 reader = new BufferedReader(new FileReader("/proc/net/arp")); 3872 3873 // Skip over the line bearing colum titles 3874 String line = reader.readLine(); 3875 3876 while ((line = reader.readLine()) != null) { 3877 String[] tokens = line.split("[ ]+"); 3878 if (tokens.length < 6) { 3879 continue; 3880 } 3881 3882 // ARP column format is 3883 // Address HWType HWAddress Flags Mask IFace 3884 String ip = tokens[0]; 3885 String mac = tokens[3]; 3886 3887 if (ipAddress.equals(ip)) { 3888 macAddress = mac; 3889 break; 3890 } 3891 } 3892 3893 if (macAddress == null) { 3894 loge("Did not find remoteAddress {" + ipAddress + "} in " + 3895 "/proc/net/arp"); 3896 } 3897 3898 } catch (FileNotFoundException e) { 3899 loge("Could not open /proc/net/arp to lookup mac address"); 3900 } catch (IOException e) { 3901 loge("Could not read /proc/net/arp to lookup mac address"); 3902 } finally { 3903 try { 3904 if (reader != null) { 3905 reader.close(); 3906 } 3907 } catch (IOException e) { 3908 // Do nothing 3909 } 3910 } 3911 return macAddress; 3912 3913 } 3914 3915 private class WifiNetworkFactory extends NetworkFactory { 3916 public WifiNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities f) { 3917 super(l, c, TAG, f); 3918 } 3919 3920 @Override 3921 protected void needNetworkFor(NetworkRequest networkRequest, int score) { 3922 ++mConnectionRequests; 3923 } 3924 3925 @Override 3926 protected void releaseNetworkFor(NetworkRequest networkRequest) { 3927 --mConnectionRequests; 3928 } 3929 3930 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3931 pw.println("mConnectionRequests " + mConnectionRequests); 3932 } 3933 3934 } 3935 3936 private class UntrustedWifiNetworkFactory extends NetworkFactory { 3937 private int mUntrustedReqCount; 3938 3939 public UntrustedWifiNetworkFactory(Looper l, Context c, String tag, NetworkCapabilities f) { 3940 super(l, c, tag, f); 3941 } 3942 3943 @Override 3944 protected void needNetworkFor(NetworkRequest networkRequest, int score) { 3945 if (!networkRequest.networkCapabilities.hasCapability( 3946 NetworkCapabilities.NET_CAPABILITY_TRUSTED)) { 3947 if (++mUntrustedReqCount == 1) { 3948 if (mWifiConnectivityManager != null) { 3949 mWifiConnectivityManager.setUntrustedConnectionAllowed(true); 3950 } 3951 } 3952 } 3953 } 3954 3955 @Override 3956 protected void releaseNetworkFor(NetworkRequest networkRequest) { 3957 if (!networkRequest.networkCapabilities.hasCapability( 3958 NetworkCapabilities.NET_CAPABILITY_TRUSTED)) { 3959 if (--mUntrustedReqCount == 0) { 3960 if (mWifiConnectivityManager != null) { 3961 mWifiConnectivityManager.setUntrustedConnectionAllowed(false); 3962 } 3963 } 3964 } 3965 } 3966 3967 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3968 pw.println("mUntrustedReqCount " + mUntrustedReqCount); 3969 } 3970 } 3971 3972 void maybeRegisterNetworkFactory() { 3973 if (mNetworkFactory == null) { 3974 checkAndSetConnectivityInstance(); 3975 if (mCm != null) { 3976 mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext, 3977 NETWORKTYPE, mNetworkCapabilitiesFilter); 3978 mNetworkFactory.setScoreFilter(60); 3979 mNetworkFactory.register(); 3980 3981 // We can't filter untrusted network in the capabilities filter because a trusted 3982 // network would still satisfy a request that accepts untrusted ones. 3983 mUntrustedNetworkFactory = new UntrustedWifiNetworkFactory(getHandler().getLooper(), 3984 mContext, NETWORKTYPE_UNTRUSTED, mNetworkCapabilitiesFilter); 3985 mUntrustedNetworkFactory.setScoreFilter(Integer.MAX_VALUE); 3986 mUntrustedNetworkFactory.register(); 3987 } 3988 } 3989 } 3990 3991 /******************************************************** 3992 * HSM states 3993 *******************************************************/ 3994 3995 class DefaultState extends State { 3996 @Override 3997 public boolean processMessage(Message message) { 3998 logStateAndMessage(message, this); 3999 4000 switch (message.what) { 4001 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { 4002 AsyncChannel ac = (AsyncChannel) message.obj; 4003 if (ac == mWifiP2pChannel) { 4004 if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 4005 mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 4006 } else { 4007 loge("WifiP2pService connection failure, error=" + message.arg1); 4008 } 4009 } else { 4010 loge("got HALF_CONNECTED for unknown channel"); 4011 } 4012 break; 4013 } 4014 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 4015 AsyncChannel ac = (AsyncChannel) message.obj; 4016 if (ac == mWifiP2pChannel) { 4017 loge("WifiP2pService channel lost, message.arg1 =" + message.arg1); 4018 //TODO: Re-establish connection to state machine after a delay 4019 // mWifiP2pChannel.connect(mContext, getHandler(), 4020 // mWifiP2pManager.getMessenger()); 4021 } 4022 break; 4023 } 4024 case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE: 4025 mBluetoothConnectionActive = (message.arg1 != 4026 BluetoothAdapter.STATE_DISCONNECTED); 4027 break; 4028 /* Synchronous call returns */ 4029 case CMD_PING_SUPPLICANT: 4030 case CMD_ENABLE_NETWORK: 4031 case CMD_ADD_OR_UPDATE_NETWORK: 4032 case CMD_REMOVE_NETWORK: 4033 case CMD_SAVE_CONFIG: 4034 replyToMessage(message, message.what, FAILURE); 4035 break; 4036 case CMD_GET_CAPABILITY_FREQ: 4037 replyToMessage(message, message.what, null); 4038 break; 4039 case CMD_GET_CONFIGURED_NETWORKS: 4040 replyToMessage(message, message.what, (List<WifiConfiguration>) null); 4041 break; 4042 case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS: 4043 replyToMessage(message, message.what, (List<WifiConfiguration>) null); 4044 break; 4045 case CMD_ENABLE_RSSI_POLL: 4046 mEnableRssiPolling = (message.arg1 == 1); 4047 break; 4048 case CMD_SET_HIGH_PERF_MODE: 4049 if (message.arg1 == 1) { 4050 setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, false); 4051 } else { 4052 setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, true); 4053 } 4054 break; 4055 case CMD_BOOT_COMPLETED: 4056 maybeRegisterNetworkFactory(); 4057 break; 4058 case CMD_SCREEN_STATE_CHANGED: 4059 handleScreenStateChanged(message.arg1 != 0); 4060 break; 4061 /* Discard */ 4062 case CMD_START_SCAN: 4063 messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; 4064 break; 4065 case CMD_START_SUPPLICANT: 4066 case CMD_STOP_SUPPLICANT: 4067 case CMD_STOP_SUPPLICANT_FAILED: 4068 case CMD_START_DRIVER: 4069 case CMD_STOP_DRIVER: 4070 case CMD_DRIVER_START_TIMED_OUT: 4071 case CMD_START_AP: 4072 case CMD_START_AP_FAILURE: 4073 case CMD_STOP_AP: 4074 case CMD_AP_STOPPED: 4075 case CMD_DISCONNECT: 4076 case CMD_RECONNECT: 4077 case CMD_REASSOCIATE: 4078 case CMD_RELOAD_TLS_AND_RECONNECT: 4079 case WifiMonitor.SUP_CONNECTION_EVENT: 4080 case WifiMonitor.SUP_DISCONNECTION_EVENT: 4081 case WifiMonitor.NETWORK_CONNECTION_EVENT: 4082 case WifiMonitor.NETWORK_DISCONNECTION_EVENT: 4083 case WifiMonitor.SCAN_RESULTS_EVENT: 4084 case WifiMonitor.SCAN_FAILED_EVENT: 4085 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 4086 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: 4087 case WifiMonitor.ASSOCIATION_REJECTION_EVENT: 4088 case WifiMonitor.WPS_OVERLAP_EVENT: 4089 case CMD_BLACKLIST_NETWORK: 4090 case CMD_CLEAR_BLACKLIST: 4091 case CMD_SET_OPERATIONAL_MODE: 4092 case CMD_SET_FREQUENCY_BAND: 4093 case CMD_RSSI_POLL: 4094 case CMD_ENABLE_ALL_NETWORKS: 4095 case DhcpClient.CMD_PRE_DHCP_ACTION: 4096 case DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE: 4097 case DhcpClient.CMD_POST_DHCP_ACTION: 4098 case CMD_NO_NETWORKS_PERIODIC_SCAN: 4099 case CMD_DISABLE_P2P_RSP: 4100 case WifiMonitor.SUP_REQUEST_IDENTITY: 4101 case CMD_TEST_NETWORK_DISCONNECT: 4102 case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER: 4103 case WifiMonitor.SUP_REQUEST_SIM_AUTH: 4104 case CMD_TARGET_BSSID: 4105 case CMD_AUTO_CONNECT: 4106 case CMD_AUTO_ROAM: 4107 case CMD_AUTO_SAVE_NETWORK: 4108 case CMD_ASSOCIATED_BSSID: 4109 case CMD_UNWANTED_NETWORK: 4110 case CMD_DISCONNECTING_WATCHDOG_TIMER: 4111 case CMD_ROAM_WATCHDOG_TIMER: 4112 case CMD_DISABLE_EPHEMERAL_NETWORK: 4113 case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION: 4114 messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; 4115 break; 4116 case CMD_SET_SUSPEND_OPT_ENABLED: 4117 if (message.arg1 == 1) { 4118 if (message.arg2 == 1) { 4119 mSuspendWakeLock.release(); 4120 } 4121 setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, true); 4122 } else { 4123 setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, false); 4124 } 4125 break; 4126 case WifiMonitor.DRIVER_HUNG_EVENT: 4127 setSupplicantRunning(false); 4128 setSupplicantRunning(true); 4129 break; 4130 case WifiManager.CONNECT_NETWORK: 4131 replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED, 4132 WifiManager.BUSY); 4133 break; 4134 case WifiManager.FORGET_NETWORK: 4135 replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED, 4136 WifiManager.BUSY); 4137 break; 4138 case WifiManager.SAVE_NETWORK: 4139 messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; 4140 replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, 4141 WifiManager.BUSY); 4142 break; 4143 case WifiManager.START_WPS: 4144 replyToMessage(message, WifiManager.WPS_FAILED, 4145 WifiManager.BUSY); 4146 break; 4147 case WifiManager.CANCEL_WPS: 4148 replyToMessage(message, WifiManager.CANCEL_WPS_FAILED, 4149 WifiManager.BUSY); 4150 break; 4151 case WifiManager.DISABLE_NETWORK: 4152 replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED, 4153 WifiManager.BUSY); 4154 break; 4155 case WifiManager.RSSI_PKTCNT_FETCH: 4156 replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED, 4157 WifiManager.BUSY); 4158 break; 4159 case CMD_GET_SUPPORTED_FEATURES: 4160 int featureSet = mWifiNative.getSupportedFeatureSet(); 4161 replyToMessage(message, message.what, featureSet); 4162 break; 4163 case CMD_FIRMWARE_ALERT: 4164 if (mWifiLogger != null) { 4165 byte[] buffer = (byte[])message.obj; 4166 mWifiLogger.captureAlertData(message.arg1, buffer); 4167 } 4168 break; 4169 case CMD_GET_LINK_LAYER_STATS: 4170 // Not supported hence reply with error message 4171 replyToMessage(message, message.what, null); 4172 break; 4173 case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED: 4174 NetworkInfo info = (NetworkInfo) message.obj; 4175 mP2pConnected.set(info.isConnected()); 4176 break; 4177 case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST: 4178 mTemporarilyDisconnectWifi = (message.arg1 == 1); 4179 replyToMessage(message, WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE); 4180 break; 4181 /* Link configuration (IP address, DNS, ...) changes notified via netlink */ 4182 case CMD_UPDATE_LINKPROPERTIES: 4183 updateLinkProperties((LinkProperties) message.obj); 4184 break; 4185 case CMD_GET_MATCHING_CONFIG: 4186 replyToMessage(message, message.what); 4187 break; 4188 case CMD_IP_CONFIGURATION_SUCCESSFUL: 4189 case CMD_IP_CONFIGURATION_LOST: 4190 case CMD_IP_REACHABILITY_LOST: 4191 messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; 4192 break; 4193 case CMD_GET_CONNECTION_STATISTICS: 4194 replyToMessage(message, message.what, mWifiConnectionStatistics); 4195 break; 4196 case CMD_REMOVE_APP_CONFIGURATIONS: 4197 deferMessage(message); 4198 break; 4199 case CMD_REMOVE_USER_CONFIGURATIONS: 4200 deferMessage(message); 4201 break; 4202 case CMD_START_IP_PACKET_OFFLOAD: 4203 if (mNetworkAgent != null) mNetworkAgent.onPacketKeepaliveEvent( 4204 message.arg1, 4205 ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK); 4206 break; 4207 case CMD_STOP_IP_PACKET_OFFLOAD: 4208 if (mNetworkAgent != null) mNetworkAgent.onPacketKeepaliveEvent( 4209 message.arg1, 4210 ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK); 4211 break; 4212 case CMD_START_RSSI_MONITORING_OFFLOAD: 4213