diff options
Diffstat (limited to 'service/java/com/android/server/wifi/WifiStateMachine.java')
-rw-r--r-- | service/java/com/android/server/wifi/WifiStateMachine.java | 513 |
1 files changed, 448 insertions, 65 deletions
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 7773cb9e4..8afbad3c5 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -197,6 +197,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno private DummyWifiLogger mWifiLogger; private WifiApConfigStore mWifiApConfigStore; private final boolean mP2pSupported; + private boolean mIbssSupported; private final AtomicBoolean mP2pConnected = new AtomicBoolean(false); private boolean mTemporarilyDisconnectWifi = false; private final String mPrimaryDeviceType; @@ -212,11 +213,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno private int mNumScanResultsReturned; private boolean mScreenOn = false; + + private boolean mIsWiFiIpReachabilityEnabled ; + private int mCurrentAssociateNetworkId = -1; + /* Chipset supports background scan */ private final boolean mBackgroundScanSupported; private final String mInterfaceName; + /* The interface for dhcp to act on */ + private final String mDataInterfaceName; /* Tethering interface could be separate from wlan interface */ private String mTetherInterfaceName; @@ -231,6 +238,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno private boolean mEnableAssociatedNetworkSwitchingInDevSettings = true; private boolean mHalBasedPnoEnableInDevSettings = false; + /* Tracks sequence number on a periodic scan message for PNO failure */ + private int mPnoPeriodicScanToken = 0; private int mHalFeatureSet = 0; private static int mPnoResultFound = 0; @@ -316,6 +325,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno private boolean mEnableRssiPolling = false; private boolean mLegacyPnoEnabled = false; + private boolean mDisabled5GhzFrequencies = false; + private boolean mIsRandomMacCleared = false; private int mRssiPollToken = 0; /* 3 operational states for STA operation: CONNECT_MODE, SCAN_ONLY_MODE, SCAN_ONLY_WIFI_OFF_MODE * In CONNECT_MODE, the STA can scan and connect to an access point @@ -586,6 +597,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // Used to filter out requests we couldn't possibly satisfy. private final NetworkCapabilities mNetworkCapabilitiesFilter = new NetworkCapabilities(); + private static final int WIFI_AUTO_CONNECT_TYPE_AUTO = 0; + /* The base for wifi message types */ static final int BASE = Protocol.BASE_WIFI; /* Start the supplicant */ @@ -840,6 +853,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno /* used to indicated RSSI threshold breach in hw */ static final int CMD_RSSI_THRESHOLD_BREACH = BASE + 164; + /* When there are saved networks and PNO fails, we do a periodic scan to notify + a saved/open network in suspend mode */ + static final int CMD_PNO_PERIODIC_SCAN = BASE + 165; + + /* Is IBSS mode supported by the driver? */ + static final int CMD_GET_IBSS_SUPPORTED = BASE + 200; /* Wifi state machine modes of operation */ @@ -1096,9 +1115,14 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno private final IBatteryStats mBatteryStats; private String mTcpBufferSizes = null; + private int mTcpDelayedAckSegments = 1; + private int mTcpUserCfg = 0; // Used for debug and stats gathering private static int sScanAlarmIntentCount = 0; + private boolean isPropFeatureEnabled = false; + + private static int DEFAULT_SCORE = NetworkAgent.WIFI_BASE_SCORE; final static int frameworkMinScanIntervalSaneValue = 10000; @@ -1112,6 +1136,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno super("WifiStateMachine"); mContext = context; mInterfaceName = wlanInterface; + if (SystemProperties.getInt("persist.fst.rate.upgrade.en", 0) == 1) { + log("fst enabled"); + mDataInterfaceName = "bond0"; + } else { + mDataInterfaceName = wlanInterface; + } + mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, ""); mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService( BatteryStats.SERVICE_NAME)); @@ -1152,7 +1183,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID; mLastSignalLevel = -1; - mNetlinkTracker = new NetlinkTracker(mInterfaceName, new NetlinkTracker.Callback() { + mNetlinkTracker = new NetlinkTracker(mDataInterfaceName, new NetlinkTracker.Callback() { public void update() { sendMessage(CMD_UPDATE_LINKPROPERTIES); } @@ -1184,6 +1215,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mBackgroundScanSupported = mContext.getResources().getBoolean( R.bool.config_wifi_background_scan_support); + mIsWiFiIpReachabilityEnabled = mContext.getResources().getBoolean( + R.bool.config_wifi_ipreachability_monitor); + mPrimaryDeviceType = mContext.getResources().getString( R.string.config_wifi_p2p_device_type); @@ -1259,6 +1293,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); + addCneAction(filter); + mContext.registerReceiver( new BroadcastReceiver() { @Override @@ -1269,6 +1305,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno sendMessage(CMD_SCREEN_STATE_CHANGED, 1); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { sendMessage(CMD_SCREEN_STATE_CHANGED, 0); + } else { + handleCneAction(intent, action); } } }, filter); @@ -1293,6 +1331,15 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } }); + mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor( + Settings.System.WIFI_AUTO_CONNECT_TYPE), false, + new ContentObserver(getHandler()) { + @Override + public void onChange(boolean selfChange) { + checkAndSetAutoConnection(); + } + }); + mContext.registerReceiver( new BroadcastReceiver() { @Override @@ -1312,6 +1359,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mTcpBufferSizes = mContext.getResources().getString( com.android.internal.R.string.config_wifi_tcp_buffers); + mTcpDelayedAckSegments = SystemProperties.getInt("net.tcp.delack.wifi", 1); + mTcpUserCfg = SystemProperties.getInt("net.tcp.usercfg.wifi", 0); addState(mDefaultState); addState(mInitialState, mDefaultState); @@ -1384,6 +1433,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mLogMessages = false; mWifiNative.setSupplicantLogLevel("INFO"); } + mWifiP2pServiceImpl.enableVerboseLogging(verbose); mWifiLogger.startLogging(mVerboseLoggingLevel > 0); mWifiAutoJoinController.enableVerboseLogging(verbose); mWifiMonitor.enableVerboseLogging(verbose); @@ -1617,6 +1667,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno logd("Setting OUI to " + oui); return mWifiNative.setScanningMacOui(ouiBytes); } + private boolean clearRandomMacOui() { + byte[] ouiBytes = new byte[]{0,0,0}; + logd("Clear random OUI"); + return mWifiNative.setScanningMacOui(ouiBytes); + } /** * ****************************************************** @@ -1661,6 +1716,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } catch (NumberFormatException e) { } c.isDFS = line.contains("(DFS)"); + c.ibssAllowed = !line.contains("(NO_IBSS)"); list.add(c); } else if (line.contains("Mode[B] Channels:")) { // B channels are the same as G channels, skipped @@ -1833,8 +1889,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } } if (stats == null || mWifiLinkLayerStatsSupported <= 0) { - long mTxPkts = TrafficStats.getTxPackets(mInterfaceName); - long mRxPkts = TrafficStats.getRxPackets(mInterfaceName); + long mTxPkts = TrafficStats.getTxPackets(mDataInterfaceName); + long mRxPkts = TrafficStats.getRxPackets(mDataInterfaceName); mWifiInfo.updatePacketRates(mTxPkts, mRxPkts); } else { mWifiInfo.updatePacketRates(stats); @@ -2057,6 +2113,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno */ public void setSupplicantRunning(boolean enable) { if (enable) { + WifiNative.setMode(0); sendMessage(CMD_START_SUPPLICANT); } else { sendMessage(CMD_STOP_SUPPLICANT); @@ -2068,6 +2125,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno */ public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) { if (enable) { + WifiNative.setMode(1); sendMessage(CMD_START_AP, wifiConfig); } else { sendMessage(CMD_STOP_AP); @@ -2356,9 +2414,16 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno return mWifiNative.getNfcWpsConfigurationToken(netId); } - void enableBackgroundScan(boolean enable) { + boolean enableBackgroundScan(boolean enable) { if (enable) { - mWifiConfigStore.enableAllNetworks(); + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + if (DBG) { + logd("No auto connect, skip enable networks during pno"); + } + } else { + mWifiConfigStore.enableAllNetworks(); + } } boolean ret = mWifiNative.enableBackgroundScan(enable); if (ret) { @@ -2366,6 +2431,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } else { Log.e(TAG, " Fail to set up pno, want " + enable + " now " + mLegacyPnoEnabled); } + return ret; } /** @@ -2494,6 +2560,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } } + public int syncIsIbssSupported(AsyncChannel channel) { + Message resultMsg = channel.sendMessageSynchronously(CMD_GET_IBSS_SUPPORTED); + int result = resultMsg.arg1; + resultMsg.recycle(); + return result; + } + /** * Get the country code * @@ -3562,6 +3635,21 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno + " suppState:" + mSupplicantStateTracker.getSupplicantStateName()); } enableRssiPolling(screenOn); + if (screenOn) { + if (mContext.getResources().getBoolean(R.bool.wifi_autocon)) { + if (!shouldAutoConnect()) { + if (DBG) { + logd("Don't auto connect skip enable networks if screen on"); + } + } else { + if (!mWifiConfigStore.enableAutoJoinWhenAssociated.get()) { + enableAllNetworks(); + } + } + } else { + enableAllNetworks(); + } + } if (mUserWantsSuspendOpt.get()) { if (screenOn) { sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 0, 0); @@ -3573,9 +3661,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } mScreenBroadcastReceived.set(true); - getWifiLinkLayerStats(false); - mOnTimeScreenStateChange = mOnTime; - lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate; + if (mIsRunning) { + getWifiLinkLayerStats(false); + mOnTimeScreenStateChange = mOnTime; + lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate; + } cancelDelayedScan(); @@ -3617,7 +3707,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno setScanAlarm(true); } else { if (!mIsScanOngoing) { - enableBackgroundScan(true); + if (!enableBackgroundScan(true)) { + handlePnoFailError(); + } } } } @@ -3741,6 +3833,15 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (mWifiNative.setBand(band)) { mFrequencyBand.set(band); + mWifiConfigStore.setConfiguredBand(band); + if (mFrequencyBand.get() == WifiManager.WIFI_FREQUENCY_BAND_2GHZ) { + mWifiNative.disable5GHzFrequencies(true); + mDisabled5GhzFrequencies = true; + } else if ((mFrequencyBand.get() != WifiManager.WIFI_FREQUENCY_BAND_2GHZ) + && (mDisabled5GhzFrequencies)) { + mWifiNative.disable5GHzFrequencies(false); + mDisabled5GhzFrequencies = false; + } if (PDBG) { logd("done set frequency band " + band); } @@ -3843,6 +3944,116 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } + /* + void ageOutScanResults(int age) { + synchronized(mScanResultCache) { + // Trim mScanResults, which prevent WifiStateMachine to return + // obsolete scan results to queriers + long now = System.CurrentTimeMillis(); + for (int i = 0; i < mScanResults.size(); i++) { + ScanResult result = mScanResults.get(i); + if ((result.seen > now || (now - result.seen) > age)) { + mScanResults.remove(i); + } + } + } + }*/ + + /** + * Allow blacklist by BSSID + * + * @param enable + * @param bssid + * @param reason + */ + private void handleBSSIDBlacklist(boolean enable, String bssid, int reason) { + if (DBG) log("Blacklisting BSSID: " + bssid + ",reason:" + reason + ",enable:" + enable ); + if (bssid != null) { + // Tell configStore to black list it + synchronized(mScanResultCache) { + mWifiAutoJoinController.handleBSSIDBlackList( enable, bssid, reason ); + mWifiConfigStore.handleDisabledAPs( enable, bssid, reason ); + } + } + } + + /** + * Update the score based on indication of wifi quality + * + * @param state + */ + private void handleStateChange(int state) { + int offset; + if (DBG) log("handle state change: " + state); + if(state == 0) { + // wifi is not good, reduce the score + mWifiInfo.score = 1; + } else { + // wifi is good, increase the score + mWifiInfo.score = NetworkAgent.WIFI_BASE_SCORE; + } + if(mNetworkAgent != null) { + mNetworkAgent.sendNetworkScore(mWifiInfo.score); + } + } + + /** + * Handle change of preference + * + * @param featureId + * @param featureParam + * @param value + */ + private void handlePrefChange(int featureId, int featureParam, int value) { + if (DBG) log("handle pref change : featurevalue: " + value); + if(featureId == 1 && featureParam == 1) { + if(value == 2/*enabled*/) { + DEFAULT_SCORE = 1; + isPropFeatureEnabled = true; + } else if(value == 1/*disabled*/) { + DEFAULT_SCORE = NetworkAgent.WIFI_BASE_SCORE; + isPropFeatureEnabled = false; + } + } + } + + /** + * register for additional intents + */ + private void addCneAction(IntentFilter filter) { + int val = SystemProperties.getInt("persist.cne.feature", 0); + boolean isPropFeatureAvail = (val == 3) ? true : false; + if (isPropFeatureAvail) { + DEFAULT_SCORE = 1; + filter.addAction("com.quicinc.cne.CNE_PREFERENCE_CHANGED"); + filter.addAction("prop_state_change"); + filter.addAction("blacklist_bad_bssid"); + } + } + + /** + * handle intents for preference change, wifi quality indication, + * and blackisting/unblacklisting indication + */ + private void handleCneAction(Intent intent, String action) { + if (null == action) return; + if (action.equals("com.quicinc.cne.CNE_PREFERENCE_CHANGED")) { + int featureId = intent.getIntExtra("cneFeatureId", -1); + int featureParam = intent.getIntExtra("cneFeatureParameter", -1); + int featureVal = intent.getIntExtra("cneParameterValue", -1); + handlePrefChange(featureId, featureParam, featureVal); + } else if (action.equals("prop_state_change")) { + int state = intent.getIntExtra("state", 0); + handleStateChange(state); + } else if (action.equals("blacklist_bad_bssid") ) { + // 1 = blacklist, 0 = unblacklist + int blacklist = intent.getIntExtra("blacklistBSSID", -1); + String bssid = intent.getStringExtra("BSSIDToBlacklist"); + int reason = intent.getIntExtra("blacklistReason", -1 ); + handleBSSIDBlacklist( ( blacklist == 0) ? true : false, bssid, reason ); + } + } + private static final String IE_STR = "ie="; private static final String ID_STR = "id="; private static final String BSSID_STR = "bssid="; @@ -3996,6 +4207,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno flags, level, freq, tsf); mScanResultCache.put(networkDetail, scanDetail); } + if (mFrequencyBand.get() + == WifiManager.WIFI_FREQUENCY_BAND_2GHZ) { + if (ScanResult.is5GHz(freq)) { + continue; + } + } else if (mFrequencyBand.get() + == WifiManager.WIFI_FREQUENCY_BAND_5GHZ) { + if (ScanResult.is24GHz(freq)) { + continue; + } + } mNumScanResultsReturned++; // Keep track of how many scan results we got // as part of this scan's processing @@ -4062,6 +4284,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (attemptAutoJoin) { synchronized (mScanResultCache) { + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + attemptAutoJoin = false; + } // AutoJoincontroller will directly acces the scan result list and update it with // ScanResult status mNumScanResultsKnown = mWifiAutoJoinController.newSupplicantResults(attemptAutoJoin); @@ -4246,7 +4472,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno ScanDetailCache scanDetailCache = mWifiConfigStore.getScanDetailCache(currentConfiguration); if (currentConfiguration != null && scanDetailCache != null) { - currentConfiguration.setVisibility(scanDetailCache.getVisibility(12000)); + currentConfiguration.setVisibility(scanDetailCache.getVisibility(12000, mFrequencyBand.get())); if (currentConfiguration.visibility != null) { if (currentConfiguration.visibility.rssi24 != WifiConfiguration.INVALID_RSSI && currentConfiguration.visibility.rssi24 @@ -4445,9 +4671,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (DBG) { logd("calculateWifiScore() report new score " + Integer.toString(score)); } - mWifiInfo.score = score; - if (mNetworkAgent != null) { - mNetworkAgent.sendNetworkScore(score); + if (!isPropFeatureEnabled) { + mWifiInfo.score = score; + if(mNetworkAgent != null) { + mNetworkAgent.sendNetworkScore(score); + } } } wifiScoringReport = sb.toString(); @@ -4499,6 +4727,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno return true; } catch (RemoteException e) { return false; + } catch (IllegalStateException ie) { + loge("Unable to set interface config: " + ie); + return false; } } @@ -4529,11 +4760,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno LinkProperties newLp = new LinkProperties(); // Interface name, proxy, and TCP buffer sizes are locally configured. - newLp.setInterfaceName(mInterfaceName); + newLp.setInterfaceName(mDataInterfaceName); newLp.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId)); if (!TextUtils.isEmpty(mTcpBufferSizes)) { newLp.setTcpBufferSizes(mTcpBufferSizes); } + newLp.setTcpDelayedAckSegments(mTcpDelayedAckSegments); + newLp.setTcpUserCfg(mTcpUserCfg); // IPv4/v6 addresses, IPv6 routes and IPv6 DNS servers come from netlink. LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties(); @@ -4554,7 +4787,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // Even when we're using static configuration, we don't need to look at the config // store, because static IP configuration also populates mDhcpResults. if ((mDhcpResults != null)) { - for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) { + for (RouteInfo route : mDhcpResults.getRoutes(mDataInterfaceName)) { newLp.addRoute(route); } for (InetAddress dns : mDhcpResults.dnsServers) { @@ -4678,7 +4911,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // for now it's only here for extra redundancy. However, it will increase // robustness if we move to getting IPv4 routes from netlink as well. loge("DHCP failure: provisioned, clearing IPv4 address."); - if (!clearIPv4Address(mInterfaceName)) { + if (!clearIPv4Address(mDataInterfaceName)) { sendMessage(CMD_IP_CONFIGURATION_LOST); } } @@ -4966,12 +5199,22 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno stopRssiMonitoringOffload(); clearCurrentConfigBSSID("handleNetworkDisconnect"); + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + /* + * The following logic shall address the requirement for the DUT to + * not reconnect to the last connected network when the Auto + * Connect is disabled. This asks for the user prompt for any + * connection attempt (as per the requirement) + */ + disableLastNetwork(); + } stopDhcp(); try { - mNwService.clearInterfaceAddresses(mInterfaceName); - mNwService.disableIpv6(mInterfaceName); + mNwService.clearInterfaceAddresses(mDataInterfaceName); + mNwService.disableIpv6(mDataInterfaceName); } catch (Exception e) { loge("Failed to clear addresses or disable ipv6" + e); } @@ -5026,27 +5269,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno void handlePreDhcpSetup() { mDhcpActive = true; - if (!mBluetoothConnectionActive) { - /* - * There are problems setting the Wi-Fi driver's power - * mode to active when bluetooth coexistence mode is - * enabled or sense. - * <p> - * We set Wi-Fi to active mode when - * obtaining an IP address because we've found - * compatibility issues with some routers with low power - * mode. - * <p> - * In order for this active power mode to properly be set, - * we disable coexistence mode until we're done with - * obtaining an IP address. One exception is if we - * are currently connected to a headset, since disabling - * coexistence would interrupt that connection. - */ - // Disable the coexistence mode - mWifiNative.setBluetoothCoexistenceMode( - mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED); - } + // Disable the coexistence mode + mWifiNative.setBluetoothCoexistenceMode( + mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED); // Disable power save and suspend optimizations during DHCP // Note: The order here is important for now. Brcm driver changes @@ -5078,10 +5303,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (mDhcpStateMachine == null) { if (useLegacyDhcpClient()) { mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine( - mContext, WifiStateMachine.this, mInterfaceName); + mContext, WifiStateMachine.this, mDataInterfaceName); } else { mDhcpStateMachine = DhcpClient.makeDhcpStateMachine( - mContext, WifiStateMachine.this, mInterfaceName); + mContext, WifiStateMachine.this, mDataInterfaceName); } } } @@ -5281,8 +5506,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } try { - mNwService.wifiFirmwareReload(mInterfaceName, "AP"); - if (DBG) Log.d(TAG, "Firmware reloaded in AP mode"); + if (!SystemProperties.getBoolean("ro.disableWifiApFirmwareReload", false)) { + mNwService.wifiFirmwareReload(mInterfaceName, "AP"); + if (DBG) Log.d(TAG, "Firmware reloaded in AP mode"); + } } catch (Exception e) { Log.e(TAG, "Failed to reload AP firmware " + e); } @@ -5554,6 +5781,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno case CMD_ADD_OR_UPDATE_NETWORK: case CMD_REMOVE_NETWORK: case CMD_SAVE_CONFIG: + case CMD_GET_IBSS_SUPPORTED: replyToMessage(message, message.what, FAILURE); break; case CMD_GET_CAPABILITY_FREQ: @@ -5753,6 +5981,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno case CMD_REMOVE_USER_CONFIGURATIONS: deferMessage(message); break; + case CMD_PNO_PERIODIC_SCAN: + deferMessage(message); case CMD_START_IP_PACKET_OFFLOAD: if (mNetworkAgent != null) mNetworkAgent.onPacketKeepaliveEvent( message.arg1, @@ -5807,6 +6037,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno logStateAndMessage(message, this); switch (message.what) { case CMD_START_SUPPLICANT: + /* Stop a running supplicant after a runtime restart + * Avoids issues with drivers that do not handle interface down + * on a running supplicant properly. + */ + mWifiMonitor.killSupplicant(mP2pSupported); + if (mWifiNative.loadDriver()) { try { mNwService.wifiFirmwareReload(mInterfaceName, "STA"); @@ -5822,28 +6058,22 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // Ensure interface is down and we have no IP // addresses before a supplicant start. mNwService.setInterfaceDown(mInterfaceName); - mNwService.clearInterfaceAddresses(mInterfaceName); + mNwService.clearInterfaceAddresses(mDataInterfaceName); // Set privacy extensions - mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true); + mNwService.setInterfaceIpv6PrivacyExtensions(mDataInterfaceName, true); // IPv6 is enabled only as long as access point is connected since: // - IPv6 addresses and routes stick around after disconnection // - kernel is unaware when connected and fails to start IPv6 negotiation // - kernel can start autoconfiguration when 802.1x is not complete - mNwService.disableIpv6(mInterfaceName); + mNwService.disableIpv6(mDataInterfaceName); } catch (RemoteException re) { loge("Unable to change interface settings: " + re); } catch (IllegalStateException ie) { loge("Unable to change interface settings: " + ie); } - /* Stop a running supplicant after a runtime restart - * Avoids issues with drivers that do not handle interface down - * on a running supplicant properly. - */ - mWifiMonitor.killSupplicant(mP2pSupported); - if (WifiNative.startHal() == false) { /* starting HAL is optional */ loge("Failed to start HAL"); @@ -5934,12 +6164,21 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno /* set frequency band of operation */ setFrequencyBand(); mWifiNative.enableSaveConfig(); + if (mWifiConfigStore.enableAutoJoinWhenAssociated.get()) { + mWifiNative.disconnect(); + } mWifiConfigStore.loadAndEnableAllNetworks(); if (mWifiConfigStore.enableVerboseLogging.get() > 0) { enableVerboseLogging(mWifiConfigStore.enableVerboseLogging.get()); } + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + mWifiConfigStore.disableAllNetworks(); + } initializeWpsDetails(); + mIbssSupported = mWifiNative.getModeCapability("IBSS"); + sendSupplicantConnectionChangedBroadcast(true); transitionTo(mDriverStartedState); break; @@ -5968,6 +6207,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: + case CMD_GET_IBSS_SUPPORTED: messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; @@ -6106,6 +6346,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.SET_COUNTRY_CODE, country); break; + + case CMD_GET_IBSS_SUPPORTED: + deferMessage(message); + break; + case CMD_RESET_SIM_NETWORKS: log("resetting EAP-SIM/AKA/AKA' networks since SIM was removed"); mWifiConfigStore.resetSimNetworks(); @@ -6373,8 +6618,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (PDBG) logd("did set frequency band " + band); mFrequencyBand.set(band); + mWifiConfigStore.setConfiguredBand(band); // Flush old data - like scan results mWifiNative.bssFlush(); + if (mFrequencyBand.get() == WifiManager.WIFI_FREQUENCY_BAND_2GHZ) { + mWifiNative.disable5GHzFrequencies(true); + mDisabled5GhzFrequencies = true; + } else if ((mFrequencyBand.get() != WifiManager.WIFI_FREQUENCY_BAND_2GHZ) + && (mDisabled5GhzFrequencies)) { + mWifiNative.disable5GHzFrequencies(false); + mDisabled5GhzFrequencies = false; + } // Fetch the latest scan results when frequency band is set // startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, null); @@ -6422,7 +6676,14 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mAlarmManager.cancel(mDriverStopIntent); if (DBG) log("Delayed stop ignored due to start"); if (mOperationalMode == CONNECT_MODE) { - mWifiConfigStore.enableAllNetworks(); + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + if (DBG) { + logd("Auto connect disabled, skip enable networks"); + } + } else { + mWifiConfigStore.enableAllNetworks(); + } } } break; @@ -6485,6 +6746,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno case WifiMonitor.ANQP_DONE_EVENT: mWifiConfigStore.notifyANQPDone((Long) message.obj, message.arg1 != 0); break; + case CMD_GET_IBSS_SUPPORTED: + replyToMessage(message, message.what, mIbssSupported ? 1 : 0); + break; case CMD_STOP_IP_PACKET_OFFLOAD: { int slot = message.arg1; int ret = stopWifiIPPacketOffload(slot); @@ -6652,7 +6916,14 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mWifiConfigStore.loadAndEnableAllNetworks(); mWifiP2pChannel.sendMessage(CMD_ENABLE_P2P); } else { - mWifiConfigStore.enableAllNetworks(); + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + if (DBG) { + logd("No auto, skip enable networks on mode change"); + } + } else { + mWifiConfigStore.enableAllNetworks(); + } } // Try autojoining with recent network already present in the cache @@ -7213,6 +7484,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: mWifiLogger.captureBugReportData(WifiLogger.REPORT_REASON_AUTH_FAILURE); mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT); + if ((mScreenOn == false) && mBackgroundScanSupported) { + // Background SCAN should trigger to initiate + // connection attempt on authentication failure. + // Hence issue PNO SCAN if authentication fails + // and LCD is off. + if (!mIsScanOngoing) { + if (!enableBackgroundScan(true)) { + handlePnoFailError(); + } + } + } break; case WifiMonitor.SSID_TEMP_DISABLED: case WifiMonitor.SSID_REENABLED: @@ -7912,6 +8194,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno WpsResult wpsResult; switch (wpsInfo.setup) { case WpsInfo.PBC: + clearRandomMacOui(); + mIsRandomMacCleared = true; wpsResult = mWifiConfigStore.startWpsPbc(wpsInfo); break; case WpsInfo.KEYPAD: @@ -8187,7 +8471,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno + " config.bssid " + config.BSSID); } config.autoJoinBSSID = "any"; - config.BSSID = "any"; + + // If an app specified a BSSID then dont over-write it + if ( !mWifiAutoJoinController.isBlacklistedBSSID(config.BSSID) ) { + config.BSSID = "any"; + } + if (DBG) { logd(dbg + " " + config.SSID + " nid=" + Integer.toString(config.networkId)); @@ -8211,9 +8500,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (!TextUtils.isEmpty(mTcpBufferSizes)) { mLinkProperties.setTcpBufferSizes(mTcpBufferSizes); } + mLinkProperties.setTcpDelayedAckSegments(mTcpDelayedAckSegments); + mLinkProperties.setTcpUserCfg(mTcpUserCfg); + mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext, "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter, - mLinkProperties, 60); + mLinkProperties, DEFAULT_SCORE); // We must clear the config BSSID, as the wifi chipset may decide to roam // from this point on and having the BSSID specified in the network block would @@ -8631,7 +8923,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno clearCurrentConfigBSSID("ObtainingIpAddress"); try { - mNwService.enableIpv6(mInterfaceName); + mNwService.enableIpv6(mDataInterfaceName); } catch (RemoteException re) { loge("Failed to enable IPv6: " + re); } catch (IllegalStateException e) { @@ -8645,7 +8937,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // Remove any IP address on the interface in case we're switching from static // IP configuration to DHCP. This is safe because if we get here when not // roaming, we don't have a usable address. - clearIPv4Address(mInterfaceName); + clearIPv4Address(mDataInterfaceName); startDhcp(); } obtainingIpWatchdogCount++; @@ -8667,7 +8959,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno ifcg.setLinkAddress(config.ipAddress); ifcg.setInterfaceUp(); try { - mNwService.setInterfaceConfig(mInterfaceName, ifcg); + mNwService.setInterfaceConfig(mDataInterfaceName, ifcg); if (DBG) log("Static IP configuration succeeded"); DhcpResults dhcpResults = new DhcpResults(config); sendMessage(CMD_STATIC_IP_SUCCESS, dhcpResults); @@ -8969,9 +9261,20 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno sendMessageDelayed(obtainMessage(CMD_TEST_NETWORK_DISCONNECT, testNetworkDisconnectCounter, 0), 15000); } - - // Reenable all networks, allow for hidden networks to be scanned - mWifiConfigStore.enableAllNetworks(); + if (!mWifiConfigStore.enableAutoJoinWhenAssociated.get()) { + if (mContext.getResources().getBoolean(R.bool.wifi_autocon) + && !shouldAutoConnect()) { + if (DBG) { + logd("Auto connect disabled, skip enable networks"); + } + } else { + // Reenable all networks, allow for hidden networks to be scanned + mWifiConfigStore.enableAllNetworks(); + } + } else { + // Reenable all networks, allow for hidden networks to be scanned + mWifiConfigStore.enableAllNetworks(); + } mLastDriverRoamAttempt = 0; @@ -9354,7 +9657,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno * cleared */ if (!mIsScanOngoing) { - enableBackgroundScan(true); + if (!enableBackgroundScan(true)) { + handlePnoFailError(); + } } } else { setScanAlarm(true); @@ -9392,6 +9697,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno ++mPeriodicScanToken, 0), mNoNetworksPeriodicScan); } break; + case CMD_PNO_PERIODIC_SCAN: + if ((message.arg1 == mPnoPeriodicScanToken) && + mBackgroundScanSupported && (mP2pConnected.get() || + (mWifiConfigStore.getConfiguredNetworks().size() + != 0))) { + startScan(UNKNOWN_SCAN_SOURCE, -1, null, null); + sendMessageDelayed(obtainMessage(CMD_PNO_PERIODIC_SCAN, + ++mPnoPeriodicScanToken, 0), + mDefaultFrameworkScanIntervalMs); + } + break; case WifiManager.FORGET_NETWORK: case CMD_REMOVE_NETWORK: case CMD_REMOVE_APP_CONFIGURATIONS: @@ -9512,7 +9828,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // attempt again to join that network. if (!mScreenOn && !mIsScanOngoing && mBackgroundScanSupported) { enableBackgroundScan(false); - enableBackgroundScan(true); + if (!enableBackgroundScan(true)) { + handlePnoFailError(); + } } return HANDLED; } @@ -9523,7 +9841,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (!mScreenOn && mIsScanOngoing && mBackgroundScanSupported && !useHalBasedAutoJoinOffload()) { - enableBackgroundScan(true); + if (!enableBackgroundScan(true)) { + handlePnoFailError(); + } } else if (!mScreenOn && !mIsScanOngoing && mBackgroundScanSupported @@ -9562,6 +9882,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (DBG) log("Turn on scanning after p2p disconnected"); sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, ++mPeriodicScanToken, 0), mNoNetworksPeriodicScan); + } else if (!mP2pConnected.get() && (!mScreenOn)) { + if (!enableBackgroundScan(true)) { + handlePnoFailError(); + } } else { // If P2P is not connected and there are saved networks, then restart // scanning at the normal period. This is necessary because scanning might @@ -9729,6 +10053,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno public void exit() { mWifiConfigStore.enableAllNetworks(); mWifiConfigStore.loadConfiguredNetworks(); + if (mIsRandomMacCleared) { + setRandomMacOui(); + mIsRandomMacCleared = false; + } } } @@ -9852,6 +10180,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (message.arg1 == mTetherToken) { loge("Failed to get tether update, shutdown soft access point"); transitionTo(mSoftApStartedState); + setWifiApState(WIFI_AP_STATE_FAILED,WifiManager.SAP_START_FAILURE_GENERAL); // Needs to be first thing handled sendMessageAtFrontOfQueue(CMD_STOP_AP); } @@ -10296,4 +10625,58 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno || reason == 23 // IEEE_802_1X_AUTH_FAILED || reason == 34; // DISASSOC_LOW_ACK } + private void handlePnoFailError() { + if (mBackgroundScanSupported && (mP2pConnected.get() || + (mWifiConfigStore.getConfiguredNetworks().size() != 0))) { + sendMessageDelayed(obtainMessage(CMD_PNO_PERIODIC_SCAN, + ++mPnoPeriodicScanToken, 0), + mDefaultFrameworkScanIntervalMs); + } + } + + boolean shouldAutoConnect() { + int autoConnectPolicy = Settings.System.getInt( + mContext.getContentResolver(), + Settings.System.WIFI_AUTO_CONNECT_TYPE, + WIFI_AUTO_CONNECT_TYPE_AUTO); + if (DBG) { + if (autoConnectPolicy == WIFI_AUTO_CONNECT_TYPE_AUTO) { + Log.d(TAG, "Wlan connection type is auto, should auto connect"); + } else { + Log.d(TAG, "Shouldn't auto connect"); + } + } + return (autoConnectPolicy == WIFI_AUTO_CONNECT_TYPE_AUTO); + } + + void disableLastNetwork() { + if (getCurrentState() != mSupplicantStoppingState) { + mWifiConfigStore.disableNetwork(mLastNetworkId, + WifiConfiguration.DISABLED_UNKNOWN_REASON); + } + } + + void checkAndSetAutoConnection() { + if (mContext.getResources().getBoolean(R.bool.wifi_autocon)) { + if (shouldAutoConnect()){ + if(!mWifiConfigStore.enableAutoJoinWhenAssociated.get()) { + /* + * This is AutoConnect-> Automatic, but auto join + * is disabled , hence re enable supplicant auto + * connection ability, also enable all networks + * so that supplicant shall try for connection. + */ + mWifiNative.enableAutoConnect(true); + mWifiConfigStore.enableAllNetworks(); + } + } else { + /* + * This is AutoConnect -> Manual selection case + * Device should not auto connect to network, hence + * disable supplicants auto connection ability. + */ + mWifiNative.enableAutoConnect(false); + } + } + } } |