summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/HostapdHal.java5
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java14
-rw-r--r--tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java24
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java29
4 files changed, 69 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index 418fde66f..6ef0a7f86 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -584,9 +584,12 @@ public class HostapdHal {
case WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS:
disconnectReason = Ieee80211ReasonCode.WLAN_REASON_DISASSOC_AP_BUSY;
break;
- default:
+ case WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED:
disconnectReason = Ieee80211ReasonCode.WLAN_REASON_UNSPECIFIED;
break;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown disconnect reason code:" + reasonCode);
}
android.hardware.wifi.hostapd.V1_2.HostapdStatus status =
iHostapdV1_2.forceClientDisconnect(ifaceName,
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 44bbc73c4..3bf12ca34 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED;
+
import static com.android.server.wifi.util.ApConfigUtil.ERROR_GENERIC;
import static com.android.server.wifi.util.ApConfigUtil.ERROR_NO_CHANNEL;
import static com.android.server.wifi.util.ApConfigUtil.ERROR_UNSUPPORTED_CONFIGURATION;
@@ -433,9 +435,21 @@ public class SoftApManager implements ActiveModeManager {
}
/**
+ * Disconnect all connected clients on active softap interface(s).
+ * This is usually done just before stopSoftAp().
+ */
+ private void disconnectAllClients() {
+ for (WifiClient client : mConnectedClients) {
+ mWifiNative.forceClientDisconnect(mApInterfaceName, client.getMacAddress(),
+ SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED);
+ }
+ }
+
+ /**
* Teardown soft AP and teardown the interface.
*/
private void stopSoftAp() {
+ disconnectAllClients();
mWifiDiagnostics.stopLogging(mApInterfaceName);
mWifiNative.teardownInterface(mApInterfaceName);
Log.d(TAG, "Soft AP is stopped");
diff --git a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
index 9db553f3b..52a28eafe 100644
--- a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
@@ -34,6 +34,7 @@ import android.hidl.manager.V1_0.IServiceNotification;
import android.net.MacAddress;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
+import android.net.wifi.WifiManager;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.os.Handler;
import android.os.IHwBinder;
@@ -820,10 +821,28 @@ public class HostapdHalTest extends WifiBaseTest {
when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort()))
.thenReturn(mStatusSuccess12);
- assertTrue(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, 0));
+ assertTrue(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client,
+ WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER));
verify(mIHostapdMockV12).forceClientDisconnect(any(), any(), anyShort());
}
+ @Test
+ public void testForceClientDisconnectFailureDueToInvalidArg() throws Exception {
+ executeAndValidateInitializationSequence();
+ when(mServiceManagerMock.getTransport(anyString(), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ MacAddress test_client = MacAddress.fromString("da:a1:19:0:0:0");
+ mIHostapdMockV12 = mock(android.hardware.wifi.hostapd.V1_2.IHostapd.class);
+ when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort()))
+ .thenReturn(mStatusSuccess12);
+
+ try {
+ mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, -1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
/**
* Verifies the failure handling in forceClientDisconnect.
*/
@@ -837,7 +856,8 @@ public class HostapdHalTest extends WifiBaseTest {
when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort()))
.thenReturn(mStatusFailure12);
- assertFalse(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, 0));
+ assertFalse(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client,
+ WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER));
verify(mIHostapdMockV12).forceClientDisconnect(any(), any(), anyShort());
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index a7e21c996..ca7bc627c 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -23,6 +23,7 @@ import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
+import static android.net.wifi.WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
@@ -1106,6 +1107,34 @@ public class SoftApManagerTest extends WifiBaseTest {
}
@Test
+ public void stopDisconnectsConnectedClients() throws Exception {
+ InOrder order = inOrder(mCallback, mWifiMetrics);
+ SoftApModeConfiguration apConfig =
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
+ mTestSoftApCapability);
+ startSoftApAndVerifyEnabled(apConfig);
+
+ order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>());
+
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_NATIVE_CLIENT, true);
+ mLooper.dispatchAll();
+
+ order.verify(mCallback).onConnectedClientsChanged(
+ Mockito.argThat((List<WifiClient> clients) ->
+ clients.contains(TEST_CONNECTED_CLIENT))
+ );
+ verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(
+ 1, apConfig.getTargetMode());
+
+ mSoftApManager.stop();
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).forceClientDisconnect(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS,
+ SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED);
+ }
+
+ @Test
public void handlesInvalidConnectedClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,