From 28036b9b6c6bbe6abfe6622ecb6dbb5fcf548cf6 Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Mon, 4 May 2020 15:56:23 -0700 Subject: Add start/stop-softap shell command Add start-softap and stop-softap wifi shell commands to help automate wifi hotspot tests. Note that this doesn't go through tetheringManager. In some devices, internet sharing might be possible if wifi STA is also enabled and is associated to another AP with internet access. Bug: 155682782 Test: atest com.android.server.wifi.WifiShellCommandTest Test: manual test with "adb shell cmd wifi start/stop-softap" in open/wpa2 modes with different band options. In all tested modes, another device can associate to the DUT's hotspot. If DUT's STA is also enabled and associated to another internet-bounding AP, internet should be also avaiable to the device associated to DUT's hotspot. Change-Id: I9ad561b0e10171ff9ccb395e1538472ac637e17a --- .../com/android/server/wifi/WifiShellCommand.java | 74 ++++++++++++++++++++++ .../android/server/wifi/WifiShellCommandTest.java | 27 ++++++++ 2 files changed, 101 insertions(+) diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java index ed955bab4..a80b14ad6 100644 --- a/service/java/com/android/server/wifi/WifiShellCommand.java +++ b/service/java/com/android/server/wifi/WifiShellCommand.java @@ -98,7 +98,9 @@ public class WifiShellCommand extends BasicShellCommandHandler { "set-verbose-logging", "set-wifi-enabled", "start-scan", + "start-softap", "status", + "stop-softap", }; private static final Map> @@ -303,6 +305,23 @@ public class WifiShellCommand extends BasicShellCommandHandler { return 0; } } + case "start-softap": { + SoftApConfiguration config = buildSoftApConfiguration(pw); + if (mWifiService.startTetheredHotspot(config)) { + pw.println("Soft AP started successfully"); + } else { + pw.println("Soft AP failed to start. Please check config parameters"); + } + return 0; + } + case "stop-softap": { + if (mWifiService.stopSoftAp()) { + pw.println("Soft AP stopped successfully"); + } else { + pw.println("Soft AP failed to stop"); + } + return 0; + } case "force-country-code": { boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); if (enabled) { @@ -722,6 +741,42 @@ public class WifiShellCommand extends BasicShellCommandHandler { return configuration; } + private SoftApConfiguration buildSoftApConfiguration(PrintWriter pw) { + String ssid = getNextArgRequired(); + String type = getNextArgRequired(); + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); + configBuilder.setSsid("\"" + ssid + "\""); + if (TextUtils.equals(type, "wpa2")) { + configBuilder.setPassphrase(getNextArgRequired(), + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + } else if (TextUtils.equals(type, "open")) { + configBuilder.setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN); + } else { + throw new IllegalArgumentException("Unknown network type " + type); + } + String option = getNextOption(); + while (option != null) { + if (option.equals("-b")) { + String preferredBand = getNextArgRequired(); + if (preferredBand.equals("2")) { + configBuilder.setBand(SoftApConfiguration.BAND_2GHZ); + } else if (preferredBand.equals("5")) { + configBuilder.setBand(SoftApConfiguration.BAND_5GHZ); + } else if (preferredBand.equals("6")) { + configBuilder.setBand(SoftApConfiguration.BAND_6GHZ); + } else if (preferredBand.equals("any")) { + configBuilder.setBand(SoftApConfiguration.BAND_ANY); + } else { + throw new IllegalArgumentException("Invalid band option " + preferredBand); + } + } else { + pw.println("Ignoring unknown option " + option); + } + option = getNextOption(); + } + return configBuilder.build(); + } + private WifiNetworkSuggestion buildSuggestion(PrintWriter pw) { String ssid = getNextArgRequired(); String type = getNextArgRequired(); @@ -940,6 +995,25 @@ public class WifiShellCommand extends BasicShellCommandHandler { pw.println(" reset-connected-score"); pw.println(" Turns on the default connected scorer."); pw.println(" Note: Will clear any external scorer set."); + pw.println(" start-softap (open|wpa2) [-b 2|5|6|any]"); + pw.println(" Start softap with provided params"); + pw.println(" Note that the shell command doesn't activate internet tethering. In some " + + "devices, internet sharing is possible when Wi-Fi STA is also enabled and is" + + "associated to another AP with internet access."); + pw.println(" - SSID of the network"); + pw.println(" open|wpa2 - Security type of the network."); + pw.println(" - Use 'open' for networks with no passphrase"); + pw.println(" - Use 'wpa2' for networks with passphrase"); + pw.println(" -b 2|5|6|any - select the preferred band."); + pw.println(" - Use '2' to select 2.4GHz band as the preferred band"); + pw.println(" - Use '5' to select 5GHz band as the preferred band"); + pw.println(" - Use '6' to select 6GHz band as the preferred band"); + pw.println(" - Use 'any' to indicate no band preference"); + pw.println(" Note: If the band option is not provided, 2.4GHz is the preferred band."); + pw.println(" The exact channel is auto-selected by FW unless overridden by " + + "force-softap-channel command"); + pw.println(" stop-softap"); + pw.println(" Stop softap (hotspot)"); } private void onHelpPrivileged(PrintWriter pw) { diff --git a/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java b/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java index a1897ded9..1f4af5cc0 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java @@ -16,6 +16,7 @@ package com.android.server.wifi; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -29,6 +30,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; +import android.net.wifi.SoftApConfiguration; import android.os.Binder; import android.os.Process; @@ -37,6 +39,7 @@ import androidx.test.filters.SmallTest; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -396,4 +399,28 @@ public class WifiShellCommandTest extends WifiBaseTest { verify(mClientModeImpl, times(2)).hasNetworkRequestUserApprovedApp(TEST_PACKAGE); mWifiShellCommand.getOutPrintWriter().toString().contains("no"); } + + @Test + public void testStartSoftAp() { + mWifiShellCommand.exec( + new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(), + new String[]{"start-softap", "ap1", "wpa2", "xyzabc321", "-b", "5"}); + ArgumentCaptor softApConfigurationCaptor = ArgumentCaptor.forClass( + SoftApConfiguration.class); + verify(mWifiService).startTetheredHotspot(softApConfigurationCaptor.capture()); + assertEquals(SoftApConfiguration.BAND_5GHZ, + softApConfigurationCaptor.getValue().getBand()); + assertEquals(SoftApConfiguration.SECURITY_TYPE_WPA2_PSK, + softApConfigurationCaptor.getValue().getSecurityType()); + assertEquals("\"ap1\"", softApConfigurationCaptor.getValue().getSsid()); + assertEquals("xyzabc321", softApConfigurationCaptor.getValue().getPassphrase()); + } + + @Test + public void testStopSoftAp() { + mWifiShellCommand.exec( + new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(), + new String[]{"stop-softap"}); + verify(mWifiService).stopSoftAp(); + } } -- cgit v1.2.3