summaryrefslogtreecommitdiffstats
path: root/service/java/com/android/server/wifi/WifiStateMachine.java
diff options
context:
space:
mode:
Diffstat (limited to 'service/java/com/android/server/wifi/WifiStateMachine.java')
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java513
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);
+ }
+ }
+ }
}