summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Shi <kaishi@google.com>2019-07-20 09:54:05 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-07-20 09:54:05 -0700
commit2ffd84c460fcb69256f1cc012fccc73411a87d7b (patch)
treeebedc9a1a8009ca1519563f1ee09aa0dc7f37edf
parent2cf53e6eaf439635452ce9a84b01716cd47f3b2f (diff)
parentf272b21563525d7c21735df8202a6e90e43f5b77 (diff)
Merge "WiFi: add ADB shell commands to force soft AP channel frequency and country code Bug: 136501595 Test: Manual test with Flame." into qt-r1-dev
am: f272b21563 Change-Id: Id2067d1b6638b8472b697de599ca1aa95f2254e3
-rw-r--r--service/java/com/android/server/wifi/HostapdHal.java29
-rw-r--r--service/java/com/android/server/wifi/WifiCountryCode.java35
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java4
-rw-r--r--service/java/com/android/server/wifi/WifiShellCommand.java92
-rw-r--r--service/java/com/android/server/wifi/util/ApConfigUtil.java2
5 files changed, 160 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index ee96fb269..5ac173447 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -33,6 +33,7 @@ import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.WifiNative.HostapdDeathEventHandler;
+import com.android.server.wifi.util.ApConfigUtil;
import com.android.server.wifi.util.NativeUtil;
import java.util.ArrayList;
@@ -64,6 +65,8 @@ public class HostapdHal {
private final boolean mEnableIeee80211AC;
private final List<android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange>
mAcsChannelRanges;
+ private boolean mForceApChannel = false;
+ private int mForcedApChannel;
// Hostapd HAL interface objects
private IServiceManager mIServiceManager = null;
@@ -301,6 +304,22 @@ public class HostapdHal {
}
/**
+ * Enable force-soft-AP-channel mode which takes effect when soft AP starts next time
+ * @param forcedApChannel The forced IEEE channel number
+ */
+ void enableForceSoftApChannel(int forcedApChannel) {
+ mForceApChannel = true;
+ mForcedApChannel = forcedApChannel;
+ }
+
+ /**
+ * Disable force-soft-AP-channel mode which take effect when soft AP starts next time
+ */
+ void disableForceSoftApChannel() {
+ mForceApChannel = false;
+ }
+
+ /**
* Add and start a new access point.
*
* @param ifaceName Name of the interface.
@@ -322,7 +341,15 @@ public class HostapdHal {
Log.e(TAG, "Unrecognized apBand " + config.apBand);
return false;
}
- if (mEnableAcs) {
+ if (mForceApChannel) {
+ ifaceParams.channelParams.enableAcs = false;
+ ifaceParams.channelParams.channel = mForcedApChannel;
+ if (mForcedApChannel <= ApConfigUtil.HIGHEST_2G_AP_CHANNEL) {
+ ifaceParams.channelParams.band = IHostapd.Band.BAND_2_4_GHZ;
+ } else {
+ ifaceParams.channelParams.band = IHostapd.Band.BAND_5_GHZ;
+ }
+ } else if (mEnableAcs) {
ifaceParams.channelParams.enableAcs = true;
ifaceParams.channelParams.acsShouldExcludeDfs = true;
} else {
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index a6695084b..499c159fa 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -48,6 +48,7 @@ public class WifiCountryCode {
private String mTelephonyCountryTimestamp = null;
private String mDriverCountryTimestamp = null;
private String mReadyTimestamp = null;
+ private boolean mForceCountryCode = false;
public WifiCountryCode(
WifiNative wifiNative,
@@ -111,6 +112,36 @@ public class WifiCountryCode {
}
/**
+ * Enable force-country-code mode
+ * @param countryCode The forced two-letter country code
+ */
+ synchronized void enableForceCountryCode(String countryCode) {
+ if (TextUtils.isEmpty(countryCode)) {
+ Log.d(TAG, "Fail to force country code because the received country code is empty");
+ return;
+ }
+ mForceCountryCode = true;
+ mTelephonyCountryCode = countryCode.toUpperCase(Locale.US);
+ // If wpa_supplicant is ready we set the country code now, otherwise it will be
+ // set once wpa_supplicant is ready.
+ if (mReady) {
+ updateCountryCode();
+ } else {
+ Log.d(TAG, "skip update supplicant not ready yet");
+ }
+ }
+
+ /**
+ * Disable force-country-code mode
+ */
+ synchronized void disableForceCountryCode() {
+ mForceCountryCode = false;
+ // Set mTelephonyCountryCode to null so that default country code is used until
+ // next call of setCountryCode().
+ mTelephonyCountryCode = null;
+ }
+
+ /**
* Handle country code change request.
* @param countryCode The country code intended to set.
* This is supposed to be from Telephony service.
@@ -118,6 +149,10 @@ public class WifiCountryCode {
* @return Returns true if the country code passed in is acceptable.
*/
public synchronized boolean setCountryCode(String countryCode) {
+ if (mForceCountryCode) {
+ Log.d(TAG, "Country code can't be set because it is the force-country-code mode");
+ return false;
+ }
Log.d(TAG, "Receive set country code request: " + countryCode);
mTelephonyCountryTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index ade295c63..8095bfac6 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -748,4 +748,8 @@ public class WifiInjector {
public IpMemoryStore getIpMemoryStore() {
return mIpMemoryStore;
}
+
+ public HostapdHal getHostapdHal() {
+ return mHostapdHal;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 256541670..b2289a832 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -18,10 +18,14 @@ package com.android.server.wifi;
import android.app.AppGlobals;
import android.content.pm.IPackageManager;
+import android.net.wifi.WifiScanner;
import android.os.Binder;
import android.os.ShellCommand;
+import com.android.server.wifi.util.ApConfigUtil;
+
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -47,6 +51,9 @@ public class WifiShellCommand extends ShellCommand {
private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
private final WifiConfigManager mWifiConfigManager;
private final IPackageManager mPM;
+ private final WifiNative mWifiNative;
+ private final HostapdHal mHostapdHal;
+ private final WifiCountryCode mWifiCountryCode;
WifiShellCommand(WifiInjector wifiInjector) {
mClientModeImpl = wifiInjector.getClientModeImpl();
@@ -54,6 +61,9 @@ public class WifiShellCommand extends ShellCommand {
mWifiNetworkSuggestionsManager = wifiInjector.getWifiNetworkSuggestionsManager();
mWifiConfigManager = wifiInjector.getWifiConfigManager();
mPM = AppGlobals.getPackageManager();
+ mHostapdHal = wifiInjector.getHostapdHal();
+ mWifiNative = wifiInjector.getWifiNative();
+ mWifiCountryCode = wifiInjector.getWifiCountryCode();
}
@Override
@@ -179,6 +189,62 @@ public class WifiShellCommand extends ShellCommand {
case "send-link-probe": {
return sendLinkProbe(pw);
}
+ case "force-softap-channel": {
+ String nextArg = getNextArgRequired();
+ if ("enabled".equals(nextArg)) {
+ int apChannelMHz;
+ try {
+ apChannelMHz = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ pw.println("Invalid argument to 'force-softap-channel enabled' "
+ + "- must be a positive integer");
+ return -1;
+ }
+ int apChannel = ApConfigUtil.convertFrequencyToChannel(apChannelMHz);
+ if (apChannel == -1 || !isApChannelMHzValid(apChannelMHz)) {
+ pw.println("Invalid argument to 'force-softap-channel enabled' "
+ + "- must be a valid WLAN channel");
+ return -1;
+ }
+ mHostapdHal.enableForceSoftApChannel(apChannel);
+ return 0;
+ } else if ("disabled".equals(nextArg)) {
+ mHostapdHal.disableForceSoftApChannel();
+ return 0;
+ } else {
+ pw.println(
+ "Invalid argument to 'force-softap-channel' - must be 'enabled'"
+ + " or 'disabled'");
+ return -1;
+ }
+ }
+ case "force-country-code": {
+ String nextArg = getNextArgRequired();
+ if ("enabled".equals(nextArg)) {
+ String countryCode = getNextArgRequired();
+ if (!(countryCode.length() == 2
+ && countryCode.chars().allMatch(Character::isLetter))) {
+ pw.println("Invalid argument to 'force-country-code enabled' "
+ + "- must be a two-letter string");
+ return -1;
+ }
+ mWifiCountryCode.enableForceCountryCode(countryCode);
+ return 0;
+ } else if ("disabled".equals(nextArg)) {
+ mWifiCountryCode.disableForceCountryCode();
+ return 0;
+ } else {
+ pw.println(
+ "Invalid argument to 'force-country-code' - must be 'enabled'"
+ + " or 'disabled'");
+ return -1;
+ }
+ }
+ case "get-country-code": {
+ pw.println("Wifi Country Code = "
+ + mWifiCountryCode.getCountryCode());
+ return 0;
+ }
default:
return handleDefaultCommands(cmd);
}
@@ -214,6 +280,25 @@ public class WifiShellCommand extends ShellCommand {
return 0;
}
+ private boolean isApChannelMHzValid(int apChannelMHz) {
+ int[] allowed2gFreq = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
+ int[] allowed5gFreq = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
+ int[] allowed5gDfsFreq =
+ mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY);
+ if (allowed2gFreq == null) {
+ allowed2gFreq = new int[0];
+ }
+ if (allowed5gFreq == null) {
+ allowed5gFreq = new int[0];
+ }
+ if (allowed5gDfsFreq == null) {
+ allowed5gDfsFreq = new int[0];
+ }
+ return (Arrays.binarySearch(allowed2gFreq, apChannelMHz) >= 0
+ || Arrays.binarySearch(allowed5gFreq, apChannelMHz) >= 0
+ || Arrays.binarySearch(allowed5gDfsFreq, apChannelMHz) >= 0);
+ }
+
private void checkRootPermission() {
final int uid = Binder.getCallingUid();
if (uid == 0) {
@@ -252,6 +337,13 @@ public class WifiShellCommand extends ShellCommand {
pw.println(" Clears the deleted ephemeral networks list.");
pw.println(" send-link-probe");
pw.println(" Manually triggers a link probe.");
+ pw.println(" force-softap-channel enabled <int> | disabled");
+ pw.println(" Sets whether soft AP channel is forced to <int> MHz");
+ pw.println(" or left for normal operation.");
+ pw.println(" force-country-code enabled <two-letter code> | disabled ");
+ pw.println(" Sets country code to <two-letter code> or left for normal value");
+ pw.println(" get-country-code");
+ pw.println(" Gets country code as a two-letter string");
pw.println();
}
}
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index dfda45b7d..c3a4c0c95 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -33,7 +33,7 @@ public class ApConfigUtil {
public static final int DEFAULT_AP_BAND = WifiConfiguration.AP_BAND_2GHZ;
public static final int DEFAULT_AP_CHANNEL = 6;
-
+ public static final int HIGHEST_2G_AP_CHANNEL = 14;
/* Return code for updateConfiguration. */
public static final int SUCCESS = 0;
public static final int ERROR_NO_CHANNEL = 1;