diff options
author | Ningyuan Wang <nywang@google.com> | 2017-08-10 18:06:16 -0700 |
---|---|---|
committer | Mukesh Agrawal <quiche@google.com> | 2018-01-09 18:10:38 +0000 |
commit | b8b86ec1082f38402d74ab51553adb42ef8e8ff3 (patch) | |
tree | 67919976fc0e96b16bac41ca70239829d0995894 | |
parent | 9199181aeb3f76105ed15102e631c033ce39e753 (diff) | |
download | frameworks_opt_net_wifi-b8b86ec1082f38402d74ab51553adb42ef8e8ff3.tar.gz frameworks_opt_net_wifi-b8b86ec1082f38402d74ab51553adb42ef8e8ff3.tar.bz2 frameworks_opt_net_wifi-b8b86ec1082f38402d74ab51553adb42ef8e8ff3.zip |
Enable acs for hotspot channel selection
Bug: 69065316
Test: tests/wifitests/runtests.sh (on walleye)
Test: manual
Test: wifi sanity (http://b/71636949)
Manual test
-----------
- enable wifi hotspot from settings
$ adb logcat -b main hostapd '*:S' -e 'ACS'
01-04 18:03:53.482 3040 3040 I hostapd : ACS: Automatic channel selection started, this may take a bit
01-04 18:03:53.482 3040 3040 I hostapd : ACS: Offloading to driver
01-04 18:03:53.827 3040 3040 I hostapd : nl80211: ACS Results: PCH: 6 SCH: 0 BW: 20 VHT0: 0 VHT1: 0 HW_MODE: 1
01-04 18:03:53.827 3040 3040 I hostapd : wlan0: ACS-COMPLETED freq=2437 channel=6
Change-Id: I66782e5921db9063acc1dc8433b42edda120278e
6 files changed, 81 insertions, 25 deletions
diff --git a/libwifi_system/hostapd_manager.cpp b/libwifi_system/hostapd_manager.cpp index 8c7de320b..d6f31fed0 100644 --- a/libwifi_system/hostapd_manager.cpp +++ b/libwifi_system/hostapd_manager.cpp @@ -45,7 +45,6 @@ namespace android { namespace wifi_system { namespace { -const int kDefaultApChannel = 6; const char kHostapdServiceName[] = "hostapd"; const char kHostapdConfigFilePath[] = "/data/misc/wifi/hostapd.conf"; @@ -126,15 +125,11 @@ string HostapdManager::CreateHostapdConfig( const string& interface_name, const vector<uint8_t> ssid, bool is_hidden, - int channel, + BandType band, EncryptionType encryption_type, const vector<uint8_t> passphrase) { string result; - if (channel < 0) { - channel = kDefaultApChannel; - } - if (ssid.size() > 32) { LOG(ERROR) << "SSIDs must be <= 32 bytes long"; return result; @@ -171,6 +166,21 @@ string HostapdManager::CreateHostapdConfig( } } + // hw_mode will be used to specify band for acs. + string hw_mode; + if (band == BandType::kBand2G) { + hw_mode = "g"; + } else if (band == BandType::kBand5G) { + hw_mode = "a"; + } else if (band == BandType::kBandAny) { + hw_mode = "any"; + } else { + LOG(ERROR) << "Unknown band type (" + << static_cast<int>(band) + << ")"; + return result; + } + result = StringPrintf( "interface=%s\n" "driver=nl80211\n" @@ -179,16 +189,17 @@ string HostapdManager::CreateHostapdConfig( // for use as a SSID. In this case, we're giving it a hex string // and hostapd needs to expect that. "ssid2=%s\n" - "channel=%d\n" + // channel can be selected automatically at run time. + "channel=0\n" + "acs_exclude_dfs=1\n" "ieee80211n=1\n" - "hw_mode=%c\n" + "hw_mode=%s\n" "ignore_broadcast_ssid=%d\n" "wowlan_triggers=any\n" "%s", interface_name.c_str(), ssid_as_string.c_str(), - channel, - (channel <= 14) ? 'g' : 'a', + hw_mode.c_str(), (is_hidden) ? 1 : 0, encryption_config.c_str()); return result; diff --git a/libwifi_system/include/wifi_system/hostapd_manager.h b/libwifi_system/include/wifi_system/hostapd_manager.h index 485267078..a5e1f12f7 100644 --- a/libwifi_system/include/wifi_system/hostapd_manager.h +++ b/libwifi_system/include/wifi_system/hostapd_manager.h @@ -33,6 +33,12 @@ class HostapdManager { kWpa2, // Strongly prefer this if at all possible. }; + enum class BandType { + kBand2G, + kBand5G, + kBandAny, + }; + HostapdManager() = default; virtual ~HostapdManager() = default; @@ -48,7 +54,7 @@ class HostapdManager { // |interface_name| is a network interface name (e.g. "wlan0"). // |ssid| is the SSID used by the configurated network. // |is_hidden| is true iff hostapd should not broadcast the SSID. - // |channel| is the WiFi channel (e.g. 6) or <0 for a default value. + // |band| defines the band which we will choose channel from. // |encryption_type| defines the encryption of the configured network. // |passphrase| is ignored for kOpen networks. // @@ -57,7 +63,7 @@ class HostapdManager { const std::string& interface_name, const std::vector<uint8_t> ssid, bool is_hidden, - int channel, + BandType band, EncryptionType encryption, const std::vector<uint8_t> passphrase); diff --git a/libwifi_system/testlib/include/wifi_system_test/mock_hostapd_manager.h b/libwifi_system/testlib/include/wifi_system_test/mock_hostapd_manager.h index 94ed41b42..3521f9d83 100644 --- a/libwifi_system/testlib/include/wifi_system_test/mock_hostapd_manager.h +++ b/libwifi_system/testlib/include/wifi_system_test/mock_hostapd_manager.h @@ -34,7 +34,7 @@ class MockHostapdManager : public HostapdManager { const std::string& interface_name, const std::vector<uint8_t> ssid, bool is_hidden, - int channel, + BandType band, EncryptionType encryption, const std::vector<uint8_t> passphrase)); MOCK_METHOD1(WriteHostapdConfig, bool(const std::string& config_file)); diff --git a/libwifi_system/tests/hostapd_manager_unittest.cpp b/libwifi_system/tests/hostapd_manager_unittest.cpp index b25dd8ec7..8ef74ff05 100644 --- a/libwifi_system/tests/hostapd_manager_unittest.cpp +++ b/libwifi_system/tests/hostapd_manager_unittest.cpp @@ -34,7 +34,7 @@ namespace { const char kTestInterfaceName[] = "foobar0"; const char kTestSsidStr[] = "helloisitme"; const char kTestPassphraseStr[] = "yourelookingfor"; -const int kTestChannel = 2; +const HostapdManager::BandType kTestBand = HostapdManager::BandType::kBand2G; // If you generate your config file with both the test ssid // and the test passphrase, you'll get this line in the config. @@ -49,7 +49,7 @@ class HostapdManagerTest : public ::testing::Test { kTestInterfaceName, cstr2vector(kTestSsidStr), false, // not hidden - kTestChannel, + kTestBand, encryption_type, cstr2vector(kTestPassphraseStr)); } @@ -66,7 +66,7 @@ void VerifyCommonConfigs(const string& config) { EXPECT_THAT(config, HasSubstr("driver=nl80211\n")); EXPECT_THAT(config, HasSubstr("ctrl_interface=/data/misc/wifi/hostapd/ctrl\n")); EXPECT_THAT(config, HasSubstr("ssid2=68656c6c6f" "6973" "6974" "6d65\n")); - EXPECT_THAT(config, HasSubstr("channel=2\n")); + EXPECT_THAT(config, HasSubstr("channel=0\n")); EXPECT_THAT(config, HasSubstr("hw_mode=g\n")); EXPECT_THAT(config, HasSubstr("wowlan_triggers=any\n")); EXPECT_THAT(config, HasSubstr("ignore_broadcast_ssid=0\n")); @@ -104,23 +104,33 @@ TEST_F(HostapdManagerTest, RespectsHiddenSetting) { kTestInterfaceName, cstr2vector(kTestSsidStr), true, - kTestChannel, + kTestBand, HostapdManager::EncryptionType::kOpen, vector<uint8_t>()); EXPECT_THAT(config, HasSubstr("ignore_broadcast_ssid=1\n")); EXPECT_THAT(config, Not(HasSubstr("ignore_broadcast_ssid=0\n"))); } -TEST_F(HostapdManagerTest, CorrectlyInfersHwMode) { +TEST_F(HostapdManagerTest, CorrectlyInfersHwModeForBand5G) { string config = HostapdManager().CreateHostapdConfig( kTestInterfaceName, cstr2vector(kTestSsidStr), true, - 44, + HostapdManager::BandType::kBand5G, HostapdManager::EncryptionType::kOpen, vector<uint8_t>()); EXPECT_THAT(config, HasSubstr("hw_mode=a\n")); - EXPECT_THAT(config, Not(HasSubstr("hw_mode=g\n"))); +} + +TEST_F(HostapdManagerTest, CorrectlyInfersHwModeForBandAny) { + string config = HostapdManager().CreateHostapdConfig( + kTestInterfaceName, + cstr2vector(kTestSsidStr), + true, + HostapdManager::BandType::kBandAny, + HostapdManager::EncryptionType::kOpen, + vector<uint8_t>()); + EXPECT_THAT(config, HasSubstr("hw_mode=any\n")); } diff --git a/service/java/com/android/server/wifi/WificondControl.java b/service/java/com/android/server/wifi/WificondControl.java index 68da98fb9..5df1e5824 100644 --- a/service/java/com/android/server/wifi/WificondControl.java +++ b/service/java/com/android/server/wifi/WificondControl.java @@ -752,6 +752,13 @@ public class WificondControl implements IBinder.DeathRecipient { return false; } int encryptionType = getIApInterfaceEncryptionType(config); + int bandType; + try { + bandType = getIApInterfaceBandType(config); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unrecognized apBand " + config.apBand); + return false; + } try { // TODO(b/67745880) Note that config.SSID is intended to be either a // hex string or "double quoted". @@ -759,7 +766,7 @@ public class WificondControl implements IBinder.DeathRecipient { // this convention. boolean success = iface.writeHostapdConfig( config.SSID.getBytes(StandardCharsets.UTF_8), config.hiddenSSID, - config.apChannel, encryptionType, + bandType, encryptionType, (config.preSharedKey != null) ? config.preSharedKey.getBytes(StandardCharsets.UTF_8) : new byte[0]); @@ -807,6 +814,17 @@ public class WificondControl implements IBinder.DeathRecipient { return true; } + private static int getIApInterfaceBandType(WifiConfiguration localConfig) { + switch (localConfig.apBand) { + case WifiConfiguration.AP_BAND_2GHZ: + return IApInterface.BAND_2G; + case WifiConfiguration.AP_BAND_5GHZ: + return IApInterface.BAND_5G; + default: + throw new IllegalArgumentException(); + } + } + private static int getIApInterfaceEncryptionType(WifiConfiguration localConfig) { int encryptionType; switch (localConfig.getAuthType()) { diff --git a/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java b/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java index 524324a7e..914222d9f 100644 --- a/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java @@ -830,7 +830,7 @@ public class WificondControlTest { config.allowedKeyManagement.set(WPA_PSK); config.preSharedKey = new String(TEST_PSK, StandardCharsets.UTF_8); config.hiddenSSID = false; - config.apChannel = TEST_FREQUENCY; + config.apBand = WifiConfiguration.AP_BAND_2GHZ; when(mApInterface.writeHostapdConfig( any(byte[].class), anyBoolean(), anyInt(), anyInt(), any(byte[].class))) @@ -840,7 +840,7 @@ public class WificondControlTest { assertTrue(mWificondControl.startSoftAp( TEST_INTERFACE_NAME, config, mSoftApListener)); verify(mApInterface).writeHostapdConfig( - eq(TEST_SSID), eq(false), eq(TEST_FREQUENCY), + eq(TEST_SSID), eq(false), eq(IApInterface.BAND_2G), eq(IApInterface.ENCRYPTION_TYPE_WPA), eq(TEST_PSK)); verify(mApInterface).startHostapd(any()); } @@ -855,7 +855,7 @@ public class WificondControlTest { config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); config.allowedKeyManagement.set(NONE); config.hiddenSSID = true; - config.apChannel = TEST_FREQUENCY; + config.apBand = WifiConfiguration.AP_BAND_5GHZ; when(mApInterface.writeHostapdConfig( any(byte[].class), anyBoolean(), anyInt(), anyInt(), any(byte[].class))) @@ -865,7 +865,7 @@ public class WificondControlTest { assertTrue(mWificondControl.startSoftAp( TEST_INTERFACE_NAME, config, mSoftApListener)); verify(mApInterface).writeHostapdConfig( - eq(TEST_SSID), eq(true), eq(TEST_FREQUENCY), + eq(TEST_SSID), eq(true), eq(IApInterface.BAND_5G), eq(IApInterface.ENCRYPTION_TYPE_NONE), eq(new byte[0])); verify(mApInterface).startHostapd(any()); } @@ -914,6 +914,17 @@ public class WificondControlTest { verify(mApInterface, never()).startHostapd(any()); } + @Test + public void testStartSoftApFailsForInvalidApBand() throws Exception { + testSetupInterfaceForSoftApMode(); + + WifiConfiguration config = new WifiConfiguration(); + config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); + config.apBand = 123456; + assertFalse(mWificondControl.startSoftAp( + TEST_INTERFACE_NAME, config, mSoftApListener)); + } + /** * Verifies soft ap start failure. */ |