diff options
Diffstat (limited to 'wifi')
124 files changed, 5035 insertions, 895 deletions
diff --git a/wifi/1.0/Android.bp b/wifi/1.0/Android.bp index 096fb6cc5..c5ee1bb77 100644 --- a/wifi/1.0/Android.bp +++ b/wifi/1.0/Android.bp @@ -25,90 +25,6 @@ hidl_interface { interfaces: [ "android.hidl.base@1.0", ], - types: [ - "IfaceType", - "NanBandIndex", - "NanBandSpecificConfig", - "NanCapabilities", - "NanCipherSuiteType", - "NanClusterEventInd", - "NanClusterEventType", - "NanConfigRequest", - "NanDataPathChannelCfg", - "NanDataPathConfirmInd", - "NanDataPathRequestInd", - "NanDataPathSecurityConfig", - "NanDataPathSecurityType", - "NanDebugConfig", - "NanDiscoveryCommonConfig", - "NanEnableRequest", - "NanFollowupReceivedInd", - "NanInitiateDataPathRequest", - "NanMatchAlg", - "NanMatchInd", - "NanParamSizeLimits", - "NanPublishRequest", - "NanPublishType", - "NanRangingIndication", - "NanRespondToDataPathIndicationRequest", - "NanSrfType", - "NanStatusType", - "NanSubscribeRequest", - "NanSubscribeType", - "NanTransmitFollowupRequest", - "NanTxType", - "RttBw", - "RttCapabilities", - "RttConfig", - "RttLciInformation", - "RttLcrInformation", - "RttMotionPattern", - "RttPeerType", - "RttPreamble", - "RttResponder", - "RttResult", - "RttStatus", - "RttType", - "StaApfPacketFilterCapabilities", - "StaBackgroundScanBucketEventReportSchemeMask", - "StaBackgroundScanBucketParameters", - "StaBackgroundScanCapabilities", - "StaBackgroundScanParameters", - "StaLinkLayerIfacePacketStats", - "StaLinkLayerIfaceStats", - "StaLinkLayerRadioStats", - "StaLinkLayerStats", - "StaRoamingCapabilities", - "StaRoamingConfig", - "StaRoamingState", - "StaScanData", - "StaScanDataFlagMask", - "StaScanLimits", - "StaScanResult", - "WifiBand", - "WifiChannelInfo", - "WifiChannelWidthInMhz", - "WifiDebugHostWakeReasonRxIcmpPacketDetails", - "WifiDebugHostWakeReasonRxMulticastPacketDetails", - "WifiDebugHostWakeReasonRxPacketDetails", - "WifiDebugHostWakeReasonStats", - "WifiDebugPacketFateFrameInfo", - "WifiDebugPacketFateFrameType", - "WifiDebugRingBufferFlags", - "WifiDebugRingBufferStatus", - "WifiDebugRingBufferVerboseLevel", - "WifiDebugRxPacketFate", - "WifiDebugRxPacketFateReport", - "WifiDebugTxPacketFate", - "WifiDebugTxPacketFateReport", - "WifiInformationElement", - "WifiNanStatus", - "WifiRateInfo", - "WifiRateNss", - "WifiRatePreamble", - "WifiStatus", - "WifiStatusCode", - ], gen_java: true, gen_java_constants: true, } diff --git a/wifi/1.2/default/OWNERS b/wifi/1.0/vts/OWNERS index 8bfb14882..8bfb14882 100644 --- a/wifi/1.2/default/OWNERS +++ b/wifi/1.0/vts/OWNERS diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index b2f76a31a..397ad179a 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -16,7 +16,7 @@ cc_library_static { name: "VtsHalWifiV1_0TargetTestUtil", - defaults: ["hidl_defaults"], + defaults: ["VtsHalTargetTestDefaults"], srcs: [ "wifi_hidl_call_util_selftest.cpp", "wifi_hidl_test.cpp", @@ -26,16 +26,9 @@ cc_library_static { "." ], shared_libs: [ - "libbase", - "liblog", - "libcutils", - "libhidlbase", - "libhidltransport", "libnativehelper", - "libutils", - "android.hardware.wifi@1.0", ], - static_libs: ["VtsHalHidlTargetTestBase"], + static_libs: ["android.hardware.wifi@1.0"], } cc_test { @@ -52,7 +45,11 @@ cc_test { static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", ], + test_suites: ["general-tests"], } cc_test { @@ -66,4 +63,5 @@ cc_test { "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", ], + test_suites: ["general-tests"], } diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp index c0af30bf5..e5762f28f 100644 --- a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -29,17 +29,23 @@ using ::android::hardware::wifi::V1_0::WifiBand; using ::android::hardware::wifi::V1_0::WifiStatusCode; using ::android::sp; +extern WifiHidlEnvironment* gEnv; + /** * Fixture to use for all AP Iface HIDL interface tests. */ class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { + if (!gEnv->isSoftApOn) return; wifi_ap_iface_ = getWifiApIface(); ASSERT_NE(nullptr, wifi_ap_iface_.get()); } - virtual void TearDown() override { stopWifi(); } + virtual void TearDown() override { + if (!gEnv->isSoftApOn) return; + stopWifi(); + } protected: sp<IWifiApIface> wifi_ap_iface_; @@ -51,6 +57,7 @@ class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { * successfully created. */ TEST(WifiApIfaceHidlTestNoFixture, Create) { + if (!gEnv->isSoftApOn) return; EXPECT_NE(nullptr, getWifiApIface().get()); stopWifi(); } @@ -60,6 +67,7 @@ TEST(WifiApIfaceHidlTestNoFixture, Create) { * Ensures that the correct interface type is returned for AP interface. */ TEST_F(WifiApIfaceHidlTest, GetType) { + if (!gEnv->isSoftApOn) return; const auto& status_and_type = HIDL_INVOKE(wifi_ap_iface_, getType); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code); EXPECT_EQ(IfaceType::AP, status_and_type.second); @@ -71,6 +79,7 @@ TEST_F(WifiApIfaceHidlTest, GetType) { * status code. */ TEST_F(WifiApIfaceHidlTest, SetCountryCode) { + if (!gEnv->isSoftApOn) return; const android::hardware::hidl_array<int8_t, 2> kCountryCode{ std::array<int8_t, 2>{{0x55, 0x53}}}; EXPECT_EQ(WifiStatusCode::SUCCESS, @@ -82,6 +91,7 @@ TEST_F(WifiApIfaceHidlTest, SetCountryCode) { * Ensures that we can retrieve valid frequencies for 2.4 GHz band. */ TEST_F(WifiApIfaceHidlTest, GetValidFrequenciesForBand) { + if (!gEnv->isSoftApOn) return; const auto& status_and_freqs = HIDL_INVOKE( wifi_ap_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code); diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp index 14d592707..1b7e82190 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp @@ -17,6 +17,7 @@ #include <android-base/logging.h> #include <android/hardware/wifi/1.0/IWifiChip.h> +#include <android/hardware/wifi/1.3/IWifiChip.h> #include <VtsHalHidlTargetTestBase.h> @@ -87,7 +88,19 @@ class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase { uint32_t configureChipForStaIfaceAndGetCapabilities() { configureChipForIfaceType(IfaceType::STA, true); - const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + + sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted = + ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_); + + std::pair<WifiStatus, uint32_t> status_and_caps; + + if (chip_converted != nullptr) { + // Call the newer HAL version + status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3); + } else { + status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + } + if (status_and_caps.first.code != WifiStatusCode::SUCCESS) { EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_and_caps.first.code); return 0; @@ -352,6 +365,7 @@ TEST_F(WifiChipHidlTest, GetDebugHostWakeReasonStats) { * succeeds. */ TEST_F(WifiChipHidlTest, CreateApIface) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp<IWifiApIface> iface; @@ -366,6 +380,7 @@ TEST_F(WifiChipHidlTest, CreateApIface) { * iface name is returned via the list. */ TEST_F(WifiChipHidlTest, GetApIfaceNames) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); const auto& status_and_iface_names1 = @@ -398,6 +413,7 @@ TEST_F(WifiChipHidlTest, GetApIfaceNames) { * doesn't retrieve an iface object. */ TEST_F(WifiChipHidlTest, GetApIface) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp<IWifiApIface> ap_iface; @@ -424,6 +440,7 @@ TEST_F(WifiChipHidlTest, GetApIface) { * doesn't remove the iface. */ TEST_F(WifiChipHidlTest, RemoveApIface) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp<IWifiApIface> ap_iface; @@ -727,10 +744,10 @@ TEST_F(WifiChipHidlTest, RemoveStaIface) { * CreateRttController */ TEST_F(WifiChipHidlTest, CreateRttController) { - configureChipForIfaceType(IfaceType::AP, true); + configureChipForIfaceType(IfaceType::STA, true); - sp<IWifiApIface> iface; - EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface)); + sp<IWifiStaIface> iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&iface)); EXPECT_NE(nullptr, iface.get()); const auto& status_and_rtt_controller = diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h index 2b1c8ec82..d430ce0be 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h @@ -58,26 +58,33 @@ class WifiHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { public: // Whether NaN feature is supported on the device. bool isNanOn = false; + // Whether SoftAp feature is supported on the device. + bool isSoftApOn = false; void usage(char* me, char* arg) { fprintf(stderr, "unrecognized option: %s\n\n" "usage: %s <gtest options> <test options>\n\n" "test options are:\n\n" - "-N, --nan_on: Whether NAN feature is supported\n", + "-N, --nan_on: Whether NAN feature is supported\n" + "-S, --softap_on: Whether SOFTAP feature is supported\n", arg, me); } int initFromOptions(int argc, char** argv) { static struct option options[] = {{"nan_on", no_argument, 0, 'N'}, + {"softap_on", no_argument, 0, 'S'}, {0, 0, 0, 0}}; int c; - while ((c = getopt_long(argc, argv, "N", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "NS", options, NULL)) >= 0) { switch (c) { case 'N': isNanOn = true; break; + case 'S': + isSoftApOn = true; + break; default: usage(argv[0], argv[optind]); return 2; diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp index 3ced328c0..a41386338 100644 --- a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -17,6 +17,7 @@ #include <android-base/logging.h> #include <android/hardware/wifi/1.0/IWifiStaIface.h> +#include <android/hardware/wifi/1.3/IWifiStaIface.h> #include <VtsHalHidlTargetTestBase.h> @@ -143,6 +144,14 @@ TEST_F(WifiStaIfaceHidlTest, LinkLayerStatsCollection) { return; } + sp<::android::hardware::wifi::V1_3::IWifiStaIface> iface_converted = + ::android::hardware::wifi::V1_3::IWifiStaIface::castFrom( + wifi_sta_iface_); + if (iface_converted != nullptr) { + // Skip this test since this API is deprecated in this newer HAL version + return; + } + // Enable link layer stats collection. EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true) diff --git a/wifi/1.1/vts/OWNERS b/wifi/1.1/vts/OWNERS new file mode 100644 index 000000000..8bfb14882 --- /dev/null +++ b/wifi/1.1/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp index 1b0c12d68..6662314aa 100644 --- a/wifi/1.1/vts/functional/Android.bp +++ b/wifi/1.1/vts/functional/Android.bp @@ -24,5 +24,8 @@ cc_test { "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", ], + test_suites: ["general-tests"], } diff --git a/wifi/1.1/vts/functional/OWNERS b/wifi/1.1/vts/functional/OWNERS deleted file mode 100644 index 2878acc7f..000000000 --- a/wifi/1.1/vts/functional/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -rpius@google.com -quiche@google.com diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp index d3a983cc8..63235472a 100644 --- a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp @@ -18,6 +18,7 @@ #include <android/hardware/wifi/1.1/IWifi.h> #include <android/hardware/wifi/1.1/IWifiChip.h> +#include <android/hardware/wifi/1.3/IWifiChip.h> #include <VtsHalHidlTargetTestBase.h> @@ -58,7 +59,19 @@ class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase { ChipModeId mode_id; EXPECT_TRUE(configureChipToSupportIfaceType( wifi_chip_, IfaceType::STA, &mode_id)); - const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + + sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted = + ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_); + + std::pair<WifiStatus, uint32_t> status_and_caps; + + if (chip_converted != nullptr) { + // Call the newer HAL version + status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3); + } else { + status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + } + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); return status_and_caps.second; } diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp index c144f22a1..1863eaf5e 100644 --- a/wifi/1.2/Android.bp +++ b/wifi/1.2/Android.bp @@ -20,12 +20,6 @@ hidl_interface { "android.hardware.wifi@1.1", "android.hidl.base@1.0", ], - types: [ - "NanConfigRequestSupplemental", - "NanDataPathChannelInfo", - "NanDataPathConfirmInd", - "NanDataPathScheduleUpdateInd", - ], gen_java: true, } diff --git a/wifi/1.2/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.2/default/tests/hidl_struct_util_unit_tests.cpp deleted file mode 100644 index 1d6e9e4a1..000000000 --- a/wifi/1.2/default/tests/hidl_struct_util_unit_tests.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <android-base/logging.h> -#include <android-base/macros.h> -#include <gmock/gmock.h> - -#undef NAN -#include "hidl_struct_util.h" - -using testing::Test; - -namespace { -constexpr uint32_t kMacId1 = 1; -constexpr uint32_t kMacId2 = 2; -constexpr uint32_t kIfaceChannel1 = 3; -constexpr uint32_t kIfaceChannel2 = 5; -constexpr char kIfaceName1[] = "wlan0"; -constexpr char kIfaceName2[] = "wlan1"; -} // namespace -namespace android { -namespace hardware { -namespace wifi { -namespace V1_2 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -class HidlStructUtilTest : public Test {}; - -TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { - std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos; - legacy_hal::WifiMacInfo legacy_mac_info1 = { - .wlan_mac_id = kMacId1, - .mac_band = - legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, - .channel = kIfaceChannel1}; - legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, - .channel = kIfaceChannel2}; - legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); - legacy_mac_info1.iface_infos.push_back(legacy_iface_info2); - legacy_mac_infos.push_back(legacy_mac_info1); - - std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos; - ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( - legacy_mac_infos, &hidl_radio_mode_infos)); - - ASSERT_EQ(1u, hidl_radio_mode_infos.size()); - auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0]; - EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId); - EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo); - ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size()); - auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0]; - EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), - hidl_iface_info1.channel); - auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1]; - EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), - hidl_iface_info2.channel); -} - -TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { - std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos; - legacy_hal::WifiMacInfo legacy_mac_info1 = { - .wlan_mac_id = kMacId1, .mac_band = legacy_hal::WLAN_MAC_5_0_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, - .channel = kIfaceChannel1}; - legacy_hal::WifiMacInfo legacy_mac_info2 = { - .wlan_mac_id = kMacId2, .mac_band = legacy_hal::WLAN_MAC_2_4_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, - .channel = kIfaceChannel2}; - legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); - legacy_mac_infos.push_back(legacy_mac_info1); - legacy_mac_info2.iface_infos.push_back(legacy_iface_info2); - legacy_mac_infos.push_back(legacy_mac_info2); - - std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos; - ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( - legacy_mac_infos, &hidl_radio_mode_infos)); - - ASSERT_EQ(2u, hidl_radio_mode_infos.size()); - - // Find mac info 1. - const auto hidl_radio_mode_info1 = std::find_if( - hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), - [&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info1.wlan_mac_id; - }); - ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1); - EXPECT_EQ(WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo); - ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size()); - auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0]; - EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), - hidl_iface_info1.channel); - - // Find mac info 2. - const auto hidl_radio_mode_info2 = std::find_if( - hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), - [&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info2.wlan_mac_id; - }); - ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2); - EXPECT_EQ(WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo); - ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size()); - auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0]; - EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), - hidl_iface_info2.channel); -} -} // namespace implementation -} // namespace V1_2 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.2/default/tests/runtests.sh b/wifi/1.2/default/tests/runtests.sh deleted file mode 100755 index 966a6a751..000000000 --- a/wifi/1.2/default/tests/runtests.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -# Copyright(C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0(the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http:// www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -if [ -z $ANDROID_BUILD_TOP ]; then - echo "You need to source and lunch before you can use this script" - exit 1 -fi - -echo "Running tests" -set -e # fail early - -#NOTE We can't actually run these commands, since they rely on functions added by -#build / envsetup.sh to the bash shell environment. -echo "+ mmma -j32 $ANDROID_BUILD_TOP/" -make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk \ - MODULES-IN-hardware-interfaces-wifi-1.2-default - -set -x # print commands - -adb wait-for-device -adb root -adb wait-for-device - -#'disable-verity' will appear in 'adb remount' output if -#dm - verity is enabled and needs to be disabled. -if adb remount | grep 'disable-verity'; then - adb disable-verity - adb reboot - adb wait-for-device - adb root - adb wait-for-device - adb remount -fi - -adb sync - -adb shell /data/nativetest/vendor/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests diff --git a/wifi/1.2/default/wifi_feature_flags.cpp b/wifi/1.2/default/wifi_feature_flags.cpp deleted file mode 100644 index 778944dd9..000000000 --- a/wifi/1.2/default/wifi_feature_flags.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "wifi_feature_flags.h" - -namespace { -#ifdef WIFI_HIDL_FEATURE_AWARE -static const bool wifiHidlFeatureAware = true; -#else -static const bool wifiHidlFeatureAware = false; -#endif // WIFI_HIDL_FEATURE_AWARE -#ifdef WIFI_HIDL_FEATURE_DUAL_INTERFACE -static const bool wifiHidlFeatureDualInterface = true; -#else -static const bool wifiHidlFeatureDualInterface = false; -#endif // WIFI_HIDL_FEATURE_DUAL_INTERFACE -#ifdef WIFI_HIDL_FEATURE_DISABLE_AP -static const bool wifiHidlFeatureDisableAp = true; -#else -static const bool wifiHidlFeatureDisableAp = false; -#endif // WIFI_HIDL_FEATURE_DISABLE_AP - -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_2 { -namespace implementation { -namespace feature_flags { - -WifiFeatureFlags::WifiFeatureFlags() {} -bool WifiFeatureFlags::isAwareSupported() { return wifiHidlFeatureAware; } -bool WifiFeatureFlags::isDualInterfaceSupported() { - return wifiHidlFeatureDualInterface; -} -bool WifiFeatureFlags::isApDisabled() { - return wifiHidlFeatureDisableAp; -} - -} // namespace feature_flags -} // namespace implementation -} // namespace V1_2 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.2/vts/OWNERS b/wifi/1.2/vts/OWNERS index 811c85794..8bfb14882 100644 --- a/wifi/1.2/vts/OWNERS +++ b/wifi/1.2/vts/OWNERS @@ -1,4 +1,2 @@ rpius@google.com -quiche@google.com -arabawy@google.com -yim@google.com
\ No newline at end of file +etancohen@google.com diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp index c5a6e8417..b2956ce3c 100644 --- a/wifi/1.2/vts/functional/Android.bp +++ b/wifi/1.2/vts/functional/Android.bp @@ -27,7 +27,9 @@ cc_test { "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", ], + test_suites: ["general-tests"], } cc_test { @@ -43,4 +45,5 @@ cc_test { "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", ], + test_suites: ["general-tests"], } diff --git a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp index a5457b761..9d567feaf 100644 --- a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp @@ -18,6 +18,7 @@ #include <android/hardware/wifi/1.2/IWifiChip.h> #include <android/hardware/wifi/1.2/IWifiChipEventCallback.h> +#include <android/hardware/wifi/1.3/IWifiChip.h> #include <VtsHalHidlTargetCallbackBase.h> #include <VtsHalHidlTargetTestBase.h> @@ -104,7 +105,19 @@ class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase { ChipModeId mode_id; EXPECT_TRUE( configureChipToSupportIfaceType(wifi_chip_, IfaceType::STA, &mode_id)); - const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + + sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted = + ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_); + + std::pair<WifiStatus, uint32_t> status_and_caps; + + if (chip_converted != nullptr) { + // Call the newer HAL version + status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3); + } else { + status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + } + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); return status_and_caps.second; } diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp new file mode 100644 index 000000000..401c7a618 --- /dev/null +++ b/wifi/1.3/Android.bp @@ -0,0 +1,23 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.wifi@1.3", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "types.hal", + "IWifi.hal", + "IWifiChip.hal", + "IWifiStaIface.hal", + ], + interfaces: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hidl.base@1.0", + ], + gen_java: true, +} + diff --git a/wifi/1.3/IWifi.hal b/wifi/1.3/IWifi.hal new file mode 100644 index 000000000..298e722a7 --- /dev/null +++ b/wifi/1.3/IWifi.hal @@ -0,0 +1,28 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.3; + +import @1.2::IWifi; + +/** + * This is the root of the HAL module and is the interface returned when + * loading an implementation of the Wi-Fi HAL. There must be at most one + * module loaded in the system. + * IWifi.getChip() must return @1.2::IWifiChip + */ +interface IWifi extends @1.2::IWifi { +}; diff --git a/wifi/1.3/IWifiChip.hal b/wifi/1.3/IWifiChip.hal new file mode 100644 index 000000000..72cee899b --- /dev/null +++ b/wifi/1.3/IWifiChip.hal @@ -0,0 +1,91 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.3; + +import @1.0::WifiStatus; +import @1.2::IWifiChip; + +/** + * Interface that represents a chip that must be configured as a single unit. + */ +interface IWifiChip extends @1.2::IWifiChip { + + /** + * Capabilities exposed by this chip. + */ + enum ChipCapabilityMask : @1.2::IWifiChip.ChipCapabilityMask { + /** + * Set Latency Mode. + */ + SET_LATENCY_MODE = 1 << 12, + + /** + * Support P2P MAC randomization + */ + P2P_RAND_MAC = 1 << 13 + }; + + /** + * Get the capabilities supported by this chip. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + * @return capabilities Bitset of |ChipCapabilityMask| values. + */ + getCapabilities_1_3() + generates (WifiStatus status, bitfield<ChipCapabilityMask> capabilities); + + /** + * This enum represents the different latency modes that can be set through + * setLatencyMode() + */ + enum LatencyMode : uint32_t { + NORMAL = 0, + LOW = 1 + }; + + /** + * API to set the wifi latency mode + * + * The latency mode is a hint to the HAL to enable or disable Wi-Fi latency + * optimization. The optimization should be enabled if the mode is set to |LOW| + * and should be disabled if the mode is set to |NORMAL|. + * Wi-Fi latency optimization may trade-off latency against other Wi-Fi + * functionality such as scanning, roaming, etc. but it should not result in + * completely halting this functionality. + * + * The low latency mode targets applications such as gaming and virtual reality. + */ + setLatencyMode(LatencyMode mode) generates (WifiStatus status); + + /** + * API to flush debug ring buffer data to files. + * + * Force flush debug ring buffer using IBase::debug. + * This API help to collect firmware/driver/pkt logs. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.UNKNOWN| + */ + flushRingBufferToFile() generates (WifiStatus status); +}; diff --git a/wifi/1.3/IWifiStaIface.hal b/wifi/1.3/IWifiStaIface.hal new file mode 100644 index 000000000..81c0c3869 --- /dev/null +++ b/wifi/1.3/IWifiStaIface.hal @@ -0,0 +1,56 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.3; + +import @1.0::WifiStatus; +import @1.0::MacAddress; +import @1.2::IWifiStaIface; + +/** + * Interface used to represent a single STA iface. + * + * IWifiChip.createStaIface() may return a @1.3::IWifiStaIface when supported. + */ +interface IWifiStaIface extends @1.2::IWifiStaIface { + /** + * Retrieve the latest link layer stats. + * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set or if + * link layer stats collection hasn't been explicitly enabled. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_NOT_STARTED|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + * @return stats Instance of |LinkLayerStats|. + */ + getLinkLayerStats_1_3() generates (WifiStatus status, StaLinkLayerStats stats); + + /** + * Gets the factory MAC address of the Sta Interface + * @return status WifiStatus of the operation + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_UNKNOWN| + * @return mac Factory MAC address of the Sta Interface + */ + getFactoryMacAddress() generates (WifiStatus status, MacAddress mac); +}; diff --git a/wifi/1.2/default/Android.mk b/wifi/1.3/default/Android.mk index 391969018..199ea3b9f 100644 --- a/wifi/1.2/default/Android.mk +++ b/wifi/1.3/default/Android.mk @@ -21,6 +21,9 @@ LOCAL_MODULE := android.hardware.wifi@1.0-service-lib LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_PROPRIETARY_MODULE := true LOCAL_CPPFLAGS := -Wall -Werror -Wextra +ifdef WIFI_HAL_INTERFACE_COMBINATIONS +LOCAL_CPPFLAGS += -DWIFI_HAL_INTERFACE_COMBINATIONS="$(WIFI_HAL_INTERFACE_COMBINATIONS)" +endif ifdef WIFI_HIDL_FEATURE_AWARE LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_AWARE endif @@ -30,6 +33,11 @@ endif ifdef WIFI_HIDL_FEATURE_DISABLE_AP LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP endif +ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION +LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION +endif +# Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed. +LOCAL_CFLAGS += -Wno-error=implicit-fallthrough LOCAL_SRC_FILES := \ hidl_struct_util.cpp \ hidl_sync_util.cpp \ @@ -38,6 +46,7 @@ LOCAL_SRC_FILES := \ wifi_ap_iface.cpp \ wifi_chip.cpp \ wifi_feature_flags.cpp \ + wifi_iface_util.cpp \ wifi_legacy_hal.cpp \ wifi_legacy_hal_stubs.cpp \ wifi_mode_controller.cpp \ @@ -58,7 +67,8 @@ LOCAL_SHARED_LIBRARIES := \ libwifi-system-iface \ android.hardware.wifi@1.0 \ android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY) @@ -84,34 +94,70 @@ LOCAL_SHARED_LIBRARIES := \ libwifi-system-iface \ android.hardware.wifi@1.0 \ android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 LOCAL_STATIC_LIBRARIES := \ android.hardware.wifi@1.0-service-lib LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc include $(BUILD_EXECUTABLE) ### +### android.hardware.wifi daemon +### +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.wifi@1.0-service-lazy +LOCAL_OVERRIDES_MODULES := android.hardware.wifi@1.0-service +LOCAL_CFLAGS := -DLAZY_SERVICE +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_PROPRIETARY_MODULE := true +LOCAL_CPPFLAGS := -Wall -Werror -Wextra +LOCAL_SRC_FILES := \ + service.cpp +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libcutils \ + libhidlbase \ + libhidltransport \ + liblog \ + libnl \ + libutils \ + libwifi-hal \ + libwifi-system-iface \ + android.hardware.wifi@1.0 \ + android.hardware.wifi@1.1 \ + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 +LOCAL_STATIC_LIBRARIES := \ + android.hardware.wifi@1.0-service-lib +LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc +include $(BUILD_EXECUTABLE) + +### ### android.hardware.wifi unit tests. ### include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.wifi@1.0-service-tests LOCAL_PROPRIETARY_MODULE := true +LOCAL_CPPFLAGS := -Wall -Werror -Wextra LOCAL_SRC_FILES := \ tests/hidl_struct_util_unit_tests.cpp \ tests/main.cpp \ tests/mock_wifi_feature_flags.cpp \ + tests/mock_wifi_iface_util.cpp \ tests/mock_wifi_legacy_hal.cpp \ tests/mock_wifi_mode_controller.cpp \ tests/ringbuffer_unit_tests.cpp \ - tests/wifi_chip_unit_tests.cpp + tests/wifi_ap_iface_unit_tests.cpp \ + tests/wifi_chip_unit_tests.cpp \ + tests/wifi_iface_util_unit_tests.cpp LOCAL_STATIC_LIBRARIES := \ libgmock \ libgtest \ + libhidlbase \ android.hardware.wifi@1.0-service-lib LOCAL_SHARED_LIBRARIES := \ libbase \ libcutils \ - libhidlbase \ libhidltransport \ liblog \ libnl \ @@ -120,5 +166,6 @@ LOCAL_SHARED_LIBRARIES := \ libwifi-system-iface \ android.hardware.wifi@1.0 \ android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 include $(BUILD_NATIVE_TEST) diff --git a/wifi/1.3/default/OWNERS b/wifi/1.3/default/OWNERS new file mode 100644 index 000000000..8bfb14882 --- /dev/null +++ b/wifi/1.3/default/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/1.2/default/THREADING.README b/wifi/1.3/default/THREADING.README index 8366ca020..8366ca020 100644 --- a/wifi/1.2/default/THREADING.README +++ b/wifi/1.3/default/THREADING.README diff --git a/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc new file mode 100644 index 000000000..cf917b545 --- /dev/null +++ b/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc @@ -0,0 +1,8 @@ +service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy + interface android.hardware.wifi@1.0::IWifi default + oneshot + disabled + class hal + capabilities NET_ADMIN NET_RAW SYS_MODULE + user wifi + group wifi gps diff --git a/wifi/1.2/default/android.hardware.wifi@1.0-service.rc b/wifi/1.3/default/android.hardware.wifi@1.0-service.rc index cf849d04a..cf849d04a 100644 --- a/wifi/1.2/default/android.hardware.wifi@1.0-service.rc +++ b/wifi/1.3/default/android.hardware.wifi@1.0-service.rc diff --git a/wifi/1.2/default/hidl_callback_util.h b/wifi/1.3/default/hidl_callback_util.h index 97f312a60..a44af79fe 100644 --- a/wifi/1.2/default/hidl_callback_util.h +++ b/wifi/1.3/default/hidl_callback_util.h @@ -52,7 +52,7 @@ class HidlDeathHandler : public android::hardware::hidl_death_recipient { namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace hidl_callback_util { template <typename CallbackType> @@ -117,7 +117,7 @@ class HidlCallbackHandler { } // namespace hidl_callback_util } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/hidl_return_util.h b/wifi/1.3/default/hidl_return_util.h index 914c1b4ed..9707444fe 100644 --- a/wifi/1.2/default/hidl_return_util.h +++ b/wifi/1.3/default/hidl_return_util.h @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace hidl_return_util { using namespace android::hardware::wifi::V1_0; @@ -113,7 +113,7 @@ Return<void> validateAndCall( } // namespace hidl_return_util } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/hidl_struct_util.cpp b/wifi/1.3/default/hidl_struct_util.cpp index 39ac544e6..2e4db7048 100644 --- a/wifi/1.2/default/hidl_struct_util.cpp +++ b/wifi/1.3/default/hidl_struct_util.cpp @@ -22,7 +22,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace hidl_struct_util { @@ -69,9 +69,9 @@ convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) { return {}; } -IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( +V1_3::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( uint32_t feature) { - using HidlChipCaps = IWifiChip::ChipCapabilityMask; + using HidlChipCaps = V1_3::IWifiChip::ChipCapabilityMask; switch (feature) { case WIFI_FEATURE_SET_TX_POWER_LIMIT: return HidlChipCaps::SET_TX_POWER_LIMIT; @@ -81,6 +81,10 @@ IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( return HidlChipCaps::D2D_RTT; case WIFI_FEATURE_D2AP_RTT: return HidlChipCaps::D2AP_RTT; + case WIFI_FEATURE_SET_LATENCY_MODE: + return HidlChipCaps::SET_LATENCY_MODE; + case WIFI_FEATURE_P2P_RAND_MAC: + return HidlChipCaps::P2P_RAND_MAC; }; CHECK(false) << "Unknown legacy feature: " << feature; return {}; @@ -139,13 +143,18 @@ bool convertLegacyFeaturesToHidlChipCapabilities( convertLegacyLoggerFeatureToHidlChipCapability(feature); } } - for (const auto feature : {WIFI_FEATURE_SET_TX_POWER_LIMIT, - WIFI_FEATURE_USE_BODY_HEAD_SAR, - WIFI_FEATURE_D2D_RTT, WIFI_FEATURE_D2AP_RTT}) { + std::vector<uint32_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT, + WIFI_FEATURE_USE_BODY_HEAD_SAR, + WIFI_FEATURE_D2D_RTT, + WIFI_FEATURE_D2AP_RTT, + WIFI_FEATURE_SET_LATENCY_MODE, + WIFI_FEATURE_P2P_RAND_MAC}; + for (const auto feature : features) { if (feature & legacy_feature_set) { *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature); } } + // There are no flags for these 3 in the legacy feature set. Adding them to // the set because all the current devices support it. *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA; @@ -267,34 +276,45 @@ legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( V1_1::IWifiChip::TxPowerScenario hidl_scenario) { switch (hidl_scenario) { // This is the only supported scenario for V1_1 - case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL: + case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL: return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL; }; CHECK(false); } legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( - IWifiChip::TxPowerScenario hidl_scenario) { + V1_2::IWifiChip::TxPowerScenario hidl_scenario) { switch (hidl_scenario) { // This is the only supported scenario for V1_1 - case IWifiChip::TxPowerScenario::VOICE_CALL: + case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL: return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL; // Those are the supported scenarios for V1_2 - case IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF: + case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF: return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; - case IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON: + case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON: return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; - case IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF: + case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF: return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; - case IWifiChip::TxPowerScenario::ON_BODY_CELL_ON: + case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_ON: return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; }; CHECK(false); } +legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( + IWifiChip::LatencyMode hidl_latency_mode) { + switch (hidl_latency_mode) { + case IWifiChip::LatencyMode::NORMAL: + return legacy_hal::WIFI_LATENCY_MODE_NORMAL; + case IWifiChip::LatencyMode::LOW: + return legacy_hal::WIFI_LATENCY_MODE_LOW; + } + CHECK(false); +} + bool convertLegacyWifiMacInfoToHidl( const legacy_hal::WifiMacInfo& legacy_mac_info, - IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { + V1_2::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { if (!hidl_radio_mode_info) { return false; } @@ -313,9 +333,9 @@ bool convertLegacyWifiMacInfoToHidl( } else { hidl_radio_mode_info->bandInfo = WifiBand::BAND_UNSPECIFIED; } - std::vector<IWifiChipEventCallback::IfaceInfo> iface_info_vec; + std::vector<V1_2::IWifiChipEventCallback::IfaceInfo> iface_info_vec; for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) { - IWifiChipEventCallback::IfaceInfo iface_info; + V1_2::IWifiChipEventCallback::IfaceInfo iface_info; iface_info.name = legacy_iface_info.name; iface_info.channel = legacy_iface_info.channel; iface_info_vec.push_back(iface_info); @@ -326,14 +346,15 @@ bool convertLegacyWifiMacInfoToHidl( bool convertLegacyWifiMacInfosToHidl( const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, - std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) { + std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>* + hidl_radio_mode_infos) { if (!hidl_radio_mode_infos) { return false; } *hidl_radio_mode_infos = {}; for (const auto& legacy_mac_info : legacy_mac_infos) { - IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; + V1_2::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) { return false; @@ -782,9 +803,58 @@ bool convertLegacyVectorOfDebugRxPacketFateToHidl( return true; } +bool convertLegacyLinkLayerRadioStatsToHidl( + const legacy_hal::LinkLayerRadioStats& legacy_radio_stat, + V1_3::StaLinkLayerRadioStats* hidl_radio_stat) { + if (!hidl_radio_stat) { + return false; + } + *hidl_radio_stat = {}; + + hidl_radio_stat->V1_0.onTimeInMs = legacy_radio_stat.stats.on_time; + hidl_radio_stat->V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time; + hidl_radio_stat->V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time; + hidl_radio_stat->V1_0.onTimeInMsForScan = + legacy_radio_stat.stats.on_time_scan; + hidl_radio_stat->V1_0.txTimeInMsPerLevel = + legacy_radio_stat.tx_time_per_levels; + hidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd; + hidl_radio_stat->onTimeInMsForBgScan = + legacy_radio_stat.stats.on_time_gscan; + hidl_radio_stat->onTimeInMsForRoamScan = + legacy_radio_stat.stats.on_time_roam_scan; + hidl_radio_stat->onTimeInMsForPnoScan = + legacy_radio_stat.stats.on_time_pno_scan; + hidl_radio_stat->onTimeInMsForHs20Scan = + legacy_radio_stat.stats.on_time_hs20; + + std::vector<V1_3::WifiChannelStats> hidl_channel_stats; + + for (const auto& channel_stat : legacy_radio_stat.channel_stats) { + V1_3::WifiChannelStats hidl_channel_stat; + hidl_channel_stat.onTimeInMs = channel_stat.on_time; + hidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time; + /* + * TODO once b/119142899 is fixed, + * replace below code with convertLegacyWifiChannelInfoToHidl() + */ + hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20; + hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq; + hidl_channel_stat.channel.centerFreq0 = + channel_stat.channel.center_freq0; + hidl_channel_stat.channel.centerFreq1 = + channel_stat.channel.center_freq1; + hidl_channel_stats.push_back(hidl_channel_stat); + } + + hidl_radio_stat->channelStats = hidl_channel_stats; + + return true; +} + bool convertLegacyLinkLayerStatsToHidl( const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats) { + V1_3::StaLinkLayerStats* hidl_stats) { if (!hidl_stats) { return false; } @@ -825,16 +895,13 @@ bool convertLegacyLinkLayerStatsToHidl( hidl_stats->iface.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; // radio legacy_stats conversion. - std::vector<StaLinkLayerRadioStats> hidl_radios_stats; + std::vector<V1_3::StaLinkLayerRadioStats> hidl_radios_stats; for (const auto& legacy_radio_stats : legacy_stats.radios) { - StaLinkLayerRadioStats hidl_radio_stats; - hidl_radio_stats.onTimeInMs = legacy_radio_stats.stats.on_time; - hidl_radio_stats.txTimeInMs = legacy_radio_stats.stats.tx_time; - hidl_radio_stats.rxTimeInMs = legacy_radio_stats.stats.rx_time; - hidl_radio_stats.onTimeInMsForScan = - legacy_radio_stats.stats.on_time_scan; - hidl_radio_stats.txTimeInMsPerLevel = - legacy_radio_stats.tx_time_per_levels; + V1_3::StaLinkLayerRadioStats hidl_radio_stats; + if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, + &hidl_radio_stats)) { + return false; + } hidl_radios_stats.push_back(hidl_radio_stats); } hidl_stats->radios = hidl_radios_stats; @@ -1197,7 +1264,7 @@ bool convertHidlNanEnableRequestToLegacy( bool convertHidlNanEnableRequest_1_2ToLegacy( const NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, + const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) @@ -1708,7 +1775,7 @@ bool convertHidlNanConfigRequestToLegacy( bool convertHidlNanConfigRequest_1_2ToLegacy( const NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, + const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanConfigRequest_1_2ToLegacy: legacy_request " @@ -2039,7 +2106,7 @@ bool convertLegacyNanDataPathRequestIndToHidl( bool convertLegacyNdpChannelInfoToHidl( const legacy_hal::NanChannelInfo& legacy_struct, - NanDataPathChannelInfo* hidl_struct) { + V1_2::NanDataPathChannelInfo* hidl_struct) { if (!hidl_struct) { LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null"; return false; @@ -2056,7 +2123,7 @@ bool convertLegacyNdpChannelInfoToHidl( bool convertLegacyNanDataPathConfirmIndToHidl( const legacy_hal::NanDataPathConfirmInd& legacy_ind, - NanDataPathConfirmInd* hidl_ind) { + V1_2::NanDataPathConfirmInd* hidl_ind) { if (!hidl_ind) { LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null"; @@ -2077,9 +2144,9 @@ bool convertLegacyNanDataPathConfirmIndToHidl( convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code); hidl_ind->V1_0.status.description = ""; // TODO: b/34059183 - std::vector<NanDataPathChannelInfo> channelInfo; + std::vector<V1_2::NanDataPathChannelInfo> channelInfo; for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { - NanDataPathChannelInfo hidl_struct; + V1_2::NanDataPathChannelInfo hidl_struct; if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) { return false; @@ -2093,7 +2160,7 @@ bool convertLegacyNanDataPathConfirmIndToHidl( bool convertLegacyNanDataPathScheduleUpdateIndToHidl( const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, - NanDataPathScheduleUpdateInd* hidl_ind) { + V1_2::NanDataPathScheduleUpdateInd* hidl_ind) { if (!hidl_ind) { LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: " "hidl_ind is null"; @@ -2103,9 +2170,9 @@ bool convertLegacyNanDataPathScheduleUpdateIndToHidl( hidl_ind->peerDiscoveryAddress = hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr); - std::vector<NanDataPathChannelInfo> channelInfo; + std::vector<V1_2::NanDataPathChannelInfo> channelInfo; for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { - NanDataPathChannelInfo hidl_struct; + V1_2::NanDataPathChannelInfo hidl_struct; if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) { return false; @@ -2616,7 +2683,7 @@ bool convertLegacyVectorOfRttResultToHidl( } } // namespace hidl_struct_util } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/hidl_struct_util.h b/wifi/1.3/default/hidl_struct_util.h index 3c789c046..3eefd9592 100644 --- a/wifi/1.2/default/hidl_struct_util.h +++ b/wifi/1.3/default/hidl_struct_util.h @@ -21,9 +21,10 @@ #include <android/hardware/wifi/1.0/IWifiChip.h> #include <android/hardware/wifi/1.0/types.h> -#include <android/hardware/wifi/1.2/IWifiChip.h> #include <android/hardware/wifi/1.2/IWifiChipEventCallback.h> #include <android/hardware/wifi/1.2/types.h> +#include <android/hardware/wifi/1.3/IWifiChip.h> +#include <android/hardware/wifi/1.3/types.h> #include "wifi_legacy_hal.h" @@ -36,7 +37,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace hidl_struct_util { using namespace android::hardware::wifi::V1_0; @@ -56,11 +57,14 @@ bool convertLegacyWakeReasonStatsToHidl( WifiDebugHostWakeReasonStats* hidl_stats); legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( V1_1::IWifiChip::TxPowerScenario hidl_scenario); +legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( + V1_3::IWifiChip::LatencyMode hidl_latency_mode); legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( - IWifiChip::TxPowerScenario hidl_scenario); + V1_2::IWifiChip::TxPowerScenario hidl_scenario); bool convertLegacyWifiMacInfosToHidl( const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, - std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos); + std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>* + hidl_radio_mode_infos); // STA iface conversion methods. bool convertLegacyFeaturesToHidlStaCapabilities( @@ -88,7 +92,7 @@ bool convertLegacyVectorOfCachedGscanResultsToHidl( std::vector<StaScanData>* hidl_scan_datas); bool convertLegacyLinkLayerStatsToHidl( const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats); + V1_3::StaLinkLayerStats* hidl_stats); bool convertLegacyRoamingCapabilitiesToHidl( const legacy_hal::wifi_roaming_capabilities& legacy_caps, StaRoamingCapabilities* hidl_caps); @@ -115,11 +119,11 @@ bool convertHidlNanConfigRequestToLegacy( legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanEnableRequest_1_2ToLegacy( const NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, + const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request); bool convertHidlNanConfigRequest_1_2ToLegacy( const NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, + const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanPublishRequestToLegacy( const NanPublishRequest& hidl_request, @@ -152,10 +156,10 @@ bool convertLegacyNanDataPathRequestIndToHidl( NanDataPathRequestInd* hidl_ind); bool convertLegacyNanDataPathConfirmIndToHidl( const legacy_hal::NanDataPathConfirmInd& legacy_ind, - NanDataPathConfirmInd* hidl_ind); + V1_2::NanDataPathConfirmInd* hidl_ind); bool convertLegacyNanDataPathScheduleUpdateIndToHidl( const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, - NanDataPathScheduleUpdateInd* hidl_ind); + V1_2::NanDataPathScheduleUpdateInd* hidl_ind); // RTT controller conversion methods. bool convertHidlVectorOfRttConfigToLegacy( @@ -184,7 +188,7 @@ bool convertLegacyVectorOfRttResultToHidl( std::vector<RttResult>* hidl_results); } // namespace hidl_struct_util } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/hidl_sync_util.cpp b/wifi/1.3/default/hidl_sync_util.cpp index ad8448a17..160727f60 100644 --- a/wifi/1.2/default/hidl_sync_util.cpp +++ b/wifi/1.3/default/hidl_sync_util.cpp @@ -23,7 +23,7 @@ std::recursive_mutex g_mutex; namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace hidl_sync_util { @@ -33,7 +33,7 @@ std::unique_lock<std::recursive_mutex> acquireGlobalLock() { } // namespace hidl_sync_util } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/hidl_sync_util.h b/wifi/1.3/default/hidl_sync_util.h index 838186278..ebfb05144 100644 --- a/wifi/1.2/default/hidl_sync_util.h +++ b/wifi/1.3/default/hidl_sync_util.h @@ -24,13 +24,13 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace hidl_sync_util { std::unique_lock<std::recursive_mutex> acquireGlobalLock(); } // namespace hidl_sync_util } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/ringbuffer.cpp b/wifi/1.3/default/ringbuffer.cpp index c126b3691..1294c5298 100644 --- a/wifi/1.2/default/ringbuffer.cpp +++ b/wifi/1.3/default/ringbuffer.cpp @@ -21,7 +21,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {} @@ -48,7 +48,7 @@ const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const { } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/ringbuffer.h b/wifi/1.3/default/ringbuffer.h index 4808e40b7..d9f8df685 100644 --- a/wifi/1.2/default/ringbuffer.h +++ b/wifi/1.3/default/ringbuffer.h @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { /** @@ -45,7 +45,7 @@ class Ringbuffer { }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/service.cpp b/wifi/1.3/default/service.cpp index 01d22bd88..73015cf05 100644 --- a/wifi/1.2/default/service.cpp +++ b/wifi/1.3/default/service.cpp @@ -15,6 +15,7 @@ */ #include <android-base/logging.h> +#include <hidl/HidlLazyUtils.h> #include <hidl/HidlTransportSupport.h> #include <utils/Looper.h> #include <utils/StrongPointer.h> @@ -26,12 +27,20 @@ using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; -using android::hardware::wifi::V1_2::implementation::feature_flags:: +using android::hardware::LazyServiceRegistrar; +using android::hardware::wifi::V1_3::implementation::feature_flags:: WifiFeatureFlags; -using android::hardware::wifi::V1_2::implementation::legacy_hal::WifiLegacyHal; -using android::hardware::wifi::V1_2::implementation::mode_controller:: +using android::hardware::wifi::V1_3::implementation::iface_util::WifiIfaceUtil; +using android::hardware::wifi::V1_3::implementation::legacy_hal::WifiLegacyHal; +using android::hardware::wifi::V1_3::implementation::mode_controller:: WifiModeController; +#ifdef LAZY_SERVICE +const bool kLazyService = true; +#else +const bool kLazyService = false; +#endif + int main(int /*argc*/, char** argv) { android::base::InitLogging( argv, android::base::LogdLogger(android::base::SYSTEM)); @@ -40,13 +49,20 @@ int main(int /*argc*/, char** argv) { configureRpcThreadpool(1, true /* callerWillJoin */); // Setup hwbinder service - android::sp<android::hardware::wifi::V1_2::IWifi> service = - new android::hardware::wifi::V1_2::implementation::Wifi( + android::sp<android::hardware::wifi::V1_3::IWifi> service = + new android::hardware::wifi::V1_3::implementation::Wifi( std::make_shared<WifiLegacyHal>(), std::make_shared<WifiModeController>(), + std::make_shared<WifiIfaceUtil>(), std::make_shared<WifiFeatureFlags>()); - CHECK_EQ(service->registerAsService(), android::NO_ERROR) - << "Failed to register wifi HAL"; + if (kLazyService) { + LazyServiceRegistrar registrar; + CHECK_EQ(registrar.registerService(service), android::NO_ERROR) + << "Failed to register wifi HAL"; + } else { + CHECK_EQ(service->registerAsService(), android::NO_ERROR) + << "Failed to register wifi HAL"; + } joinRpcThreadpool(); diff --git a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp new file mode 100644 index 000000000..dbf7bd611 --- /dev/null +++ b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android-base/macros.h> +#include <gmock/gmock.h> + +#undef NAN +#include "hidl_struct_util.h" + +using testing::Test; + +namespace { +constexpr uint32_t kMacId1 = 1; +constexpr uint32_t kMacId2 = 2; +constexpr uint32_t kIfaceChannel1 = 3; +constexpr uint32_t kIfaceChannel2 = 5; +constexpr char kIfaceName1[] = "wlan0"; +constexpr char kIfaceName2[] = "wlan1"; +} // namespace +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; +using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz; + +class HidlStructUtilTest : public Test {}; + +TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { + std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos; + legacy_hal::WifiMacInfo legacy_mac_info1 = { + .wlan_mac_id = kMacId1, + .mac_band = + legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, + .channel = kIfaceChannel1}; + legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, + .channel = kIfaceChannel2}; + legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); + legacy_mac_info1.iface_infos.push_back(legacy_iface_info2); + legacy_mac_infos.push_back(legacy_mac_info1); + + std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo> + hidl_radio_mode_infos; + ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( + legacy_mac_infos, &hidl_radio_mode_infos)); + + ASSERT_EQ(1u, hidl_radio_mode_infos.size()); + auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0]; + EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId); + EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo); + ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size()); + auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0]; + EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), + hidl_iface_info1.channel); + auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1]; + EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), + hidl_iface_info2.channel); +} + +TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { + std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos; + legacy_hal::WifiMacInfo legacy_mac_info1 = { + .wlan_mac_id = kMacId1, .mac_band = legacy_hal::WLAN_MAC_5_0_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, + .channel = kIfaceChannel1}; + legacy_hal::WifiMacInfo legacy_mac_info2 = { + .wlan_mac_id = kMacId2, .mac_band = legacy_hal::WLAN_MAC_2_4_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, + .channel = kIfaceChannel2}; + legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); + legacy_mac_infos.push_back(legacy_mac_info1); + legacy_mac_info2.iface_infos.push_back(legacy_iface_info2); + legacy_mac_infos.push_back(legacy_mac_info2); + + std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo> + hidl_radio_mode_infos; + ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( + legacy_mac_infos, &hidl_radio_mode_infos)); + + ASSERT_EQ(2u, hidl_radio_mode_infos.size()); + + // Find mac info 1. + const auto hidl_radio_mode_info1 = + std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), + [&legacy_mac_info1]( + const V1_2::IWifiChipEventCallback::RadioModeInfo& x) { + return x.radioId == legacy_mac_info1.wlan_mac_id; + }); + ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1); + EXPECT_EQ(WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo); + ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size()); + auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0]; + EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), + hidl_iface_info1.channel); + + // Find mac info 2. + const auto hidl_radio_mode_info2 = + std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), + [&legacy_mac_info2]( + const V1_2::IWifiChipEventCallback::RadioModeInfo& x) { + return x.radioId == legacy_mac_info2.wlan_mac_id; + }); + ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2); + EXPECT_EQ(WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo); + ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size()); + auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0]; + EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), + hidl_iface_info2.channel); +} + +TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { + legacy_hal::LinkLayerStats legacy_stats{}; + legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.iface.beacon_rx = rand(); + legacy_stats.iface.rssi_mgmt = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand(); + + for (auto& radio : legacy_stats.radios) { + radio.stats.on_time = rand(); + radio.stats.tx_time = rand(); + radio.stats.rx_time = rand(); + radio.stats.on_time_scan = rand(); + radio.stats.on_time_nbd = rand(); + radio.stats.on_time_gscan = rand(); + radio.stats.on_time_roam_scan = rand(); + radio.stats.on_time_pno_scan = rand(); + radio.stats.on_time_hs20 = rand(); + for (int i = 0; i < 4; i++) { + radio.tx_time_per_levels.push_back(rand()); + } + + legacy_hal::wifi_channel_stat channel_stat1 = { + .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0}, + .cca_busy_time = 0x55, + .on_time = 0x1111}; + legacy_hal::wifi_channel_stat channel_stat2 = { + .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0}, + .cca_busy_time = 0x66, + .on_time = 0x2222}; + radio.channel_stats.push_back(channel_stat1); + radio.channel_stats.push_back(channel_stat2); + } + + V1_3::StaLinkLayerStats converted{}; + hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, + &converted); + EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.beaconRx); + EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.avgRssiMgmt); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu, + converted.iface.wmeBePktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu, + converted.iface.wmeBePktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost, + converted.iface.wmeBePktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries, + converted.iface.wmeBePktStats.retries); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu, + converted.iface.wmeBkPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu, + converted.iface.wmeBkPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost, + converted.iface.wmeBkPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries, + converted.iface.wmeBkPktStats.retries); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu, + converted.iface.wmeViPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu, + converted.iface.wmeViPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost, + converted.iface.wmeViPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries, + converted.iface.wmeViPktStats.retries); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu, + converted.iface.wmeVoPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu, + converted.iface.wmeVoPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost, + converted.iface.wmeVoPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries, + converted.iface.wmeVoPktStats.retries); + + EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size()); + for (size_t i = 0; i < legacy_stats.radios.size(); i++) { + EXPECT_EQ(legacy_stats.radios[i].stats.on_time, + converted.radios[i].V1_0.onTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, + converted.radios[i].V1_0.txTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, + converted.radios[i].V1_0.rxTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan, + converted.radios[i].V1_0.onTimeInMsForScan); + EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(), + converted.radios[i].V1_0.txTimeInMsPerLevel.size()); + for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); + j++) { + EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j], + converted.radios[i].V1_0.txTimeInMsPerLevel[j]); + } + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd, + converted.radios[i].onTimeInMsForNanScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan, + converted.radios[i].onTimeInMsForBgScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan, + converted.radios[i].onTimeInMsForRoamScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan, + converted.radios[i].onTimeInMsForPnoScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20, + converted.radios[i].onTimeInMsForHs20Scan); + EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(), + converted.radios[i].channelStats.size()); + for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); + k++) { + auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k]; + EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20, + converted.radios[i].channelStats[k].channel.width); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq), + converted.radios[i].channelStats[k].channel.centerFreq); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq0), + converted.radios[i].channelStats[k].channel.centerFreq0); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq1), + converted.radios[i].channelStats[k].channel.centerFreq1); + EXPECT_EQ(legacy_channel_st.cca_busy_time, + converted.radios[i].channelStats[k].ccaBusyTimeInMs); + EXPECT_EQ(legacy_channel_st.on_time, + converted.radios[i].channelStats[k].onTimeInMs); + } + } +} + +TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) { + using HidlChipCaps = V1_3::IWifiChip::ChipCapabilityMask; + + uint32_t hidle_caps; + + uint32_t legacy_feature_set = + WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE; + uint32_t legacy_logger_feature_set = + legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; + + ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( + legacy_feature_set, legacy_logger_feature_set, &hidle_caps)); + + EXPECT_EQ(HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA | + HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS | + HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT | + HidlChipCaps::SET_LATENCY_MODE | + HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP, + hidle_caps); +} +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.2/default/tests/main.cpp b/wifi/1.3/default/tests/main.cpp index 9aac83724..9aac83724 100644 --- a/wifi/1.2/default/tests/main.cpp +++ b/wifi/1.3/default/tests/main.cpp diff --git a/wifi/1.2/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.3/default/tests/mock_wifi_feature_flags.cpp index 8d0b1921c..a393fdc53 100644 --- a/wifi/1.2/default/tests/mock_wifi_feature_flags.cpp +++ b/wifi/1.3/default/tests/mock_wifi_feature_flags.cpp @@ -21,7 +21,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace feature_flags { @@ -29,7 +29,7 @@ MockWifiFeatureFlags::MockWifiFeatureFlags() {} } // namespace feature_flags } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/tests/mock_wifi_feature_flags.h b/wifi/1.3/default/tests/mock_wifi_feature_flags.h index 2a36dd50f..ee12b54c7 100644 --- a/wifi/1.2/default/tests/mock_wifi_feature_flags.h +++ b/wifi/1.3/default/tests/mock_wifi_feature_flags.h @@ -18,13 +18,14 @@ #define MOCK_WIFI_FEATURE_FLAGS_H_ #include <gmock/gmock.h> +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 #include "wifi_feature_flags.h" namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace feature_flags { @@ -32,14 +33,13 @@ class MockWifiFeatureFlags : public WifiFeatureFlags { public: MockWifiFeatureFlags(); - MOCK_METHOD0(isAwareSupported, bool()); - MOCK_METHOD0(isDualInterfaceSupported, bool()); - MOCK_METHOD0(isApDisabled, bool()); + MOCK_METHOD0(getChipModes, std::vector<V1_0::IWifiChip::ChipMode>()); + MOCK_METHOD0(isApMacRandomizationDisabled, bool()); }; } // namespace feature_flags } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp new file mode 100644 index 000000000..706cb6a5e --- /dev/null +++ b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android-base/macros.h> +#include <gmock/gmock.h> + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "mock_wifi_iface_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +namespace iface_util { + +MockWifiIfaceUtil::MockWifiIfaceUtil() : WifiIfaceUtil() {} +} // namespace iface_util +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.h b/wifi/1.3/default/tests/mock_wifi_iface_util.h new file mode 100644 index 000000000..87ab5db41 --- /dev/null +++ b/wifi/1.3/default/tests/mock_wifi_iface_util.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_WIFI_IFACE_UTIL_H_ +#define MOCK_WIFI_IFACE_UTIL_H_ + +#include <gmock/gmock.h> + +#include "wifi_iface_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +namespace iface_util { + +class MockWifiIfaceUtil : public WifiIfaceUtil { + public: + MockWifiIfaceUtil(); + MOCK_METHOD1(getFactoryMacAddress, + std::array<uint8_t, 6>(const std::string&)); + MOCK_METHOD2(setMacAddress, + bool(const std::string&, const std::array<uint8_t, 6>&)); + MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>()); +}; +} // namespace iface_util +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // MOCK_WIFI_IFACE_UTIL_H_ diff --git a/wifi/1.2/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp index 8381ddef4..4cd279d54 100644 --- a/wifi/1.2/default/tests/mock_wifi_legacy_hal.cpp +++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp @@ -24,14 +24,14 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace legacy_hal { MockWifiLegacyHal::MockWifiLegacyHal() : WifiLegacyHal() {} } // namespace legacy_hal } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/tests/mock_wifi_legacy_hal.h b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h index 43370b4f5..53fa8d6f4 100644 --- a/wifi/1.2/default/tests/mock_wifi_legacy_hal.h +++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace legacy_hal { @@ -39,6 +39,16 @@ class MockWifiLegacyHal : public WifiLegacyHal { MOCK_METHOD2(registerRadioModeChangeCallbackHandler, wifi_error(const std::string&, const on_radio_mode_change_callback&)); + MOCK_METHOD1(getFirmwareVersion, std::pair<wifi_error, std::string>( + const std::string& iface_name)); + MOCK_METHOD1(getDriverVersion, std::pair<wifi_error, std::string>( + const std::string& iface_name)); + + MOCK_METHOD2(selectTxPowerScenario, + wifi_error(const std::string& iface_name, + wifi_power_scenario scenario)); + MOCK_METHOD1(resetTxPowerScenario, + wifi_error(const std::string& iface_name)); MOCK_METHOD2(nanRegisterCallbackHandlers, wifi_error(const std::string&, const NanCallbackHandlers&)); MOCK_METHOD2(nanDisableRequest, @@ -49,7 +59,7 @@ class MockWifiLegacyHal : public WifiLegacyHal { }; } // namespace legacy_hal } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.3/default/tests/mock_wifi_mode_controller.cpp index 461a581a2..2b0ea366f 100644 --- a/wifi/1.2/default/tests/mock_wifi_mode_controller.cpp +++ b/wifi/1.3/default/tests/mock_wifi_mode_controller.cpp @@ -24,14 +24,14 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace mode_controller { MockWifiModeController::MockWifiModeController() : WifiModeController() {} } // namespace mode_controller } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/tests/mock_wifi_mode_controller.h b/wifi/1.3/default/tests/mock_wifi_mode_controller.h index 50c3e35bb..c204059e6 100644 --- a/wifi/1.2/default/tests/mock_wifi_mode_controller.h +++ b/wifi/1.3/default/tests/mock_wifi_mode_controller.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace mode_controller { @@ -38,7 +38,7 @@ class MockWifiModeController : public WifiModeController { }; } // namespace mode_controller } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.3/default/tests/ringbuffer_unit_tests.cpp index ad5289b91..0cf1e4f25 100644 --- a/wifi/1.2/default/tests/ringbuffer_unit_tests.cpp +++ b/wifi/1.3/default/tests/ringbuffer_unit_tests.cpp @@ -24,7 +24,7 @@ using testing::Test; namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { class RingbufferTest : public Test { @@ -91,7 +91,7 @@ TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) { EXPECT_EQ(input, buffer_.getData().front()); } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.3/default/tests/runtests.sh b/wifi/1.3/default/tests/runtests.sh new file mode 100755 index 000000000..6bce3ef8c --- /dev/null +++ b/wifi/1.3/default/tests/runtests.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# Copyright(C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0(the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http:// www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -z $ANDROID_BUILD_TOP ]; then + echo "You need to source and lunch before you can use this script" + exit 1 +fi +set -e + +$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi@1.0-service-tests +adb root +adb sync data +adb shell /data/nativetest64/vendor/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests diff --git a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp b/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp new file mode 100644 index 000000000..28e028b67 --- /dev/null +++ b/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android-base/macros.h> +#include <cutils/properties.h> +#include <gmock/gmock.h> + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "wifi_ap_iface.h" + +#include "mock_wifi_feature_flags.h" +#include "mock_wifi_iface_util.h" +#include "mock_wifi_legacy_hal.h" + +using testing::NiceMock; +using testing::Return; +using testing::Test; + +namespace { +constexpr char kIfaceName[] = "mockWlan0"; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { + +class WifiApIfaceTest : public Test { + protected: + std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{ + new NiceMock<legacy_hal::MockWifiLegacyHal>}; + std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{ + new NiceMock<iface_util::MockWifiIfaceUtil>}; + std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> + feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>}; +}; + +TEST_F(WifiApIfaceTest, SetRandomMacAddressIfFeatureEnabled) { + EXPECT_CALL(*feature_flags_, isApMacRandomizationDisabled()) + .WillOnce(testing::Return(false)); + EXPECT_CALL(*iface_util_, getOrCreateRandomMacAddress()) + .WillOnce(testing::Return(std::array<uint8_t, 6>{0, 0, 0, 0, 0, 0})); + EXPECT_CALL(*iface_util_, setMacAddress(testing::_, testing::_)) + .WillOnce(testing::Return(true)); + sp<WifiApIface> ap_iface = + new WifiApIface(kIfaceName, legacy_hal_, iface_util_, feature_flags_); +} + +TEST_F(WifiApIfaceTest, DontSetRandomMacAddressIfFeatureDisabled) { + EXPECT_CALL(*feature_flags_, isApMacRandomizationDisabled()) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*iface_util_, getOrCreateRandomMacAddress()).Times(0); + EXPECT_CALL(*iface_util_, setMacAddress(testing::_, testing::_)).Times(0); + sp<WifiApIface> ap_iface = + new WifiApIface(kIfaceName, legacy_hal_, iface_util_, feature_flags_); +} +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp index 8722d0ac4..792832848 100644 --- a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp +++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp @@ -16,12 +16,14 @@ #include <android-base/logging.h> #include <android-base/macros.h> +#include <cutils/properties.h> #include <gmock/gmock.h> #undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 #include "wifi_chip.h" #include "mock_wifi_feature_flags.h" +#include "mock_wifi_iface_util.h" #include "mock_wifi_legacy_hal.h" #include "mock_wifi_mode_controller.h" @@ -38,54 +40,96 @@ constexpr ChipId kFakeChipId = 5; namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { class WifiChipTest : public Test { protected: void setupV1IfaceCombination() { - EXPECT_CALL(*feature_flags_, isAwareSupported()) - .WillRepeatedly(testing::Return(false)); - EXPECT_CALL(*feature_flags_, isDualInterfaceSupported()) - .WillRepeatedly(testing::Return(false)); - EXPECT_CALL(*feature_flags_, isApDisabled()) - .WillRepeatedly(testing::Return(false)); + // clang-format off + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsSta = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P}, 1}}} + }; + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsAp = { + {{{{IfaceType::AP}, 1}}} + }; + const std::vector<V1_0::IWifiChip::ChipMode> modes = { + {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}, + {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes()) + .WillRepeatedly(testing::Return(modes)); } void setupV1_AwareIfaceCombination() { - EXPECT_CALL(*feature_flags_, isAwareSupported()) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*feature_flags_, isDualInterfaceSupported()) - .WillRepeatedly(testing::Return(false)); - EXPECT_CALL(*feature_flags_, isApDisabled()) - .WillRepeatedly(testing::Return(false)); + // clang-format off + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsSta = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsAp = { + {{{{IfaceType::AP}, 1}}} + }; + const std::vector<V1_0::IWifiChip::ChipMode> modes = { + {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}, + {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes()) + .WillRepeatedly(testing::Return(modes)); } void setupV1_AwareDisabledApIfaceCombination() { - EXPECT_CALL(*feature_flags_, isAwareSupported()) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*feature_flags_, isDualInterfaceSupported()) - .WillRepeatedly(testing::Return(false)); - EXPECT_CALL(*feature_flags_, isApDisabled()) - .WillRepeatedly(testing::Return(true)); + // clang-format off + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsSta = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const std::vector<V1_0::IWifiChip::ChipMode> modes = { + {feature_flags::chip_mode_ids::kV1Sta, combinationsSta} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes()) + .WillRepeatedly(testing::Return(modes)); } void setupV2_AwareIfaceCombination() { - EXPECT_CALL(*feature_flags_, isAwareSupported()) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*feature_flags_, isDualInterfaceSupported()) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*feature_flags_, isApDisabled()) - .WillRepeatedly(testing::Return(false)); + // clang-format off + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinations = { + {{{{IfaceType::STA}, 1}, {{IfaceType::AP}, 1}}}, + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const std::vector<V1_0::IWifiChip::ChipMode> modes = { + {feature_flags::chip_mode_ids::kV3, combinations} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes()) + .WillRepeatedly(testing::Return(modes)); } void setupV2_AwareDisabledApIfaceCombination() { - EXPECT_CALL(*feature_flags_, isAwareSupported()) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*feature_flags_, isDualInterfaceSupported()) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*feature_flags_, isApDisabled()) - .WillRepeatedly(testing::Return(true)); + // clang-format off + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinations = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const std::vector<V1_0::IWifiChip::ChipMode> modes = { + {feature_flags::chip_mode_ids::kV3, combinations} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes()) + .WillRepeatedly(testing::Return(modes)); + } + + void setup_MultiIfaceCombination() { + // clang-format off + const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinations = { + {{{{IfaceType::STA}, 3}, {{IfaceType::AP}, 1}}} + }; + const std::vector<V1_0::IWifiChip::ChipMode> modes = { + {feature_flags::chip_mode_ids::kV3, combinations} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes()) + .WillRepeatedly(testing::Return(modes)); } void assertNumberOfModes(uint32_t num_modes) { @@ -204,26 +248,47 @@ class WifiChipTest : public Test { } } - public: - void SetUp() override { - chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_, - feature_flags_); - - EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*legacy_hal_, start()) - .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS)); + bool createRttController() { + bool success = false; + chip_->createRttController( + NULL, [&success](const WifiStatus& status, + const sp<IWifiRttController>& rtt) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(rtt.get(), nullptr); + success = true; + } + }); + return success; } - private: sp<WifiChip> chip_; ChipId chip_id_ = kFakeChipId; std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{ new NiceMock<legacy_hal::MockWifiLegacyHal>}; std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{new NiceMock<mode_controller::MockWifiModeController>}; + std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{ + new NiceMock<iface_util::MockWifiIfaceUtil>}; std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>}; + + public: + void SetUp() override { + chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_, + iface_util_, feature_flags_); + + EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) + .WillRepeatedly(testing::Return(true)); + EXPECT_CALL(*legacy_hal_, start()) + .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS)); + } + + void TearDown() override { + // Restore default system iface names (This should ideally be using a + // mock). + property_set("wifi.interface", "wlan0"); + property_set("wifi.concurrent.interface", "wlan1"); + } }; ////////// V1 Iface Combinations //////////// @@ -241,7 +306,7 @@ class WifiChipV1IfaceCombinationTest : public WifiChipTest { TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); } TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) { @@ -267,7 +332,7 @@ TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) { TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); } TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) { @@ -300,7 +365,7 @@ class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest { TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); } TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) { @@ -368,7 +433,7 @@ TEST_F(WifiChipV1_AwareIfaceCombinationTest, TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); } TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) { @@ -386,6 +451,53 @@ TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) { ASSERT_TRUE(createIface(IfaceType::NAN).empty()); } +TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) { + findModeAndConfigureForIfaceType(IfaceType::AP); + const auto ap_iface_name = createIface(IfaceType::AP); + ASSERT_FALSE(ap_iface_name.empty()); + ASSERT_FALSE(createRttController()); + + removeIface(IfaceType::AP, ap_iface_name); + + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); +} + ////////// V2 + Aware Iface Combinations //////////// // Mode 1 - STA + STA/AP // - STA + P2P/NAN @@ -401,7 +513,7 @@ class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest { TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); } TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) { @@ -416,19 +528,25 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) { TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); } TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) { findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); ASSERT_TRUE(createIface(IfaceType::STA).empty()); } TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); } TEST_F(WifiChipV2_AwareIfaceCombinationTest, @@ -540,40 +658,144 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, ASSERT_NE(sta_iface_name, ap_iface_name); } +TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); +} + ////////// V1 Iface Combinations when AP creation is disabled ////////// class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest { - public: - void SetUp() override { - setupV1_AwareDisabledApIfaceCombination(); - WifiChipTest::SetUp(); - } + public: + void SetUp() override { + setupV1_AwareDisabledApIfaceCombination(); + WifiChipTest::SetUp(); + } }; TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_TRUE(createIface(IfaceType::AP).empty()); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createIface(IfaceType::AP).empty()); } ////////// V2 Iface Combinations when AP creation is disabled ////////// -class WifiChipV2_AwareDisabledApIfaceCombinationTest: public WifiChipTest { - public: - void SetUp() override { - setupV2_AwareDisabledApIfaceCombination(); - WifiChipTest::SetUp(); - } +class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest { + public: + void SetUp() override { + setupV2_AwareDisabledApIfaceCombination(); + WifiChipTest::SetUp(); + } }; TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_TRUE(createIface(IfaceType::AP).empty()); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createIface(IfaceType::AP).empty()); +} + +class WifiChip_MultiIfaceTest : public WifiChipTest { + public: + void SetUp() override { + setup_MultiIfaceCombination(); + WifiChipTest::SetUp(); + } +}; + +TEST_F(WifiChip_MultiIfaceTest, Create3Sta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) { + property_set("wifi.interface.0", ""); + property_set("wifi.interface.1", ""); + property_set("wifi.interface.2", ""); + property_set("wifi.interface", ""); + property_set("wifi.concurrent.interface", ""); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan1"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan2"); } +TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) { + property_set("wifi.interface.0", "test0"); + property_set("wifi.interface.1", "test1"); + property_set("wifi.interface.2", "test2"); + property_set("wifi.interface", "bad0"); + property_set("wifi.concurrent.interface", "bad1"); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "bad0"); + ASSERT_EQ(createIface(IfaceType::STA), "bad1"); + ASSERT_EQ(createIface(IfaceType::STA), "test2"); +} + +TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) { + property_set("wifi.interface.0", ""); + property_set("wifi.interface.1", ""); + property_set("wifi.interface.2", ""); + property_set("wifi.interface", "testA0"); + property_set("wifi.concurrent.interface", "testA1"); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "testA0"); + ASSERT_EQ(createIface(IfaceType::STA), "testA1"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan2"); +} + +TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) { + findModeAndConfigureForIfaceType(IfaceType::STA); + // First AP will be slotted to wlan1. + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); + // First STA will be slotted to wlan0. + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + // All further STA will be slotted to the remaining free indices. + ASSERT_EQ(createIface(IfaceType::STA), "wlan2"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan3"); +} } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp new file mode 100644 index 000000000..e5758facd --- /dev/null +++ b/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android-base/macros.h> +#include <gmock/gmock.h> + +#undef NAN +#include "wifi_iface_util.h" + +using testing::Test; + +namespace { +constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02; + +bool isValidUnicastLocallyAssignedMacAddress( + const std::array<uint8_t, 6>& mac_address) { + uint8_t first_byte = mac_address[0]; + return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask; +} +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +class WifiIfaceUtilTest : public Test { + protected: + iface_util::WifiIfaceUtil iface_util_; +}; + +TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) { + auto mac_address = iface_util_.getOrCreateRandomMacAddress(); + ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address)); + + // All further calls should return the same MAC address. + ASSERT_EQ(mac_address, iface_util_.getOrCreateRandomMacAddress()); + ASSERT_EQ(mac_address, iface_util_.getOrCreateRandomMacAddress()); +} +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.2/default/wifi.cpp b/wifi/1.3/default/wifi.cpp index 79f921fa6..1f640856c 100644 --- a/wifi/1.2/default/wifi.cpp +++ b/wifi/1.3/default/wifi.cpp @@ -28,7 +28,7 @@ static constexpr android::hardware::wifi::V1_0::ChipId kChipId = 0; namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; @@ -36,9 +36,11 @@ using hidl_return_util::validateAndCallWithLock; Wifi::Wifi( const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal, const std::shared_ptr<mode_controller::WifiModeController> mode_controller, + const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util, const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags) : legacy_hal_(legacy_hal), mode_controller_(mode_controller), + iface_util_(iface_util), feature_flags_(feature_flags), run_state_(RunState::STOPPED) {} @@ -105,7 +107,7 @@ WifiStatus Wifi::startInternal() { if (wifi_status.code == WifiStatusCode::SUCCESS) { // Create the chip instance once the HAL is started. chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_, - feature_flags_); + iface_util_, feature_flags_); run_state_ = RunState::STARTED; for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onStart().isOk()) { @@ -206,7 +208,7 @@ WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( return createWifiStatus(WifiStatusCode::SUCCESS); } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi.h b/wifi/1.3/default/wifi.h index 86919b194..c4ab7732b 100644 --- a/wifi/1.2/default/wifi.h +++ b/wifi/1.3/default/wifi.h @@ -20,7 +20,7 @@ #include <functional> #include <android-base/macros.h> -#include <android/hardware/wifi/1.2/IWifi.h> +#include <android/hardware/wifi/1.3/IWifi.h> #include <utils/Looper.h> #include "hidl_callback_util.h" @@ -32,17 +32,18 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { /** * Root HIDL interface object used to control the Wifi HAL. */ -class Wifi : public V1_2::IWifi { +class Wifi : public V1_3::IWifi { public: Wifi(const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal, const std::shared_ptr<mode_controller::WifiModeController> mode_controller, + const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util, const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags); bool isValid(); @@ -78,6 +79,7 @@ class Wifi : public V1_2::IWifi { // and shared with all the child HIDL interface objects. std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; std::shared_ptr<mode_controller::WifiModeController> mode_controller_; + std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_; std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_; RunState run_state_; sp<WifiChip> chip_; @@ -88,7 +90,7 @@ class Wifi : public V1_2::IWifi { }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_ap_iface.cpp b/wifi/1.3/default/wifi_ap_iface.cpp index 92b7b48d9..9a8681afe 100644 --- a/wifi/1.2/default/wifi_ap_iface.cpp +++ b/wifi/1.3/default/wifi_ap_iface.cpp @@ -24,14 +24,33 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; WifiApIface::WifiApIface( const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) - : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {} + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util, + const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags) + : ifname_(ifname), + legacy_hal_(legacy_hal), + iface_util_(iface_util), + feature_flags_(feature_flags), + is_valid_(true) { + if (feature_flags_.lock()->isApMacRandomizationDisabled()) { + LOG(INFO) << "AP MAC randomization disabled"; + return; + } + LOG(INFO) << "AP MAC randomization enabled"; + // Set random MAC address + std::array<uint8_t, 6> randomized_mac = + iface_util_.lock()->getOrCreateRandomMacAddress(); + bool status = iface_util_.lock()->setMacAddress(ifname_, randomized_mac); + if (!status) { + LOG(ERROR) << "Failed to set random mac address"; + } +} void WifiApIface::invalidate() { legacy_hal_.reset(); @@ -93,7 +112,7 @@ WifiApIface::getValidFrequenciesForBandInternal(WifiBand band) { return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_ap_iface.h b/wifi/1.3/default/wifi_ap_iface.h index 5363ec258..98c5c9c37 100644 --- a/wifi/1.2/default/wifi_ap_iface.h +++ b/wifi/1.3/default/wifi_ap_iface.h @@ -20,12 +20,14 @@ #include <android-base/macros.h> #include <android/hardware/wifi/1.0/IWifiApIface.h> +#include "wifi_feature_flags.h" +#include "wifi_iface_util.h" #include "wifi_legacy_hal.h" namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -34,8 +36,11 @@ using namespace android::hardware::wifi::V1_0; */ class WifiApIface : public V1_0::IWifiApIface { public: - WifiApIface(const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); + WifiApIface( + const std::string& ifname, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util, + const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags); // Refer to |WifiChip::invalidate()|. void invalidate(); bool isValid(); @@ -59,13 +64,15 @@ class WifiApIface : public V1_0::IWifiApIface { std::string ifname_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; + std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; + std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags_; bool is_valid_; DISALLOW_COPY_AND_ASSIGN(WifiApIface); }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp index 3bd05570f..b768959f2 100644 --- a/wifi/1.2/default/wifi_chip.cpp +++ b/wifi/1.3/default/wifi_chip.cpp @@ -28,28 +28,22 @@ #include "wifi_status_util.h" namespace { +using android::sp; using android::base::unique_fd; using android::hardware::hidl_string; using android::hardware::hidl_vec; using android::hardware::wifi::V1_0::ChipModeId; using android::hardware::wifi::V1_0::IfaceType; using android::hardware::wifi::V1_0::IWifiChip; -using android::sp; - -constexpr ChipModeId kInvalidModeId = UINT32_MAX; -// These mode ID's should be unique (even across combo versions). Refer to -// handleChipConfiguration() for it's usage. -// Mode ID's for V1 -constexpr ChipModeId kV1StaChipModeId = 0; -constexpr ChipModeId kV1ApChipModeId = 1; -// Mode ID for V2 -constexpr ChipModeId kV2ChipModeId = 2; constexpr char kCpioMagic[] = "070701"; -constexpr size_t kMaxBufferSizeBytes = 1024 * 1024; -constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60; +constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3; +constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10; constexpr uint32_t kMaxRingBufferFileNum = 20; constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; +constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface"; +constexpr char kNoActiveWlanIfaceNamePropertyValue[] = ""; +constexpr unsigned kMaxWlanIfaces = 5; template <typename Iface> void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) { @@ -87,16 +81,24 @@ sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, return nullptr; } -std::string getWlan0IfaceName() { - std::array<char, PROPERTY_VALUE_MAX> buffer; - property_get("wifi.interface", buffer.data(), "wlan0"); - return buffer.data(); -} +std::string getWlanIfaceName(unsigned idx) { + if (idx >= kMaxWlanIfaces) { + CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces; + return {}; + } -std::string getWlan1IfaceName() { std::array<char, PROPERTY_VALUE_MAX> buffer; - property_get("wifi.concurrent.interface", buffer.data(), "wlan1"); - return buffer.data(); + if (idx == 0 || idx == 1) { + const char* altPropName = + (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface"; + auto res = property_get(altPropName, buffer.data(), nullptr); + if (res > 0) return buffer.data(); + } + std::string propName = "wifi.interface." + std::to_string(idx); + auto res = property_get(propName.c_str(), buffer.data(), nullptr); + if (res > 0) return buffer.data(); + + return "wlan" + std::to_string(idx); } std::string getP2pIfaceName() { @@ -105,22 +107,29 @@ std::string getP2pIfaceName() { return buffer.data(); } +void setActiveWlanIfaceNameProperty(const std::string& ifname) { + auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data()); + if (res != 0) { + PLOG(ERROR) << "Failed to set active wlan iface name property"; + } +} + // delete files that meet either conditions: // 1. older than a predefined time in the wifi tombstone dir. // 2. Files in excess to a predefined amount, starting from the oldest ones bool removeOldFilesInternal() { time_t now = time(0); const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds; - DIR* dir_dump = opendir(kTombstoneFolderPath); + std::unique_ptr<DIR, decltype(&closedir)> dir_dump( + opendir(kTombstoneFolderPath), closedir); if (!dir_dump) { - LOG(ERROR) << "Failed to open directory: " << strerror(errno); + PLOG(ERROR) << "Failed to open directory"; return false; } - unique_fd dir_auto_closer(dirfd(dir_dump)); struct dirent* dp; bool success = true; std::list<std::pair<const time_t, std::string>> valid_files; - while ((dp = readdir(dir_dump))) { + while ((dp = readdir(dir_dump.get()))) { if (dp->d_type != DT_REG) { continue; } @@ -128,8 +137,7 @@ bool removeOldFilesInternal() { struct stat cur_file_stat; std::string cur_file_path = kTombstoneFolderPath + cur_file_name; if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) { - LOG(ERROR) << "Failed to get file stat for " << cur_file_path - << ": " << strerror(errno); + PLOG(ERROR) << "Failed to get file stat for " << cur_file_path; success = false; continue; } @@ -144,7 +152,7 @@ bool removeOldFilesInternal() { if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) { if (unlink(cur_file.second.c_str()) != 0) { - LOG(ERROR) << "Error deleting file " << strerror(errno); + PLOG(ERROR) << "Error deleting file"; success = false; } cur_file_count--; @@ -168,13 +176,11 @@ bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, major(st.st_dev), minor(st.st_dev), major(st.st_rdev), minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0); if (write(out_fd, read_buf.data(), llen) == -1) { - LOG(ERROR) << "Error writing cpio header to file " << file_name << " " - << strerror(errno); + PLOG(ERROR) << "Error writing cpio header to file " << file_name; return false; } if (write(out_fd, file_name, file_name_len) == -1) { - LOG(ERROR) << "Error writing filename to file " << file_name << " " - << strerror(errno); + PLOG(ERROR) << "Error writing filename to file " << file_name; return false; } @@ -183,8 +189,7 @@ bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, if (llen != 0) { const uint32_t zero = 0; if (write(out_fd, &zero, 4 - llen) == -1) { - LOG(ERROR) << "Error padding 0s to file " << file_name << " " - << strerror(errno); + PLOG(ERROR) << "Error padding 0s to file " << file_name; return false; } } @@ -200,17 +205,17 @@ size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) { while (llen > 0) { ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size()); if (bytes_read == -1) { - LOG(ERROR) << "Error reading file " << strerror(errno); + PLOG(ERROR) << "Error reading file"; return ++n_error; } llen -= bytes_read; if (write(out_fd, read_buf.data(), bytes_read) == -1) { - LOG(ERROR) << "Error writing data to file " << strerror(errno); + PLOG(ERROR) << "Error writing data to file"; return ++n_error; } if (bytes_read == 0) { // this should never happen, but just in case // to unstuck from while loop - LOG(ERROR) << "Unexpected read result for " << strerror(errno); + PLOG(ERROR) << "Unexpected read result"; n_error++; break; } @@ -219,7 +224,7 @@ size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) { if (llen != 0) { const uint32_t zero = 0; if (write(out_fd, &zero, 4 - llen) == -1) { - LOG(ERROR) << "Error padding 0s to file " << strerror(errno); + PLOG(ERROR) << "Error padding 0s to file"; return ++n_error; } } @@ -234,7 +239,7 @@ bool cpioWriteFileTrailer(int out_fd) { sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0) + 4) == -1) { - LOG(ERROR) << "Error writing trailing bytes " << strerror(errno); + PLOG(ERROR) << "Error writing trailing bytes"; return false; } return true; @@ -246,13 +251,13 @@ bool cpioWriteFileTrailer(int out_fd) { size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { struct dirent* dp; size_t n_error = 0; - DIR* dir_dump = opendir(input_dir); + std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), + closedir); if (!dir_dump) { - LOG(ERROR) << "Failed to open directory: " << strerror(errno); + PLOG(ERROR) << "Failed to open directory"; return ++n_error; } - unique_fd dir_auto_closer(dirfd(dir_dump)); - while ((dp = readdir(dir_dump))) { + while ((dp = readdir(dir_dump.get()))) { if (dp->d_type != DT_REG) { continue; } @@ -263,15 +268,13 @@ size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { struct stat st; const std::string cur_file_path = kTombstoneFolderPath + cur_file_name; if (stat(cur_file_path.c_str(), &st) == -1) { - LOG(ERROR) << "Failed to get file stat for " << cur_file_path - << ": " << strerror(errno); + PLOG(ERROR) << "Failed to get file stat for " << cur_file_path; n_error++; continue; } const int fd_read = open(cur_file_path.c_str(), O_RDONLY); if (fd_read == -1) { - LOG(ERROR) << "Failed to open file " << cur_file_path << " " - << strerror(errno); + PLOG(ERROR) << "Failed to open file " << cur_file_path; n_error++; continue; } @@ -304,7 +307,7 @@ std::vector<char> makeCharVec(const std::string& str) { namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; @@ -312,15 +315,18 @@ using hidl_return_util::validateAndCallWithLock; WifiChip::WifiChip( ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, const std::weak_ptr<mode_controller::WifiModeController> mode_controller, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util, const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags) : chip_id_(chip_id), legacy_hal_(legacy_hal), mode_controller_(mode_controller), + iface_util_(iface_util), feature_flags_(feature_flags), is_valid_(true), - current_mode_id_(kInvalidModeId), + current_mode_id_(feature_flags::chip_mode_ids::kInvalid), + modes_(feature_flags.lock()->getChipModes()), debug_ring_buffer_cb_registered_(false) { - populateModes(); + setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); } void WifiChip::invalidate() { @@ -328,6 +334,7 @@ void WifiChip::invalidate() { LOG(ERROR) << "Error writing files to flash"; } invalidateAndRemoveAllIfaces(); + setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); legacy_hal_.reset(); event_cb_handler_.invalidate(); is_valid_ = false; @@ -335,7 +342,7 @@ void WifiChip::invalidate() { bool WifiChip::isValid() { return is_valid_; } -std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() { +std::set<sp<V1_2::IWifiChipEventCallback>> WifiChip::getEventCallbacks() { return event_cb_handler_.getCallbacks(); } @@ -344,6 +351,7 @@ Return<void> WifiChip::getId(getId_cb hidl_status_cb) { &WifiChip::getIdInternal, hidl_status_cb); } +// Deprecated support for this callback Return<void> WifiChip::registerEventCallback( const sp<V1_0::IWifiChipEventCallback>& event_callback, registerEventCallback_cb hidl_status_cb) { @@ -524,6 +532,13 @@ Return<void> WifiChip::forceDumpToDebugRingBuffer( hidl_status_cb, ring_name); } +Return<void> WifiChip::flushRingBufferToFile( + flushRingBufferToFile_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::flushRingBufferToFileInternal, + hidl_status_cb); +} + Return<void> WifiChip::stopLoggingToDebugRingBuffer( stopLoggingToDebugRingBuffer_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, @@ -546,7 +561,8 @@ Return<void> WifiChip::enableDebugErrorAlerts( } Return<void> WifiChip::selectTxPowerScenario( - V1_1::IWifiChip::TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { + V1_1::IWifiChip::TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario); @@ -559,8 +575,15 @@ Return<void> WifiChip::resetTxPowerScenario( hidl_status_cb); } +Return<void> WifiChip::setLatencyMode(LatencyMode mode, + setLatencyMode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setLatencyModeInternal, hidl_status_cb, + mode); +} + Return<void> WifiChip::registerEventCallback_1_2( - const sp<IWifiChipEventCallback>& event_callback, + const sp<V1_2::IWifiChipEventCallback>& event_callback, registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::registerEventCallbackInternal_1_2, @@ -568,9 +591,16 @@ Return<void> WifiChip::registerEventCallback_1_2( } Return<void> WifiChip::selectTxPowerScenario_1_2( - TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { + TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::selectTxPowerScenarioInternal_1_2, + hidl_status_cb, scenario); +} + +Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario); + &WifiChip::getCapabilitiesInternal_1_3, + hidl_status_cb); } Return<void> WifiChip::debug(const hidl_handle& handle, @@ -615,16 +645,22 @@ WifiStatus WifiChip::registerEventCallbackInternal( } std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() { + // Deprecated support for this callback. + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; +} + +std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() { legacy_hal::wifi_error legacy_status; uint32_t legacy_feature_set; uint32_t legacy_logger_feature_set; + const auto ifname = getFirstActiveWlanIfaceName(); std::tie(legacy_status, legacy_feature_set) = - legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName()); + legacy_hal_.lock()->getSupportedFeatureSet(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), 0}; } std::tie(legacy_status, legacy_logger_feature_set) = - legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName()); + legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { // some devices don't support querying logger feature set legacy_logger_feature_set = 0; @@ -669,6 +705,7 @@ WifiStatus WifiChip::configureChipInternal( } current_mode_id_ = mode_id; LOG(INFO) << "Configured chip in mode " << mode_id; + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return status; } @@ -685,8 +722,9 @@ WifiChip::requestChipDebugInfoInternal() { IWifiChip::ChipDebugInfo result; legacy_hal::wifi_error legacy_status; std::string driver_desc; + const auto ifname = getFirstActiveWlanIfaceName(); std::tie(legacy_status, driver_desc) = - legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName()); + legacy_hal_.lock()->getDriverVersion(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status); @@ -698,7 +736,7 @@ WifiChip::requestChipDebugInfoInternal() { std::string firmware_desc; std::tie(legacy_status, firmware_desc) = - legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName()); + legacy_hal_.lock()->getFirmwareVersion(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status); @@ -716,7 +754,8 @@ WifiChip::requestDriverDebugDumpInternal() { legacy_hal::wifi_error legacy_status; std::vector<uint8_t> driver_dump; std::tie(legacy_status, driver_dump) = - legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName()); + legacy_hal_.lock()->requestDriverMemoryDump( + getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status); @@ -731,7 +770,8 @@ WifiChip::requestFirmwareDebugDumpInternal() { legacy_hal::wifi_error legacy_status; std::vector<uint8_t> firmware_dump; std::tie(legacy_status, firmware_dump) = - legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName()); + legacy_hal_.lock()->requestFirmwareMemoryDump( + getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status); @@ -741,17 +781,19 @@ WifiChip::requestFirmwareDebugDumpInternal() { } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { - if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - std::string ifname = allocateApOrStaIfaceName(); - sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_); + std::string ifname = allocateApIfaceName(); + sp<WifiApIface> iface = + new WifiApIface(ifname, legacy_hal_, iface_util_, feature_flags_); ap_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) { LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; } } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } @@ -783,15 +825,16 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; } } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return createWifiStatus(WifiStatusCode::SUCCESS); } std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() { - if (!canCurrentModeSupportIfaceOfType(IfaceType::NAN)) { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } // These are still assumed to be based on wlan0. - std::string ifname = getWlan0IfaceName(); + std::string ifname = getFirstActiveWlanIfaceName(); sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_); nan_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { @@ -834,7 +877,7 @@ WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) { } std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() { - if (!canCurrentModeSupportIfaceOfType(IfaceType::P2P)) { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string ifname = getP2pIfaceName(); @@ -880,17 +923,18 @@ WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) { } std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() { - if (!canCurrentModeSupportIfaceOfType(IfaceType::STA)) { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - std::string ifname = allocateApOrStaIfaceName(); - sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_); + std::string ifname = allocateStaIfaceName(); + sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_); sta_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) { LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; } } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } @@ -922,13 +966,20 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) { LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; } } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return createWifiStatus(WifiStatusCode::SUCCESS); } std::pair<WifiStatus, sp<IWifiRttController>> WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) { - sp<WifiRttController> rtt = - new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_); + if (sta_ifaces_.size() == 0 && + !canCurrentModeSupportIfaceOfType(IfaceType::STA)) { + LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs " + "(and RTT by extension)"; + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + sp<WifiRttController> rtt = new WifiRttController( + getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_); rtt_controllers_.emplace_back(rtt); return {createWifiStatus(WifiStatusCode::SUCCESS), rtt}; } @@ -939,7 +990,7 @@ WifiChip::getDebugRingBuffersStatusInternal() { std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec; std::tie(legacy_status, legacy_ring_buffer_status_vec) = - legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName()); + legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } @@ -961,7 +1012,7 @@ WifiStatus WifiChip::startLoggingToDebugRingBufferInternal( } legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging( - getWlan0IfaceName(), ring_name, + getFirstActiveWlanIfaceName(), ring_name, static_cast< std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>( verbose_level), @@ -978,15 +1029,24 @@ WifiStatus WifiChip::forceDumpToDebugRingBufferInternal( return status; } legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name); + legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), + ring_name); return createWifiStatusFromLegacyError(legacy_status); } +WifiStatus WifiChip::flushRingBufferToFileInternal() { + if (!writeRingbufferFilesInternal()) { + LOG(ERROR) << "Error writing files to flash"; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() { legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deregisterRingBufferCallbackHandler( - getWlan0IfaceName()); + getFirstActiveWlanIfaceName()); return createWifiStatusFromLegacyError(legacy_status); } @@ -995,7 +1055,7 @@ WifiChip::getDebugHostWakeReasonStatsInternal() { legacy_hal::wifi_error legacy_status; legacy_hal::WakeReasonStats legacy_stats; std::tie(legacy_status, legacy_stats) = - legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName()); + legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } @@ -1027,39 +1087,47 @@ WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) { } }; legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler( - getWlan0IfaceName(), on_alert_callback); + getFirstActiveWlanIfaceName(), on_alert_callback); } else { legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler( - getWlan0IfaceName()); + getFirstActiveWlanIfaceName()); } return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::selectTxPowerScenarioInternal( - V1_1::IWifiChip::TxPowerScenario scenario) { + V1_1::IWifiChip::TxPowerScenario scenario) { auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( - getWlan0IfaceName(), + getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario)); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::resetTxPowerScenarioInternal() { auto legacy_status = - legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName()); + legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName()); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) { + auto legacy_status = legacy_hal_.lock()->setLatencyMode( + getFirstActiveWlanIfaceName(), + hidl_struct_util::convertHidlLatencyModeToLegacy(mode)); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::registerEventCallbackInternal_1_2( - const sp<IWifiChipEventCallback>& event_callback) { + const sp<V1_2::IWifiChipEventCallback>& event_callback) { if (!event_cb_handler_.addCallback(event_callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } return createWifiStatus(WifiStatusCode::SUCCESS); } -WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) { +WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2( + TxPowerScenario scenario) { auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( - getWlan0IfaceName(), + getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); return createWifiStatusFromLegacyError(legacy_status); } @@ -1083,9 +1151,9 @@ WifiStatus WifiChip::handleChipConfiguration( } // Firmware mode change not needed for V2 devices. bool success = true; - if (mode_id == kV1StaChipModeId) { + if (mode_id == feature_flags::chip_mode_ids::kV1Sta) { success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA); - } else if (mode_id == kV1ApChipModeId) { + } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) { success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP); } if (!success) { @@ -1104,6 +1172,16 @@ WifiStatus WifiChip::handleChipConfiguration( // This probably is not a critical failure? LOG(ERROR) << "Failed to register radio mode change callback"; } + // Extract and save the version information into property. + std::pair<WifiStatus, IWifiChip::ChipDebugInfo> version_info; + version_info = WifiChip::requestChipDebugInfoInternal(); + if (WifiStatusCode::SUCCESS == version_info.first.code) { + property_set("vendor.wlan.firmware.version", + version_info.second.firmwareDescription.c_str()); + property_set("vendor.wlan.driver.version", + version_info.second.driverDescription.c_str()); + } + return createWifiStatus(WifiStatusCode::SUCCESS); } @@ -1139,7 +1217,7 @@ WifiStatus WifiChip::registerDebugRingBufferCallback() { }; legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler( - getWlan0IfaceName(), on_ring_buffer_data_callback); + getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback); if (legacy_status == legacy_hal::WIFI_SUCCESS) { debug_ring_buffer_cb_registered_ = true; @@ -1156,7 +1234,7 @@ WifiStatus WifiChip::registerRadioModeChangeCallback() { LOG(ERROR) << "Callback invoked on an invalid object"; return; } - std::vector<IWifiChipEventCallback::RadioModeInfo> + std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos; if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl( mac_infos, &hidl_radio_mode_infos)) { @@ -1173,86 +1251,10 @@ WifiStatus WifiChip::registerRadioModeChangeCallback() { }; legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRadioModeChangeCallbackHandler( - getWlan0IfaceName(), on_radio_mode_change_callback); + getFirstActiveWlanIfaceName(), on_radio_mode_change_callback); return createWifiStatusFromLegacyError(legacy_status); } -void WifiChip::populateModes() { - // The chip combination supported for current devices is fixed. - // They can be one of the following based on device features: - // a) 2 separate modes of operation with 1 interface combination each: - // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN(optional) - // concurrent iface operations. - // Mode 2 (AP mode): Will support 1 AP iface operation. - // - // b) 1 mode of operation with 2 interface combinations - // (conditional on isDualInterfaceSupported()): - // Interface Combination 1: Will support 1 STA and 1 P2P or NAN(optional) - // concurrent iface operations. - // Interface Combination 2: Will support 1 STA and 1 AP concurrent - // iface operations. - // If Aware is enabled (conditional on isAwareSupported()), the iface - // combination will be modified to support either P2P or NAN in place of - // just P2P. - if (feature_flags_.lock()->isDualInterfaceSupported()) { - // V2 Iface combinations for Mode Id = 2. - const IWifiChip::ChipIfaceCombinationLimit - chip_iface_combination_limit_1 = {{IfaceType::STA}, 1}; - const IWifiChip::ChipIfaceCombinationLimit - chip_iface_combination_limit_2 = {{IfaceType::AP}, 1}; - IWifiChip::ChipIfaceCombinationLimit chip_iface_combination_limit_3; - if (feature_flags_.lock()->isAwareSupported()) { - chip_iface_combination_limit_3 = {{IfaceType::P2P, IfaceType::NAN}, - 1}; - } else { - chip_iface_combination_limit_3 = {{IfaceType::P2P}, 1}; - } - const IWifiChip::ChipIfaceCombination chip_iface_combination_1 = { - {chip_iface_combination_limit_1, chip_iface_combination_limit_2}}; - const IWifiChip::ChipIfaceCombination chip_iface_combination_2 = { - {chip_iface_combination_limit_1, chip_iface_combination_limit_3}}; - if (feature_flags_.lock()->isApDisabled()) { - const IWifiChip::ChipMode chip_mode = { - kV2ChipModeId, - {chip_iface_combination_2}}; - modes_ = {chip_mode}; - } else { - const IWifiChip::ChipMode chip_mode = { - kV2ChipModeId, - {chip_iface_combination_1, chip_iface_combination_2}}; - modes_ = {chip_mode}; - } - } else { - // V1 Iface combinations for Mode Id = 0. (STA Mode) - const IWifiChip::ChipIfaceCombinationLimit - sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1}; - IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2; - if (feature_flags_.lock()->isAwareSupported()) { - sta_chip_iface_combination_limit_2 = { - {IfaceType::P2P, IfaceType::NAN}, 1}; - } else { - sta_chip_iface_combination_limit_2 = {{IfaceType::P2P}, 1}; - } - const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = { - {sta_chip_iface_combination_limit_1, - sta_chip_iface_combination_limit_2}}; - const IWifiChip::ChipMode sta_chip_mode = { - kV1StaChipModeId, {sta_chip_iface_combination}}; - // Iface combinations for Mode Id = 1. (AP Mode) - const IWifiChip::ChipIfaceCombinationLimit - ap_chip_iface_combination_limit = {{IfaceType::AP}, 1}; - const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = { - {ap_chip_iface_combination_limit}}; - const IWifiChip::ChipMode ap_chip_mode = {kV1ApChipModeId, - {ap_chip_iface_combination}}; - if (feature_flags_.lock()->isApDisabled()) { - modes_ = {sta_chip_mode}; - } else { - modes_ = {sta_chip_mode, ap_chip_mode}; - } - } -} - std::vector<IWifiChip::ChipIfaceCombination> WifiChip::getCurrentModeIfaceCombinations() { if (!isValidModeId(current_mode_id_)) { @@ -1316,8 +1318,9 @@ std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations( return expanded_combos; } -bool WifiChip::canExpandedIfaceCombinationSupportIfaceOfType( - const std::map<IfaceType, size_t>& combo, IfaceType requested_type) { +bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( + const std::map<IfaceType, size_t>& expanded_combo, + IfaceType requested_type) { const auto current_combo = getCurrentIfaceCombination(); // Check if we have space for 1 more iface of |type| in this combo @@ -1327,7 +1330,7 @@ bool WifiChip::canExpandedIfaceCombinationSupportIfaceOfType( if (type == requested_type) { num_ifaces_needed++; } - size_t num_ifaces_allowed = combo.at(type); + size_t num_ifaces_allowed = expanded_combo.at(type); if (num_ifaces_needed > num_ifaces_allowed) { return false; } @@ -1338,8 +1341,55 @@ bool WifiChip::canExpandedIfaceCombinationSupportIfaceOfType( // This method does the following: // a) Enumerate all possible iface combos by expanding the current // ChipIfaceCombination. -// b) Check if the requested iface type can be added to the current mode. -bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType type) { +// b) Check if the requested iface type can be added to the current mode +// with the iface combination that is already active. +bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( + IfaceType requested_type) { + if (!isValidModeId(current_mode_id_)) { + LOG(ERROR) << "Chip not configured in a mode yet"; + return false; + } + const auto combinations = getCurrentModeIfaceCombinations(); + for (const auto& combination : combinations) { + const auto expanded_combos = expandIfaceCombinations(combination); + for (const auto& expanded_combo : expanded_combos) { + if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( + expanded_combo, requested_type)) { + return true; + } + } + } + return false; +} + +// Note: This does not consider ifaces already active. It only checks if the +// provided expanded iface combination can support the requested combo. +bool WifiChip::canExpandedIfaceComboSupportIfaceCombo( + const std::map<IfaceType, size_t>& expanded_combo, + const std::map<IfaceType, size_t>& req_combo) { + // Check if we have space for 1 more iface of |type| in this combo + for (const auto type : + {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + if (req_combo.count(type) == 0) { + // Iface of "type" not in the req_combo. + continue; + } + size_t num_ifaces_needed = req_combo.at(type); + size_t num_ifaces_allowed = expanded_combo.at(type); + if (num_ifaces_needed > num_ifaces_allowed) { + return false; + } + } + return true; +} +// This method does the following: +// a) Enumerate all possible iface combos by expanding the current +// ChipIfaceCombination. +// b) Check if the requested iface combo can be added to the current mode. +// Note: This does not consider ifaces already active. It only checks if the +// current mode can support the requested combo. +bool WifiChip::canCurrentModeSupportIfaceCombo( + const std::map<IfaceType, size_t>& req_combo) { if (!isValidModeId(current_mode_id_)) { LOG(ERROR) << "Chip not configured in a mode yet"; return false; @@ -1348,8 +1398,8 @@ bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType type) { for (const auto& combination : combinations) { const auto expanded_combos = expandIfaceCombinations(combination); for (const auto& expanded_combo : expanded_combos) { - if (canExpandedIfaceCombinationSupportIfaceOfType(expanded_combo, - type)) { + if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, + req_combo)) { return true; } } @@ -1357,6 +1407,17 @@ bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType type) { return false; } +// This method does the following: +// a) Enumerate all possible iface combos by expanding the current +// ChipIfaceCombination. +// b) Check if the requested iface type can be added to the current mode. +bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) { + // Check if we can support atleast 1 iface of type. + std::map<IfaceType, size_t> req_iface_combo; + req_iface_combo[requested_type] = 1; + return canCurrentModeSupportIfaceCombo(req_iface_combo); +} + bool WifiChip::isValidModeId(ChipModeId mode_id) { for (const auto& mode : modes_) { if (mode.id == mode_id) { @@ -1366,25 +1427,51 @@ bool WifiChip::isValidModeId(ChipModeId mode_id) { return false; } -// Return "wlan0", if "wlan0" is not already in use, else return "wlan1". -// This is based on the assumption that we'll have a max of 2 concurrent -// AP/STA ifaces. -std::string WifiChip::allocateApOrStaIfaceName() { - auto ap_iface = findUsingName(ap_ifaces_, getWlan0IfaceName()); - auto sta_iface = findUsingName(sta_ifaces_, getWlan0IfaceName()); - if (!ap_iface.get() && !sta_iface.get()) { - return getWlan0IfaceName(); - } - ap_iface = findUsingName(ap_ifaces_, getWlan1IfaceName()); - sta_iface = findUsingName(sta_ifaces_, getWlan1IfaceName()); - if (!ap_iface.get() && !sta_iface.get()) { - return getWlan1IfaceName(); +bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() { + // Check if we can support atleast 1 STA & 1 AP concurrently. + std::map<IfaceType, size_t> req_iface_combo; + req_iface_combo[IfaceType::AP] = 1; + req_iface_combo[IfaceType::STA] = 1; + return canCurrentModeSupportIfaceCombo(req_iface_combo); +} + +std::string WifiChip::getFirstActiveWlanIfaceName() { + if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName(); + if (ap_ifaces_.size() > 0) return ap_ifaces_[0]->getName(); + // This could happen if the chip call is made before any STA/AP + // iface is created. Default to wlan0 for such cases. + LOG(WARNING) << "No active wlan interfaces in use! Using default"; + return getWlanIfaceName(0); +} + +// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx| +// not already in use. +// Note: This doesn't check the actual presence of these interfaces. +std::string WifiChip::allocateApOrStaIfaceName(uint32_t start_idx) { + for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) { + const auto ifname = getWlanIfaceName(idx); + if (findUsingName(ap_ifaces_, ifname)) continue; + if (findUsingName(sta_ifaces_, ifname)) continue; + return ifname; } // This should never happen. We screwed up somewhere if it did. - CHECK(0) << "wlan0 and wlan1 in use already!"; + CHECK(false) << "All wlan interfaces in use already!"; return {}; } +// AP iface names start with idx 1 for modes supporting +// concurrent STA, else start with idx 0. +std::string WifiChip::allocateApIfaceName() { + return allocateApOrStaIfaceName( + isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0); +} + +// STA iface names start with idx 0. +// Primary STA iface will always be 0. +std::string WifiChip::allocateStaIfaceName() { + return allocateApOrStaIfaceName(0); +} + bool WifiChip::writeRingbufferFilesInternal() { if (!removeOldFilesInternal()) { LOG(ERROR) << "Error occurred while deleting old tombstone files"; @@ -1400,14 +1487,14 @@ bool WifiChip::writeRingbufferFilesInternal() { kTombstoneFolderPath + item.first + "XXXXXXXXXX"; const int dump_fd = mkstemp(makeCharVec(file_path_raw).data()); if (dump_fd == -1) { - LOG(ERROR) << "create file failed: " << strerror(errno); + PLOG(ERROR) << "create file failed"; return false; } unique_fd file_auto_closer(dump_fd); for (const auto& cur_block : cur_buffer.getData()) { if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) == -1) { - LOG(ERROR) << "Error writing to file " << strerror(errno); + PLOG(ERROR) << "Error writing to file"; } } } @@ -1415,7 +1502,7 @@ bool WifiChip::writeRingbufferFilesInternal() { } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_chip.h b/wifi/1.3/default/wifi_chip.h index ada945885..3d12f4c9b 100644 --- a/wifi/1.2/default/wifi_chip.h +++ b/wifi/1.3/default/wifi_chip.h @@ -21,7 +21,7 @@ #include <map> #include <android-base/macros.h> -#include <android/hardware/wifi/1.2/IWifiChip.h> +#include <android/hardware/wifi/1.3/IWifiChip.h> #include "hidl_callback_util.h" #include "ringbuffer.h" @@ -37,7 +37,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -46,13 +46,14 @@ using namespace android::hardware::wifi::V1_0; * Since there is only a single chip instance used today, there is no * identifying handle information stored here. */ -class WifiChip : public V1_2::IWifiChip { +class WifiChip : public V1_3::IWifiChip { public: WifiChip( ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, const std::weak_ptr<mode_controller::WifiModeController> mode_controller, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util, const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags); // HIDL does not provide a built-in mechanism to let the server invalidate // a HIDL interface object after creation. If any client process holds onto @@ -69,10 +70,11 @@ class WifiChip : public V1_2::IWifiChip { // marked valid before processing them. void invalidate(); bool isValid(); - std::set<sp<IWifiChipEventCallback>> getEventCallbacks(); + std::set<sp<V1_2::IWifiChipEventCallback>> getEventCallbacks(); // HIDL methods exposed. Return<void> getId(getId_cb hidl_status_cb) override; + // Deprecated support for this callback Return<void> registerEventCallback( const sp<V1_0::IWifiChipEventCallback>& event_callback, registerEventCallback_cb hidl_status_cb) override; @@ -125,6 +127,8 @@ class WifiChip : public V1_2::IWifiChip { Return<void> forceDumpToDebugRingBuffer( const hidl_string& ring_name, forceDumpToDebugRingBuffer_cb hidl_status_cb) override; + Return<void> flushRingBufferToFile( + flushRingBufferToFile_cb hidl_status_cb) override; Return<void> stopLoggingToDebugRingBuffer( stopLoggingToDebugRingBuffer_cb hidl_status_cb) override; Return<void> getDebugHostWakeReasonStats( @@ -136,19 +140,25 @@ class WifiChip : public V1_2::IWifiChip { selectTxPowerScenario_cb hidl_status_cb) override; Return<void> resetTxPowerScenario( resetTxPowerScenario_cb hidl_status_cb) override; + Return<void> setLatencyMode(LatencyMode mode, + setLatencyMode_cb hidl_status_cb) override; Return<void> registerEventCallback_1_2( - const sp<IWifiChipEventCallback>& event_callback, + const sp<V1_2::IWifiChipEventCallback>& event_callback, registerEventCallback_1_2_cb hidl_status_cb) override; Return<void> selectTxPowerScenario_1_2( TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) override; + Return<void> getCapabilities_1_3( + getCapabilities_cb hidl_status_cb) override; Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override; + private: void invalidateAndRemoveAllIfaces(); // Corresponding worker functions for the HIDL methods. std::pair<WifiStatus, ChipId> getIdInternal(); + // Deprecated support for this callback WifiStatus registerEventCallbackInternal( const sp<V1_0::IWifiChipEventCallback>& event_callback); std::pair<WifiStatus, uint32_t> getCapabilitiesInternal(); @@ -191,36 +201,52 @@ class WifiChip : public V1_2::IWifiChip { WifiDebugRingBufferVerboseLevel verbose_level, uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes); WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name); + WifiStatus flushRingBufferToFileInternal(); WifiStatus stopLoggingToDebugRingBufferInternal(); std::pair<WifiStatus, WifiDebugHostWakeReasonStats> getDebugHostWakeReasonStatsInternal(); WifiStatus enableDebugErrorAlertsInternal(bool enable); - WifiStatus selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario); + WifiStatus selectTxPowerScenarioInternal( + V1_1::IWifiChip::TxPowerScenario scenario); WifiStatus resetTxPowerScenarioInternal(); + WifiStatus setLatencyModeInternal(LatencyMode mode); WifiStatus registerEventCallbackInternal_1_2( - const sp<IWifiChipEventCallback>& event_callback); + const sp<V1_2::IWifiChipEventCallback>& event_callback); WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario); + std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3(); WifiStatus handleChipConfiguration( std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); WifiStatus registerRadioModeChangeCallback(); - void populateModes(); std::vector<IWifiChip::ChipIfaceCombination> getCurrentModeIfaceCombinations(); std::map<IfaceType, size_t> getCurrentIfaceCombination(); std::vector<std::map<IfaceType, size_t>> expandIfaceCombinations( const IWifiChip::ChipIfaceCombination& combination); - bool canExpandedIfaceCombinationSupportIfaceOfType( - const std::map<IfaceType, size_t>& combo, IfaceType type); - bool canCurrentModeSupportIfaceOfType(IfaceType type); + bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( + const std::map<IfaceType, size_t>& expanded_combo, + IfaceType requested_type); + bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( + IfaceType requested_type); + bool canExpandedIfaceComboSupportIfaceCombo( + const std::map<IfaceType, size_t>& expanded_combo, + const std::map<IfaceType, size_t>& req_combo); + bool canCurrentModeSupportIfaceCombo( + const std::map<IfaceType, size_t>& req_combo); + bool canCurrentModeSupportIfaceOfType(IfaceType requested_type); bool isValidModeId(ChipModeId mode_id); - std::string allocateApOrStaIfaceName(); + bool isStaApConcurrencyAllowedInCurrentMode(); + std::string getFirstActiveWlanIfaceName(); + std::string allocateApOrStaIfaceName(uint32_t start_idx); + std::string allocateApIfaceName(); + std::string allocateStaIfaceName(); bool writeRingbufferFilesInternal(); ChipId chip_id_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; std::weak_ptr<mode_controller::WifiModeController> mode_controller_; + std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags_; std::vector<sp<WifiApIface>> ap_ifaces_; std::vector<sp<WifiNanIface>> nan_ifaces_; @@ -236,14 +262,14 @@ class WifiChip : public V1_2::IWifiChip { // registration mechanism. Use this to check if we have already // registered a callback. bool debug_ring_buffer_cb_registered_; - hidl_callback_util::HidlCallbackHandler<IWifiChipEventCallback> + hidl_callback_util::HidlCallbackHandler<V1_2::IWifiChipEventCallback> event_cb_handler_; DISALLOW_COPY_AND_ASSIGN(WifiChip); }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.3/default/wifi_feature_flags.cpp b/wifi/1.3/default/wifi_feature_flags.cpp new file mode 100644 index 000000000..7212cfac3 --- /dev/null +++ b/wifi/1.3/default/wifi_feature_flags.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wifi_feature_flags.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +namespace feature_flags { + +using V1_0::ChipModeId; +using V1_0::IfaceType; +using V1_0::IWifiChip; + +/* The chip may either have a single mode supporting any number of combinations, + * or a fixed dual-mode (so it involves firmware loading to switch between + * modes) setting. If there is a need to support more modes, it needs to be + * implemented manually in WiFi HAL (see changeFirmwareMode in + * WifiChip::handleChipConfiguration). + * + * Supported combinations are defined in device's makefile, for example: + * WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}}, + * WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}} + * What means: + * Interface combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface + * operations. + * Interface combination 2: 1 STA and 2 AP concurrent iface operations. + * + * For backward compatibility, the following makefile flags can be used to + * generate combinations list: + * - WIFI_HIDL_FEATURE_DUAL_INTERFACE + * - WIFI_HIDL_FEATURE_DISABLE_AP + * - WIFI_HIDL_FEATURE_AWARE + * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided. + * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with + * two interface combinations: + * Interface Combination 1: Will support 1 STA and 1 P2P or NAN (optional) + * concurrent iface operations. + * Interface Combination 2: Will support 1 STA and 1 AP concurrent + * iface operations. + * + * The only dual-mode configuration supported is for alternating STA and AP + * mode, that may involve firmware reloading. In such case, there are 2 separate + * modes of operation with 1 interface combination each: + * Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional) + * concurrent iface operations. + * Mode 2 (AP mode): Will support 1 AP iface operation. + * + * If Aware is enabled, the iface combination will be modified to support either + * P2P or NAN in place of just P2P. + */ +// clang-format off +#ifdef WIFI_HAL_INTERFACE_COMBINATIONS +constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; +#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE) +// former V2 (fixed dual interface) setup expressed as V3 +constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; +# ifdef WIFI_HIDL_FEATURE_DISABLE_AP +# ifdef WIFI_HIDL_FEATURE_AWARE +// 1 STA + 1 of (P2P or NAN) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}} +# else +// 1 STA + 1 P2P +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} +# endif +# else +# ifdef WIFI_HIDL_FEATURE_AWARE +// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ + {{{STA}, 1}, {{P2P, NAN}, 1}} +# else +// (1 STA + 1 AP) or (1 STA + 1 P2P) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ + {{{STA}, 1}, {{P2P}, 1}} +# endif +# endif +#else +// V1 (fixed single interface, dual-mode chip) +constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta; +# ifdef WIFI_HIDL_FEATURE_AWARE +// 1 STA + 1 of (P2P or NAN) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}} +# else +// 1 STA + 1 P2P +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} +# endif + +# ifndef WIFI_HIDL_FEATURE_DISABLE_AP +# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}} +# endif +#endif +// clang-format on + +/** + * Helper class to convert a collection of combination limits to a combination. + * + * The main point here is to simplify the syntax required by + * WIFI_HAL_INTERFACE_COMBINATIONS. + */ +struct ChipIfaceCombination + : public hidl_vec<IWifiChip::ChipIfaceCombinationLimit> { + ChipIfaceCombination( + const std::initializer_list<IWifiChip::ChipIfaceCombinationLimit> list) + : hidl_vec(list) {} + + operator IWifiChip::ChipIfaceCombination() const { return {*this}; } + + static hidl_vec<IWifiChip::ChipIfaceCombination> make_vec( + const std::initializer_list<ChipIfaceCombination> list) { + return hidl_vec<IWifiChip::ChipIfaceCombination>( // + std::begin(list), std::end(list)); + } +}; + +#define STA IfaceType::STA +#define AP IfaceType::AP +#define P2P IfaceType::P2P +#define NAN IfaceType::NAN +static const std::vector<IWifiChip::ChipMode> kChipModes{ + {kMainModeId, + ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})}, +#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP + {chip_mode_ids::kV1Ap, + ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})}, +#endif +}; +#undef STA +#undef AP +#undef P2P +#undef NAN + +#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION +static const bool wifiHidlFeatureDisableApMacRandomization = true; +#else +static const bool wifiHidlFeatureDisableApMacRandomization = false; +#endif // WIFI_HIDL_FEATURE_DISABLE_AP + +WifiFeatureFlags::WifiFeatureFlags() {} + +std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes() { + return kChipModes; +} + +bool WifiFeatureFlags::isApMacRandomizationDisabled() { + return wifiHidlFeatureDisableApMacRandomization; +} + +} // namespace feature_flags +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.2/default/wifi_feature_flags.h b/wifi/1.3/default/wifi_feature_flags.h index 4a7b2d225..3ae692090 100644 --- a/wifi/1.2/default/wifi_feature_flags.h +++ b/wifi/1.3/default/wifi_feature_flags.h @@ -17,26 +17,38 @@ #ifndef WIFI_FEATURE_FLAGS_H_ #define WIFI_FEATURE_FLAGS_H_ +#include <android/hardware/wifi/1.2/IWifiChip.h> + namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace feature_flags { +namespace chip_mode_ids { +// These mode ID's should be unique (even across combo versions). Refer to +// handleChipConfiguration() for it's usage. +constexpr V1_0::ChipModeId kInvalid = UINT32_MAX; +// Mode ID's for V1 +constexpr V1_0::ChipModeId kV1Sta = 0; +constexpr V1_0::ChipModeId kV1Ap = 1; +// Mode ID for V3 +constexpr V1_0::ChipModeId kV3 = 3; +} // namespace chip_mode_ids + class WifiFeatureFlags { public: WifiFeatureFlags(); virtual ~WifiFeatureFlags() = default; - virtual bool isAwareSupported(); - virtual bool isDualInterfaceSupported(); - virtual bool isApDisabled(); + virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes(); + virtual bool isApMacRandomizationDisabled(); }; } // namespace feature_flags } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.3/default/wifi_iface_util.cpp new file mode 100644 index 000000000..5d6127141 --- /dev/null +++ b/wifi/1.3/default/wifi_iface_util.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstddef> +#include <iostream> +#include <limits> +#include <random> + +#include <android-base/logging.h> +#include <android-base/macros.h> +#include <private/android_filesystem_config.h> + +#undef NAN +#include "wifi_iface_util.h" + +namespace { +// Constants to set the local bit & clear the multicast bit. +constexpr uint8_t kMacAddressMulticastMask = 0x01; +constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +namespace iface_util { + +WifiIfaceUtil::WifiIfaceUtil() : random_mac_address_(nullptr) {} + +std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress( + const std::string& iface_name) { + return iface_tool_.GetFactoryMacAddress(iface_name.c_str()); +} + +bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, + const std::array<uint8_t, 6>& mac) { + if (!iface_tool_.SetUpState(iface_name.c_str(), false)) { + LOG(ERROR) << "SetUpState(false) failed."; + return false; + } + if (!iface_tool_.SetMacAddress(iface_name.c_str(), mac)) { + LOG(ERROR) << "SetMacAddress failed."; + return false; + } + if (!iface_tool_.SetUpState(iface_name.c_str(), true)) { + LOG(ERROR) << "SetUpState(true) failed."; + return false; + } + LOG(DEBUG) << "Successfully SetMacAddress."; + return true; +} + +std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() { + if (random_mac_address_) { + return *random_mac_address_.get(); + } + random_mac_address_ = + std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress()); + return *random_mac_address_.get(); +} + +std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() { + std::array<uint8_t, 6> address = {}; + std::random_device rd; + std::default_random_engine engine(rd()); + std::uniform_int_distribution<uint8_t> dist( + std::numeric_limits<uint8_t>::min(), + std::numeric_limits<uint8_t>::max()); + for (size_t i = 0; i < address.size(); i++) { + address[i] = dist(engine); + } + // Set the local bit and clear the multicast bit. + address[0] |= kMacAddressLocallyAssignedMask; + address[0] &= ~kMacAddressMulticastMask; + return address; +} +} // namespace iface_util +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.3/default/wifi_iface_util.h new file mode 100644 index 000000000..b2382344e --- /dev/null +++ b/wifi/1.3/default/wifi_iface_util.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WIFI_IFACE_UTIL_H_ +#define WIFI_IFACE_UTIL_H_ + +#include <wifi_system/interface_tool.h> + +#include <android/hardware/wifi/1.0/IWifi.h> + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_3 { +namespace implementation { +namespace iface_util { + +/** + * Util class for common iface operations. + */ +class WifiIfaceUtil { + public: + WifiIfaceUtil(); + virtual ~WifiIfaceUtil() = default; + + virtual std::array<uint8_t, 6> getFactoryMacAddress( + const std::string& iface_name); + virtual bool setMacAddress(const std::string& iface_name, + const std::array<uint8_t, 6>& mac); + // Get or create a random MAC address. The MAC address returned from + // this method will remain the same throughout the lifetime of the HAL + // daemon. (So, changes on every reboot) + virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress(); + + private: + std::array<uint8_t, 6> createRandomMacAddress(); + + wifi_system::InterfaceTool iface_tool_; + std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_; +}; + +} // namespace iface_util +} // namespace implementation +} // namespace V1_3 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_IFACE_UTIL_H_ diff --git a/wifi/1.2/default/wifi_legacy_hal.cpp b/wifi/1.3/default/wifi_legacy_hal.cpp index 375204c70..7f9b63575 100644 --- a/wifi/1.2/default/wifi_legacy_hal.cpp +++ b/wifi/1.3/default/wifi_legacy_hal.cpp @@ -18,6 +18,7 @@ #include <chrono> #include <android-base/logging.h> +#include <cutils/properties.h> #include "hidl_sync_util.h" #include "wifi_legacy_hal.h" @@ -35,6 +36,7 @@ static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128; static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32; static constexpr uint32_t kMaxRingBuffers = 10; static constexpr uint32_t kMaxStopCompleteWaitMs = 100; +static constexpr char kDriverPropName[] = "wlan.driver.status"; // Helper function to create a non-const char* for legacy Hal API's. std::vector<char> makeCharVec(const std::string& str) { @@ -48,7 +50,7 @@ std::vector<char> makeCharVec(const std::string& str) { namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace legacy_hal { // Legacy HAL functions accept "C" style function pointers, so use global @@ -366,6 +368,8 @@ wifi_error WifiLegacyHal::start() { LOG(ERROR) << "Timed out awaiting driver ready"; return status; } + property_set(kDriverPropName, "ok"); + LOG(DEBUG) << "Starting legacy HAL"; if (!iface_tool_.SetWifiUpState(true)) { LOG(ERROR) << "Failed to set WiFi interface up"; @@ -420,6 +424,8 @@ wifi_error WifiLegacyHal::stop( return WIFI_SUCCESS; } +bool WifiLegacyHal::isStarted() { return is_started_; } + std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion( const std::string& iface_name) { std::array<char, kMaxVersionStringLength> buffer; @@ -547,6 +553,7 @@ wifi_error WifiLegacyHal::startGscan( on_results_user_callback(id, cached_scan_results); return; } + FALLTHROUGH_INTENDED; } // Fall through if failed. Failure to retrieve cached scan // results should trigger a background scan failure. @@ -648,6 +655,8 @@ std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats( [&link_stats_ptr](wifi_request_id /* id */, wifi_iface_stat* iface_stats_ptr, int num_radios, wifi_radio_stat* radio_stats_ptr) { + wifi_radio_stat* l_radio_stats_ptr; + if (iface_stats_ptr != nullptr) { link_stats_ptr->iface = *iface_stats_ptr; link_stats_ptr->iface.num_peers = 0; @@ -658,20 +667,35 @@ std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats( LOG(ERROR) << "Invalid radio stats in link layer stats"; return; } + l_radio_stats_ptr = radio_stats_ptr; for (int i = 0; i < num_radios; i++) { LinkLayerRadioStats radio; - radio.stats = radio_stats_ptr[i]; + + radio.stats = *l_radio_stats_ptr; // Copy over the tx level array to the separate vector. - if (radio_stats_ptr[i].num_tx_levels > 0 && - radio_stats_ptr[i].tx_time_per_levels != nullptr) { + if (l_radio_stats_ptr->num_tx_levels > 0 && + l_radio_stats_ptr->tx_time_per_levels != nullptr) { radio.tx_time_per_levels.assign( - radio_stats_ptr[i].tx_time_per_levels, - radio_stats_ptr[i].tx_time_per_levels + - radio_stats_ptr[i].num_tx_levels); + l_radio_stats_ptr->tx_time_per_levels, + l_radio_stats_ptr->tx_time_per_levels + + l_radio_stats_ptr->num_tx_levels); } radio.stats.num_tx_levels = 0; radio.stats.tx_time_per_levels = nullptr; + /* Copy over the channel stat to separate vector */ + if (l_radio_stats_ptr->num_channels > 0) { + /* Copy the channel stats */ + radio.channel_stats.assign( + l_radio_stats_ptr->channels, + l_radio_stats_ptr->channels + + l_radio_stats_ptr->num_channels); + } link_stats_ptr->radios.push_back(radio); + l_radio_stats_ptr = + (wifi_radio_stat*)((u8*)l_radio_stats_ptr + + sizeof(wifi_radio_stat) + + (sizeof(wifi_channel_stat) * + l_radio_stats_ptr->num_channels)); } }; @@ -753,7 +777,7 @@ wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, } wifi_error WifiLegacyHal::startSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id, + const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type, const std::vector<uint8_t>& ip_packet_data, const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) { @@ -763,9 +787,9 @@ wifi_error WifiLegacyHal::startSendingOffloadedPacket( std::vector<uint8_t> dst_address_internal( dst_address.data(), dst_address.data() + dst_address.size()); return global_func_table_.wifi_start_sending_offloaded_packet( - cmd_id, getIfaceHandle(iface_name), ip_packet_data_internal.data(), - ip_packet_data_internal.size(), src_address_internal.data(), - dst_address_internal.data(), period_in_ms); + cmd_id, getIfaceHandle(iface_name), ether_type, + ip_packet_data_internal.data(), ip_packet_data_internal.size(), + src_address_internal.data(), dst_address_internal.data(), period_in_ms); } wifi_error WifiLegacyHal::stopSendingOffloadedPacket( @@ -792,6 +816,12 @@ wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) { getIfaceHandle(iface_name)); } +wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, + wifi_latency_mode mode) { + return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), + mode); +} + std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet( const std::string& iface_name) { uint32_t supported_feature_flags; @@ -1417,7 +1447,7 @@ void WifiLegacyHal::invalidate() { } // namespace legacy_hal } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_legacy_hal.h b/wifi/1.3/default/wifi_legacy_hal.h index 60905ab39..a3ed460b1 100644 --- a/wifi/1.2/default/wifi_legacy_hal.h +++ b/wifi/1.3/default/wifi_legacy_hal.h @@ -25,10 +25,17 @@ #include <wifi_system/interface_tool.h> +// HACK: The include inside the namespace below also transitively includes a +// bunch of libc headers into the namespace, which leads to functions like +// socketpair being defined in +// android::hardware::wifi::V1_1::implementation::legacy_hal. Include this one +// particular header as a hacky workaround until that's fixed. +#include <sys/socket.h> + namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { // This is in a separate namespace to prevent typename conflicts between // the legacy HAL types and the HIDL interface types. @@ -54,6 +61,7 @@ struct PacketFilterCapabilities { struct LinkLayerRadioStats { wifi_radio_stat stats; std::vector<uint32_t> tx_time_per_levels; + std::vector<wifi_channel_stat> channel_stats; }; struct LinkLayerStats { @@ -100,7 +108,8 @@ struct NanCallbackHandlers { on_event_transmit_follow_up; std::function<void(const NanRangeRequestInd&)> on_event_range_request; std::function<void(const NanRangeReportInd&)> on_event_range_report; - std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update; + std::function<void(const NanDataPathScheduleUpdateInd&)> + on_event_schedule_update; }; // Full scan results contain IE info and are hence passed by reference, to @@ -172,10 +181,12 @@ class WifiLegacyHal { // using a predefined timeout. virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock, const std::function<void()>& on_complete_callback); + // Checks if legacy HAL has successfully started + bool isStarted(); // Wrappers for all the functions in the legacy HAL function table. - std::pair<wifi_error, std::string> getDriverVersion( + virtual std::pair<wifi_error, std::string> getDriverVersion( const std::string& iface_name); - std::pair<wifi_error, std::string> getFirmwareVersion( + virtual std::pair<wifi_error, std::string> getFirmwareVersion( const std::string& iface_name); std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump( const std::string& iface_name); @@ -235,7 +246,7 @@ class WifiLegacyHal { fw_roaming_state_t state); wifi_error configureNdOffload(const std::string& iface_name, bool enable); wifi_error startSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id, + const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type, const std::vector<uint8_t>& ip_packet_data, const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms); @@ -243,9 +254,11 @@ class WifiLegacyHal { uint32_t cmd_id); wifi_error setScanningMacOui(const std::string& iface_name, const std::array<uint8_t, 3>& oui); - wifi_error selectTxPowerScenario(const std::string& iface_name, - wifi_power_scenario scenario); - wifi_error resetTxPowerScenario(const std::string& iface_name); + virtual wifi_error selectTxPowerScenario(const std::string& iface_name, + wifi_power_scenario scenario); + virtual wifi_error resetTxPowerScenario(const std::string& iface_name); + wifi_error setLatencyMode(const std::string& iface_name, + wifi_latency_mode mode); // Logger/debug functions. std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet( const std::string& iface_name); @@ -383,7 +396,7 @@ class WifiLegacyHal { } // namespace legacy_hal } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp b/wifi/1.3/default/wifi_legacy_hal_stubs.cpp index fc28bb55e..dedd2d481 100644 --- a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.3/default/wifi_legacy_hal_stubs.cpp @@ -20,7 +20,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace legacy_hal { template <typename> @@ -137,11 +137,12 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_select_tx_power_scenario); populateStubFor(&hal_fn->wifi_reset_tx_power_scenario); populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler); + populateStubFor(&hal_fn->wifi_set_latency_mode); return true; } } // namespace legacy_hal } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_legacy_hal_stubs.h b/wifi/1.3/default/wifi_legacy_hal_stubs.h index d560dd4e8..64854e00f 100644 --- a/wifi/1.2/default/wifi_legacy_hal_stubs.h +++ b/wifi/1.3/default/wifi_legacy_hal_stubs.h @@ -20,7 +20,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace legacy_hal { #include <hardware_legacy/wifi_hal.h> @@ -28,7 +28,7 @@ namespace legacy_hal { bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn); } // namespace legacy_hal } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_mode_controller.cpp b/wifi/1.3/default/wifi_mode_controller.cpp index c286d2439..c392486f8 100644 --- a/wifi/1.2/default/wifi_mode_controller.cpp +++ b/wifi/1.3/default/wifi_mode_controller.cpp @@ -48,7 +48,7 @@ int convertIfaceTypeToFirmwareMode(IfaceType type) { namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace mode_controller { @@ -85,7 +85,7 @@ bool WifiModeController::deinitialize() { } } // namespace mode_controller } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_mode_controller.h b/wifi/1.3/default/wifi_mode_controller.h index 395aa5d9e..ace5a5283 100644 --- a/wifi/1.2/default/wifi_mode_controller.h +++ b/wifi/1.3/default/wifi_mode_controller.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { namespace mode_controller { using namespace android::hardware::wifi::V1_0; @@ -55,7 +55,7 @@ class WifiModeController { } // namespace mode_controller } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_nan_iface.cpp b/wifi/1.3/default/wifi_nan_iface.cpp index 566d36e72..4325f44da 100644 --- a/wifi/1.2/default/wifi_nan_iface.cpp +++ b/wifi/1.3/default/wifi_nan_iface.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; @@ -420,7 +420,7 @@ WifiNanIface::WifiNanIface( LOG(ERROR) << "Callback invoked on an invalid object"; return; } - NanDataPathConfirmInd hidl_struct; + V1_2::NanDataPathConfirmInd hidl_struct; if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl( msg, &hidl_struct)) { LOG(ERROR) << "Failed to convert nan capabilities response"; @@ -477,7 +477,7 @@ WifiNanIface::WifiNanIface( LOG(ERROR) << "Callback invoked on an invalid object"; return; } - NanDataPathScheduleUpdateInd hidl_struct; + V1_2::NanDataPathScheduleUpdateInd hidl_struct; if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl( msg, &hidl_struct)) { LOG(ERROR) << "Failed to convert nan capabilities response"; @@ -655,7 +655,7 @@ Return<void> WifiNanIface::terminateDataPathRequest( } Return<void> WifiNanIface::registerEventCallback_1_2( - const sp<IWifiNanIfaceEventCallback>& callback, + const sp<V1_2::IWifiNanIfaceEventCallback>& callback, registerEventCallback_1_2_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiNanIface::registerEventCallback_1_2Internal, @@ -664,7 +664,7 @@ Return<void> WifiNanIface::registerEventCallback_1_2( Return<void> WifiNanIface::enableRequest_1_2( uint16_t cmd_id, const NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2, + const V1_2::NanConfigRequestSupplemental& msg2, enableRequest_1_2_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiNanIface::enableRequest_1_2Internal, @@ -673,7 +673,7 @@ Return<void> WifiNanIface::enableRequest_1_2( Return<void> WifiNanIface::configRequest_1_2( uint16_t cmd_id, const NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2, + const V1_2::NanConfigRequestSupplemental& msg2, configRequest_1_2_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiNanIface::configRequest_1_2Internal, @@ -832,7 +832,7 @@ WifiStatus WifiNanIface::registerEventCallback_1_2Internal( WifiStatus WifiNanIface::enableRequest_1_2Internal( uint16_t cmd_id, const NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2) { + const V1_2::NanConfigRequestSupplemental& msg2) { legacy_hal::NanEnableRequest legacy_msg; if (!hidl_struct_util::convertHidlNanEnableRequest_1_2ToLegacy( msg1, msg2, &legacy_msg)) { @@ -845,7 +845,7 @@ WifiStatus WifiNanIface::enableRequest_1_2Internal( WifiStatus WifiNanIface::configRequest_1_2Internal( uint16_t cmd_id, const NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2) { + const V1_2::NanConfigRequestSupplemental& msg2) { legacy_hal::NanConfigRequest legacy_msg; if (!hidl_struct_util::convertHidlNanConfigRequest_1_2ToLegacy( msg1, msg2, &legacy_msg)) { @@ -857,7 +857,7 @@ WifiStatus WifiNanIface::configRequest_1_2Internal( } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_nan_iface.h b/wifi/1.3/default/wifi_nan_iface.h index dba527b5f..f735d61cf 100644 --- a/wifi/1.2/default/wifi_nan_iface.h +++ b/wifi/1.3/default/wifi_nan_iface.h @@ -27,7 +27,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -89,15 +89,15 @@ class WifiNanIface : public V1_2::IWifiNanIface { terminateDataPathRequest_cb hidl_status_cb) override; Return<void> registerEventCallback_1_2( - const sp<IWifiNanIfaceEventCallback>& callback, + const sp<V1_2::IWifiNanIfaceEventCallback>& callback, registerEventCallback_1_2_cb hidl_status_cb) override; Return<void> enableRequest_1_2( uint16_t cmd_id, const NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2, + const V1_2::NanConfigRequestSupplemental& msg2, enableRequest_1_2_cb hidl_status_cb) override; Return<void> configRequest_1_2( uint16_t cmd_id, const NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2, + const V1_2::NanConfigRequestSupplemental& msg2, configRequest_1_2_cb hidl_status_cb) override; private: @@ -135,10 +135,10 @@ class WifiNanIface : public V1_2::IWifiNanIface { const sp<V1_2::IWifiNanIfaceEventCallback>& callback); WifiStatus enableRequest_1_2Internal( uint16_t cmd_id, const NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2); + const V1_2::NanConfigRequestSupplemental& msg2); WifiStatus configRequest_1_2Internal( uint16_t cmd_id, const NanConfigRequest& msg, - const NanConfigRequestSupplemental& msg2); + const V1_2::NanConfigRequestSupplemental& msg2); // all 1_0 and descendant callbacks std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks(); @@ -157,7 +157,7 @@ class WifiNanIface : public V1_2::IWifiNanIface { }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_p2p_iface.cpp b/wifi/1.3/default/wifi_p2p_iface.cpp index 92bbaee38..b5d5886f6 100644 --- a/wifi/1.2/default/wifi_p2p_iface.cpp +++ b/wifi/1.3/default/wifi_p2p_iface.cpp @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; @@ -60,7 +60,7 @@ std::pair<WifiStatus, IfaceType> WifiP2pIface::getTypeInternal() { } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_p2p_iface.h b/wifi/1.3/default/wifi_p2p_iface.h index 76120b157..8a7207a41 100644 --- a/wifi/1.2/default/wifi_p2p_iface.h +++ b/wifi/1.3/default/wifi_p2p_iface.h @@ -25,7 +25,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -58,7 +58,7 @@ class WifiP2pIface : public V1_0::IWifiP2pIface { }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_rtt_controller.cpp b/wifi/1.3/default/wifi_rtt_controller.cpp index b68445bf8..fa317e3ae 100644 --- a/wifi/1.2/default/wifi_rtt_controller.cpp +++ b/wifi/1.3/default/wifi_rtt_controller.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; @@ -269,7 +269,7 @@ WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) { return createWifiStatusFromLegacyError(legacy_status); } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_rtt_controller.h b/wifi/1.3/default/wifi_rtt_controller.h index 1ab01e170..9798b79f8 100644 --- a/wifi/1.2/default/wifi_rtt_controller.h +++ b/wifi/1.3/default/wifi_rtt_controller.h @@ -27,7 +27,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { /** @@ -97,7 +97,7 @@ class WifiRttController : public V1_0::IWifiRttController { }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_sta_iface.cpp b/wifi/1.3/default/wifi_sta_iface.cpp index daa56101c..a6539e5d9 100644 --- a/wifi/1.2/default/wifi_sta_iface.cpp +++ b/wifi/1.3/default/wifi_sta_iface.cpp @@ -24,14 +24,18 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using hidl_return_util::validateAndCall; WifiStaIface::WifiStaIface( const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) - : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) { + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) + : ifname_(ifname), + legacy_hal_(legacy_hal), + iface_util_(iface_util), + is_valid_(true) { // Turn on DFS channel usage for STA iface. legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true); @@ -152,6 +156,13 @@ Return<void> WifiStaIface::getLinkLayerStats( hidl_status_cb); } +Return<void> WifiStaIface::getLinkLayerStats_1_3( + getLinkLayerStats_1_3_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getLinkLayerStatsInternal_1_3, + hidl_status_cb); +} + Return<void> WifiStaIface::startRssiMonitoring( uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, startRssiMonitoring_cb hidl_status_cb) { @@ -248,6 +259,13 @@ Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac, mac); } +Return<void> WifiStaIface::getFactoryMacAddress( + getFactoryMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getFactoryMacAddressInternal, + hidl_status_cb); +} + std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -445,8 +463,13 @@ WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() { return createWifiStatusFromLegacyError(legacy_status); } -std::pair<WifiStatus, StaLinkLayerStats> +std::pair<WifiStatus, V1_0::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal() { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +std::pair<WifiStatus, V1_3::StaLinkLayerStats> +WifiStaIface::getLinkLayerStatsInternal_1_3() { legacy_hal::wifi_error legacy_status; legacy_hal::LinkLayerStats legacy_stats; std::tie(legacy_status, legacy_stats) = @@ -454,7 +477,7 @@ WifiStaIface::getLinkLayerStatsInternal() { if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } - StaLinkLayerStats hidl_stats; + V1_3::StaLinkLayerStats hidl_stats; if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; @@ -539,12 +562,12 @@ WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) { WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal( uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, - uint16_t /* ether_type */, const std::array<uint8_t, 6>& src_address, + uint16_t ether_type, const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) { legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket( - ifname_, cmd_id, ip_packet_data, src_address, dst_address, - period_in_ms); + ifname_, cmd_id, ether_type, ip_packet_data, src_address, + dst_address, period_in_ms); return createWifiStatusFromLegacyError(legacy_status); } @@ -603,26 +626,22 @@ WifiStaIface::getDebugRxPacketFatesInternal() { WifiStatus WifiStaIface::setMacAddressInternal( const std::array<uint8_t, 6>& mac) { - if (!iface_tool_.SetWifiUpState(false)) { - LOG(ERROR) << "SetWifiUpState(false) failed."; + bool status = iface_util_.lock()->setMacAddress(ifname_, mac); + if (!status) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } - - if (!iface_tool_.SetMacAddress(ifname_.c_str(), mac)) { - LOG(ERROR) << "SetMacAddress failed."; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - - if (!iface_tool_.SetWifiUpState(true)) { - LOG(ERROR) << "SetWifiUpState(true) failed."; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - LOG(DEBUG) << "Successfully SetMacAddress."; return createWifiStatus(WifiStatusCode::SUCCESS); } +std::pair<WifiStatus, std::array<uint8_t, 6>> +WifiStaIface::getFactoryMacAddressInternal() { + std::array<uint8_t, 6> mac = + iface_util_.lock()->getFactoryMacAddress(ifname_); + return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; +} + } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_sta_iface.h b/wifi/1.3/default/wifi_sta_iface.h index 71cd17d30..92249394b 100644 --- a/wifi/1.2/default/wifi_sta_iface.h +++ b/wifi/1.3/default/wifi_sta_iface.h @@ -19,27 +19,27 @@ #include <android-base/macros.h> #include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h> -#include <android/hardware/wifi/1.2/IWifiStaIface.h> - -#include <wifi_system/interface_tool.h> +#include <android/hardware/wifi/1.3/IWifiStaIface.h> #include "hidl_callback_util.h" +#include "wifi_iface_util.h" #include "wifi_legacy_hal.h" namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using namespace android::hardware::wifi::V1_0; /** * HIDL interface object used to control a STA Iface instance. */ -class WifiStaIface : public V1_2::IWifiStaIface { +class WifiStaIface : public V1_3::IWifiStaIface { public: WifiStaIface(const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util); // Refer to |WifiChip::invalidate()|. void invalidate(); bool isValid(); @@ -75,6 +75,8 @@ class WifiStaIface : public V1_2::IWifiStaIface { disableLinkLayerStatsCollection_cb hidl_status_cb) override; Return<void> getLinkLayerStats( getLinkLayerStats_cb hidl_status_cb) override; + Return<void> getLinkLayerStats_1_3( + getLinkLayerStats_1_3_cb hidl_status_cb) override; Return<void> startRssiMonitoring( uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, startRssiMonitoring_cb hidl_status_cb) override; @@ -107,6 +109,8 @@ class WifiStaIface : public V1_2::IWifiStaIface { getDebugRxPacketFates_cb hidl_status_cb) override; Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac, setMacAddress_cb hidl_status_cb) override; + Return<void> getFactoryMacAddress( + getFactoryMacAddress_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -130,7 +134,9 @@ class WifiStaIface : public V1_2::IWifiStaIface { WifiStatus stopBackgroundScanInternal(uint32_t cmd_id); WifiStatus enableLinkLayerStatsCollectionInternal(bool debug); WifiStatus disableLinkLayerStatsCollectionInternal(); - std::pair<WifiStatus, StaLinkLayerStats> getLinkLayerStatsInternal(); + std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal(); + std::pair<WifiStatus, V1_3::StaLinkLayerStats> + getLinkLayerStatsInternal_1_3(); WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi); WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); @@ -151,19 +157,21 @@ class WifiStaIface : public V1_2::IWifiStaIface { std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> getDebugRxPacketFatesInternal(); WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac); + std::pair<WifiStatus, std::array<uint8_t, 6>> + getFactoryMacAddressInternal(); std::string ifname_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; + std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; bool is_valid_; hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_; - wifi_system::InterfaceTool iface_tool_; DISALLOW_COPY_AND_ASSIGN(WifiStaIface); }; } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_status_util.cpp b/wifi/1.3/default/wifi_status_util.cpp index dd37b6ba8..0a5bb13d4 100644 --- a/wifi/1.2/default/wifi_status_util.cpp +++ b/wifi/1.3/default/wifi_status_util.cpp @@ -19,7 +19,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { std::string legacyErrorToString(legacy_hal::wifi_error error) { @@ -100,7 +100,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) { } } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.2/default/wifi_status_util.h b/wifi/1.3/default/wifi_status_util.h index e9136b38c..bc8baa9fe 100644 --- a/wifi/1.2/default/wifi_status_util.h +++ b/wifi/1.3/default/wifi_status_util.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_2 { +namespace V1_3 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -37,7 +37,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error); } // namespace implementation -} // namespace V1_2 +} // namespace V1_3 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.3/types.hal b/wifi/1.3/types.hal new file mode 100644 index 000000000..3b292b074 --- /dev/null +++ b/wifi/1.3/types.hal @@ -0,0 +1,89 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.3; + +import @1.0::StaLinkLayerRadioStats; +import @1.0::StaLinkLayerIfaceStats; +import @1.0::TimeStampInMs; +import @1.0::WifiChannelInfo; + +struct WifiChannelStats { + /** + * Channel information. + */ + WifiChannelInfo channel; + /** + * Total time for which the radio is awake on this channel. + */ + uint32_t onTimeInMs; + /** + * Total time for which CCA is held busy on this channel. + */ + uint32_t ccaBusyTimeInMs; +}; + +struct StaLinkLayerRadioStats { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::StaLinkLayerRadioStats V1_0; + + /** + * Total time for which the radio is awake due to NAN scan since boot or crash. + */ + uint32_t onTimeInMsForNanScan; + + /** + * Total time for which the radio is awake due to background scan since boot or crash. + */ + uint32_t onTimeInMsForBgScan; + + /** + * Total time for which the radio is awake due to roam scan since boot or crash. + */ + uint32_t onTimeInMsForRoamScan; + + /** + * Total time for which the radio is awake due to PNO scan since boot or crash. + */ + uint32_t onTimeInMsForPnoScan; + + /** + * Total time for which the radio is awake due to Hotspot 2.0 scans and GAS exchange since boot + * or crash. + */ + uint32_t onTimeInMsForHs20Scan; + + /** + * List of channel stats associated with this radio + */ + vec<WifiChannelStats> channelStats; +}; + +/** + * Link layer stats retrieved via |getLinkLayerStats|. + */ +struct StaLinkLayerStats { + StaLinkLayerIfaceStats iface; + vec<StaLinkLayerRadioStats> radios; + /** + * TimeStamp for each stats sample. + * This is the absolute milliseconds from boot when these stats were + * sampled. + */ + TimeStampInMs timeStampInMs; +};
\ No newline at end of file diff --git a/wifi/1.3/vts/OWNERS b/wifi/1.3/vts/OWNERS new file mode 100644 index 000000000..8bfb14882 --- /dev/null +++ b/wifi/1.3/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/1.3/vts/functional/Android.bp b/wifi/1.3/vts/functional/Android.bp new file mode 100644 index 000000000..53c8f0851 --- /dev/null +++ b/wifi/1.3/vts/functional/Android.bp @@ -0,0 +1,32 @@ +// +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_test { + name: "VtsHalWifiV1_3TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalWifiV1_3TargetTest.cpp", + "wifi_chip_hidl_test.cpp", + "wifi_sta_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + ], +} diff --git a/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp b/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp new file mode 100644 index 000000000..faf426e99 --- /dev/null +++ b/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android/hardware/wifi/1.3/IWifi.h> + +#include "wifi_hidl_test_utils.h" + +using ::android::hardware::wifi::V1_3::IWifi; + +// Test environment for Wifi HIDL HAL. +class WifiHidlEnvironment_1_3 : public WifiHidlEnvironment { + public: + // get the test environment singleton + static WifiHidlEnvironment_1_3* Instance() { + static WifiHidlEnvironment_1_3* instance = new WifiHidlEnvironment_1_3; + return instance; + } + + virtual void registerTestServices() override { + registerTestService<android::hardware::wifi::V1_3::IWifi>(); + } + + private: + WifiHidlEnvironment_1_3() {} +}; + +WifiHidlEnvironment_1_3* gEnv = WifiHidlEnvironment_1_3::Instance(); + +int main(int argc, char** argv) { + ::testing::AddGlobalTestEnvironment(gEnv); + ::testing::InitGoogleTest(&argc, argv); + gEnv->init(&argc, argv); + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + return status; +} diff --git a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp new file mode 100644 index 000000000..d980fcb31 --- /dev/null +++ b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> + +#include <android/hardware/wifi/1.3/IWifiChip.h> + +#include <VtsHalHidlTargetTestBase.h> + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::IfaceType; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_3::IWifiChip; + +namespace { +constexpr IWifiChip::LatencyMode kLatencyModeNormal = + IWifiChip::LatencyMode::NORMAL; + +constexpr IWifiChip::LatencyMode kLatencyModeLow = IWifiChip::LatencyMode::LOW; +}; // namespace + +/** + * Fixture to use for all Wifi chip HIDL interface tests. + */ +class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + wifi_chip_ = IWifiChip::castFrom(getWifiChip()); + ASSERT_NE(nullptr, wifi_chip_.get()); + } + + virtual void TearDown() override { stopWifi(); } + + protected: + // Helper function to configure the Chip in one of the supported modes. + // Most of the non-mode-configuration-related methods require chip + // to be first configured. + ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) { + ChipModeId mode_id; + EXPECT_EQ(expectSuccess, + configureChipToSupportIfaceType(wifi_chip_, type, &mode_id)); + return mode_id; + } + + uint32_t configureChipForStaIfaceAndGetCapabilities() { + ChipModeId mode_id; + EXPECT_TRUE(configureChipToSupportIfaceType(wifi_chip_, IfaceType::STA, + &mode_id)); + const auto& status_and_caps = + HIDL_INVOKE(wifi_chip_, getCapabilities_1_3); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + return status_and_caps.second; + } + + sp<IWifiChip> wifi_chip_; +}; + +/* + * SetLatencyMode_normal + * This test case tests the setLatencyMode() API with + * Latency mode NORMAL + */ +TEST_F(WifiChipHidlTest, SetLatencyMode_normal) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + const auto& status = + HIDL_INVOKE(wifi_chip_, setLatencyMode, kLatencyModeNormal); + if (caps & (IWifiChip::ChipCapabilityMask::SET_LATENCY_MODE)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code); + } +} + +/* + * SetLatencyMode_low + * This test case tests the setLatencyMode() API with Latency mode LOW + */ +TEST_F(WifiChipHidlTest, SetLatencyMode_low) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + const auto& status = + HIDL_INVOKE(wifi_chip_, setLatencyMode, kLatencyModeLow); + if (caps & (IWifiChip::ChipCapabilityMask::SET_LATENCY_MODE)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code); + } +} + +/* + * GetCapabilities_1_3 + */ +TEST_F(WifiChipHidlTest, GetCapabilities_1_3) { + configureChipForIfaceType(IfaceType::STA, true); + const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities_1_3); + if (status_and_caps.first.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_caps.first.code); + return; + } + EXPECT_NE(0u, status_and_caps.second); +} diff --git a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp new file mode 100644 index 000000000..71e90acb9 --- /dev/null +++ b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Staache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <numeric> +#include <vector> + +#include <android-base/logging.h> + +#include <android/hardware/wifi/1.3/IWifiStaIface.h> + +#include <VtsHalHidlTargetTestBase.h> + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_3::IWifiStaIface; + +/** + * Fixture to use for all STA Iface HIDL interface tests. + */ +class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + wifi_sta_iface_ = IWifiStaIface::castFrom(getWifiStaIface()); + ASSERT_NE(nullptr, wifi_sta_iface_.get()); + } + + virtual void TearDown() override { stopWifi(); } + + protected: + bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) { + const auto& status_and_caps = + HIDL_INVOKE(wifi_sta_iface_, getCapabilities); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + return (status_and_caps.second & cap_mask) != 0; + } + + sp<IWifiStaIface> wifi_sta_iface_; +}; + +/* + * GetFactoryMacAddress: + * Ensures that calls to get factory MAC address will retrieve a non-zero MAC + * and return a success status code. + */ +TEST_F(WifiStaIfaceHidlTest, GetFactoryMacAddress) { + const auto& status_and_mac = + HIDL_INVOKE(wifi_sta_iface_, getFactoryMacAddress); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_mac.first.code); + const int num_elements = sizeof(status_and_mac.second) / sizeof(uint8_t); + EXPECT_EQ(6, num_elements); + for (int i = 0; i < num_elements; i++) { + EXPECT_NE(0, status_and_mac.second[i]); + } +} + +/* + * GetLinkLayerStats_1_3 + * Ensures that calls to get link layer stats V1_3 will retrieve a non-empty + * StaLinkLayerStats after link layer stats collection is enabled. + */ +TEST_F(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) { + if (!isCapabilitySupported( + IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) { + // No-op if link layer stats is not supported. + return; + } + + // Enable link layer stats collection. + EXPECT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true) + .code); + // Retrieve link layer stats. + const auto& status_and_stats = + HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats_1_3); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code); + EXPECT_GT(status_and_stats.second.timeStampInMs, 0u); + // Disable link layer stats collection. + EXPECT_EQ( + WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code); +} diff --git a/wifi/hostapd/1.0/Android.bp b/wifi/hostapd/1.0/Android.bp index a17e15346..9ee976e6d 100644 --- a/wifi/hostapd/1.0/Android.bp +++ b/wifi/hostapd/1.0/Android.bp @@ -14,10 +14,6 @@ hidl_interface { "android.hardware.wifi.supplicant@1.0", "android.hidl.base@1.0", ], - types: [ - "HostapdStatus", - "HostapdStatusCode", - ], gen_java: true, } diff --git a/wifi/hostapd/1.0/vts/OWNERS b/wifi/hostapd/1.0/vts/OWNERS new file mode 100644 index 000000000..8bfb14882 --- /dev/null +++ b/wifi/hostapd/1.0/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp index 7a920b448..93867d28a 100644 --- a/wifi/hostapd/1.0/vts/functional/Android.bp +++ b/wifi/hostapd/1.0/vts/functional/Android.bp @@ -24,6 +24,7 @@ cc_library_static { static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.hostapd@1.1", "android.hardware.wifi@1.0", "libcrypto", "libgmock", @@ -43,10 +44,12 @@ cc_test { "VtsHalWifiV1_0TargetTestUtil", "VtsHalWifiHostapdV1_0TargetTestUtil", "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.hostapd@1.1", "android.hardware.wifi@1.0", "libcrypto", "libgmock", "libwifi-system", "libwifi-system-iface", ], + test_suites: ["general-tests"], } diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp index 504f4c8d2..6dc9eb4be 100644 --- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp @@ -41,6 +41,7 @@ constexpr int kIfaceInvalidChannel = 567; class HostapdHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { + stopSupplicantIfNeeded(); startHostapdAndWaitForHidlService(); hostapd_ = getHostapd(); ASSERT_NE(hostapd_.get(), nullptr); @@ -138,9 +139,11 @@ TEST(HostapdHidlTestNoFixture, Create) { * Access point creation should pass. */ TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithAcs(), - getPskNwParams()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint, + getIfaceParamsWithAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -148,9 +151,11 @@ TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) { * Access point creation should pass. */ TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithAcs(), - getOpenNwParams()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint, + getIfaceParamsWithAcs(), getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -158,9 +163,11 @@ TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) { * Access point creation should pass. */ TEST_F(HostapdHidlTest, AddPskAccessPointWithoutAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint, - getIfaceParamsWithoutAcs(), getPskNwParams()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint, + getIfaceParamsWithoutAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -168,9 +175,12 @@ TEST_F(HostapdHidlTest, AddPskAccessPointWithoutAcs) { * Access point creation should pass. */ TEST_F(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint, - getIfaceParamsWithoutAcs(), getOpenNwParams()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(), + getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -178,12 +188,14 @@ TEST_F(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { * Access point creation & removal should pass. */ TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithAcs(), - getPskNwParams()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); - status = - HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint, + getIfaceParamsWithAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + status = + HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -191,12 +203,14 @@ TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) { * Access point creation & removal should pass. */ TEST_F(HostapdHidlTest, RemoveAccessPointWithoutAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint, - getIfaceParamsWithoutAcs(), getPskNwParams()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); - status = - HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); - EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint, + getIfaceParamsWithoutAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + status = + HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -204,10 +218,12 @@ TEST_F(HostapdHidlTest, RemoveAccessPointWithoutAcs) { * Access point creation should fail. */ TEST_F(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { - auto status = - HIDL_INVOKE(hostapd_, addAccessPoint, - getIfaceParamsWithInvalidChannel(), getPskNwParams()); - EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint, + getIfaceParamsWithInvalidChannel(), getPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); + } } /** @@ -215,10 +231,12 @@ TEST_F(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { * Access point creation should fail. */ TEST_F(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { - auto status = - HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(), - getInvalidPskNwParams()); - EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); + if (!is_1_1(hostapd_)) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(), + getInvalidPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); + } } /* diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp index e5ba8efa9..1c499e746 100644 --- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp +++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp @@ -23,24 +23,26 @@ #include <wifi_system/hostapd_manager.h> #include <wifi_system/interface_tool.h> +#include <wifi_system/supplicant_manager.h> #include "hostapd_hidl_test_utils.h" #include "wifi_hidl_test_utils.h" using ::android::sp; using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::joinRpcThreadpool; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; +using ::android::hardware::joinRpcThreadpool; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::hardware::wifi::V1_0::ChipModeId; -using ::android::hardware::wifi::V1_0::IWifiChip; -using ::android::hardware::wifi::hostapd::V1_0::IHostapd; using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus; using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode; +using ::android::hardware::wifi::hostapd::V1_0::IHostapd; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::IWifiChip; using ::android::hidl::manager::V1_0::IServiceNotification; using ::android::wifi_system::HostapdManager; +using ::android::wifi_system::SupplicantManager; extern WifiHostapdHidlEnvironment* gEnv; @@ -108,6 +110,16 @@ class ServiceNotificationListener : public IServiceNotification { std::condition_variable condition_; }; +void stopSupplicantIfNeeded() { + SupplicantManager supplicant_manager; + if (supplicant_manager.IsSupplicantRunning()) { + LOG(INFO) << "Supplicant is running, stop supplicant first."; + ASSERT_TRUE(supplicant_manager.StopSupplicant()); + deInitilializeDriverAndFirmware(); + ASSERT_FALSE(supplicant_manager.IsSupplicantRunning()); + } +} + void stopHostapd() { HostapdManager hostapd_manager; @@ -130,6 +142,12 @@ void startHostapdAndWaitForHidlService() { ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name)); } +bool is_1_1(const sp<IHostapd>& hostapd) { + sp<::android::hardware::wifi::hostapd::V1_1::IHostapd> hostapd_1_1 = + ::android::hardware::wifi::hostapd::V1_1::IHostapd::castFrom(hostapd); + return hostapd_1_1.get() != nullptr; +} + sp<IHostapd> getHostapd() { return ::testing::VtsHalHidlTargetTestBase::getService<IHostapd>( gEnv->getServiceName<IHostapd>()); diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h index 1b9247732..9b3df4206 100644 --- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h +++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h @@ -18,12 +18,14 @@ #define HOSTAPD_HIDL_TEST_UTILS_H #include <android/hardware/wifi/hostapd/1.0/IHostapd.h> +#include <android/hardware/wifi/hostapd/1.1/IHostapd.h> #include <VtsHalHidlTargetTestEnvBase.h> // Used to stop the android wifi framework before every test. void stopWifiFramework(); void startWifiFramework(); +void stopSupplicantIfNeeded(); void stopHostapd(); // Used to configure the chip, driver and start wpa_hostapd before every // test. @@ -34,6 +36,8 @@ void startHostapdAndWaitForHidlService(); // These helper functions should be modified to return vectors if we support // multiple instances. android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd> getHostapd(); +bool is_1_1(const android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd>& + hostapd); class WifiHostapdHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { diff --git a/wifi/hostapd/1.1/Android.bp b/wifi/hostapd/1.1/Android.bp new file mode 100644 index 000000000..d4170b678 --- /dev/null +++ b/wifi/hostapd/1.1/Android.bp @@ -0,0 +1,20 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.wifi.hostapd@1.1", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IHostapd.hal", + "IHostapdCallback.hal", + ], + interfaces: [ + "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.supplicant@1.0", + "android.hidl.base@1.0", + ], + gen_java: true, +} + diff --git a/wifi/hostapd/1.1/IHostapd.hal b/wifi/hostapd/1.1/IHostapd.hal new file mode 100644 index 000000000..c144f6a03 --- /dev/null +++ b/wifi/hostapd/1.1/IHostapd.hal @@ -0,0 +1,103 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.hostapd@1.1; + +import @1.0::IHostapd; +import @1.0::HostapdStatus; + +import IHostapdCallback; + +/** + * Top-level object for managing SoftAPs. + */ +interface IHostapd extends @1.0::IHostapd { + /** + * Parameters to specify the channel range for ACS. + */ + struct AcsChannelRange { + /** + * Channel number (IEEE 802.11) at the start of the range. + */ + uint32_t start; + /** + * Channel number (IEEE 802.11) at the end of the range. + */ + uint32_t end; + }; + + /** + * Parameters to control the channel selection for the interface. + */ + struct ChannelParams { + /** + * This option can be used to specify the channels selected by ACS. + * If this is an empty list, all channels allowed in selected HW mode + * are specified implicitly. + * Note: channels may be overridden by firmware. + * Note: this option is ignored if ACS is disabled. + */ + vec<AcsChannelRange> acsChannelRanges; + }; + + /** + * Parameters to use for setting up the access point interface. + */ + struct IfaceParams { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::IHostapd.IfaceParams V1_0; + /** Additional Channel params for the interface */ + ChannelParams channelParams; + }; + + /** + * Adds a new access point for hostapd to control. + * + * This should trigger the setup of an access point with the specified + * interface and network params. + * + * @param ifaceParams AccessPoint Params for the access point. + * @param nwParams Network Params for the access point. + * @return status Status of the operation. + * Possible status codes: + * |HostapdStatusCode.SUCCESS|, + * |HostapdStatusCode.FAILURE_ARGS_INVALID|, + * |HostapdStatusCode.FAILURE_UNKNOWN|, + * |HostapdStatusCode.FAILURE_IFACE_EXISTS| + */ + addAccessPoint_1_1(IfaceParams ifaceParams, NetworkParams nwParams) + generates(HostapdStatus status); + + /** + * Register for callbacks from the hostapd service. + * + * These callbacks are invoked for global events that are not specific + * to any interface or network. Registration of multiple callback + * objects is supported. These objects must be deleted when the corresponding + * client process is dead. + * + * @param callback An instance of the |IHostapdCallback| HIDL interface + * object. + * @return status Status of the operation. + * Possible status codes: + * |HostapdStatusCode.SUCCESS|, + * |HostapdStatusCode.FAILURE_UNKNOWN| + */ + registerCallback(IHostapdCallback callback) + generates (HostapdStatus status); +}; diff --git a/wifi/hostapd/1.1/IHostapdCallback.hal b/wifi/hostapd/1.1/IHostapdCallback.hal new file mode 100644 index 000000000..1d314fe91 --- /dev/null +++ b/wifi/hostapd/1.1/IHostapdCallback.hal @@ -0,0 +1,30 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.hostapd@1.1; + +/** + * Top-level object for managing SoftAPs. + */ +interface IHostapdCallback { + /** + * Invoked when an asynchronous failure is encountered in one of the access + * points added via |IHostapd.addAccessPoint|. + * + * @param ifaceName Name of the interface. + */ + oneway onFailure(string ifaceName); +}; diff --git a/wifi/hostapd/1.1/vts/OWNERS b/wifi/hostapd/1.1/vts/OWNERS new file mode 100644 index 000000000..8bfb14882 --- /dev/null +++ b/wifi/hostapd/1.1/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp new file mode 100644 index 000000000..bbf5246ce --- /dev/null +++ b/wifi/hostapd/1.1/vts/functional/Android.bp @@ -0,0 +1,58 @@ +// +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_static { + name: "VtsHalWifiHostapdV1_1TargetTestUtil", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["hostapd_hidl_test_utils_1_1.cpp"], + export_include_dirs: [ + "." + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiHostapdV1_0TargetTestUtil", + "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.hostapd@1.1", + "android.hardware.wifi@1.0", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], +} + +cc_test { + name: "VtsHalWifiHostapdV1_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalWifiHostapdV1_1TargetTest.cpp", + "hostapd_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiHostapdV1_0TargetTestUtil", + "VtsHalWifiHostapdV1_1TargetTestUtil", + "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.hostapd@1.1", + "android.hardware.wifi@1.0", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], + test_suites: ["general-tests"], +} + diff --git a/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp b/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp new file mode 100644 index 000000000..6916db2ca --- /dev/null +++ b/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android/hardware/wifi/1.0/IWifi.h> + +#include "hostapd_hidl_test_utils.h" +#include "hostapd_hidl_test_utils_1_1.h" + +class WifiHostapdHidlEnvironment_1_1 : public WifiHostapdHidlEnvironment { + public: + // get the test environment singleton + static WifiHostapdHidlEnvironment_1_1* Instance() { + static WifiHostapdHidlEnvironment_1_1* instance = + new WifiHostapdHidlEnvironment_1_1; + return instance; + } + + virtual void registerTestServices() override { + registerTestService<::android::hardware::wifi::V1_0::IWifi>(); + registerTestService<android::hardware::wifi::hostapd::V1_0::IHostapd>(); + registerTestService<android::hardware::wifi::hostapd::V1_1::IHostapd>(); + } + + private: + WifiHostapdHidlEnvironment_1_1() {} +}; + +WifiHostapdHidlEnvironment* gEnv = WifiHostapdHidlEnvironment_1_1::Instance(); + +int main(int argc, char** argv) { + ::testing::AddGlobalTestEnvironment(gEnv); + ::testing::InitGoogleTest(&argc, argv); + gEnv->init(&argc, argv); + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + return status; +} diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp new file mode 100644 index 000000000..26a58b2c6 --- /dev/null +++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <cutils/properties.h> + +#include <VtsHalHidlTargetTestBase.h> + +#include <android/hardware/wifi/hostapd/1.1/IHostapd.h> + +#include "hostapd_hidl_call_util.h" +#include "hostapd_hidl_test_utils.h" +#include "hostapd_hidl_test_utils_1_1.h" + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus; +using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode; +using ::android::hardware::wifi::hostapd::V1_1::IHostapd; +using ::android::hardware::wifi::hostapd::V1_1::IHostapdCallback; + +namespace { +constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', + '2', '3', '4', '5'}; +constexpr char kNwPassphrase[] = "test12345"; +constexpr int kIfaceChannel = 6; +constexpr int kIfaceInvalidChannel = 567; +} // namespace + +class HostapdHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + stopSupplicantIfNeeded(); + startHostapdAndWaitForHidlService(); + hostapd_ = getHostapd_1_1(); + ASSERT_NE(hostapd_.get(), nullptr); + } + + virtual void TearDown() override { stopHostapd(); } + + protected: + std::string getPrimaryWlanIfaceName() { + std::array<char, PROPERTY_VALUE_MAX> buffer; + property_get("wifi.interface", buffer.data(), "wlan0"); + return buffer.data(); + } + + IHostapd::IfaceParams getIfaceParamsWithAcs() { + ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams + iface_params; + IHostapd::IfaceParams iface_params_1_1; + + iface_params.ifaceName = getPrimaryWlanIfaceName(); + iface_params.hwModeParams.enable80211N = true; + iface_params.hwModeParams.enable80211AC = false; + iface_params.channelParams.enableAcs = true; + iface_params.channelParams.acsShouldExcludeDfs = true; + iface_params.channelParams.channel = 0; + iface_params.channelParams.band = IHostapd::Band::BAND_ANY; + iface_params_1_1.V1_0 = iface_params; + return iface_params_1_1; + } + + IHostapd::IfaceParams getIfaceParamsWithAcsAndChannelRange() { + IHostapd::IfaceParams iface_params_1_1 = getIfaceParamsWithAcs(); + IHostapd::ChannelParams channelParams; + IHostapd::AcsChannelRange acsChannelRange; + acsChannelRange.start = 1; + acsChannelRange.end = 11; + std::vector<IHostapd::AcsChannelRange> vec_acsChannelRange; + vec_acsChannelRange.push_back(acsChannelRange); + channelParams.acsChannelRanges = vec_acsChannelRange; + iface_params_1_1.channelParams = channelParams; + return iface_params_1_1; + } + + IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidChannelRange() { + IHostapd::IfaceParams iface_params_1_1 = + getIfaceParamsWithAcsAndChannelRange(); + iface_params_1_1.channelParams.acsChannelRanges[0].start = 222; + iface_params_1_1.channelParams.acsChannelRanges[0].end = 999; + return iface_params_1_1; + } + + IHostapd::IfaceParams getIfaceParamsWithoutAcs() { + ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams + iface_params; + IHostapd::IfaceParams iface_params_1_1; + + iface_params.ifaceName = getPrimaryWlanIfaceName(); + iface_params.hwModeParams.enable80211N = true; + iface_params.hwModeParams.enable80211AC = false; + iface_params.channelParams.enableAcs = false; + iface_params.channelParams.acsShouldExcludeDfs = false; + iface_params.channelParams.channel = kIfaceChannel; + iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ; + iface_params_1_1.V1_0 = iface_params; + return iface_params_1_1; + } + + IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() { + IHostapd::IfaceParams iface_params_1_1 = getIfaceParamsWithoutAcs(); + iface_params_1_1.V1_0.channelParams.channel = kIfaceInvalidChannel; + return iface_params_1_1; + } + + IHostapd::NetworkParams getPskNwParams() { + IHostapd::NetworkParams nw_params; + nw_params.ssid = + std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid)); + nw_params.isHidden = false; + nw_params.encryptionType = IHostapd::EncryptionType::WPA2; + nw_params.pskPassphrase = kNwPassphrase; + return nw_params; + } + + IHostapd::NetworkParams getInvalidPskNwParams() { + IHostapd::NetworkParams nw_params; + nw_params.ssid = + std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid)); + nw_params.isHidden = false; + nw_params.encryptionType = IHostapd::EncryptionType::WPA2; + return nw_params; + } + + IHostapd::NetworkParams getOpenNwParams() { + IHostapd::NetworkParams nw_params; + nw_params.ssid = + std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid)); + nw_params.isHidden = false; + nw_params.encryptionType = IHostapd::EncryptionType::NONE; + return nw_params; + } + + // IHostapd object used for all tests in this fixture. + sp<IHostapd> hostapd_; +}; + +class IfaceCallback : public IHostapdCallback { + Return<void> onFailure( + const hidl_string& /* Name of the interface */) override { + return Void(); + } +}; + +/* + * RegisterCallback + */ +TEST_F(HostapdHidlTest, registerCallback) { + hostapd_->registerCallback( + new IfaceCallback(), [](const HostapdStatus& status) { + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + }); +} + +/** + * Adds an access point with PSK network config & ACS enabled. + * Access point creation should pass. + */ +TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with PSK network config, ACS enabled & channel Range. + * Access point creation should pass. + */ +TEST_F(HostapdHidlTest, AddPskAccessPointWithAcsAndChannelRange) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithAcsAndChannelRange(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid channel range. + * Access point creation should fail. + */ +TEST_F(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidChannelRange) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithAcsAndInvalidChannelRange(), + getPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with Open network config & ACS enabled. + * Access point creation should pass. + */ +TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithAcs(), getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with PSK network config & ACS disabled. + * Access point creation should pass. + */ +TEST_F(HostapdHidlTest, AddPskAccessPointWithoutAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithoutAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with Open network config & ACS disabled. + * Access point creation should pass. + */ +TEST_F(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithoutAcs(), getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds & then removes an access point with PSK network config & ACS enabled. + * Access point creation & removal should pass. + */ +TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + status = + HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds & then removes an access point with PSK network config & ACS disabled. + * Access point creation & removal should pass. + */ +TEST_F(HostapdHidlTest, RemoveAccessPointWithoutAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithoutAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); + status = + HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid channel. + * Access point creation should fail. + */ +TEST_F(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_1, + getIfaceParamsWithInvalidChannel(), getPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid PSK network config. + * Access point creation should fail. + */ +TEST_F(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_1, getIfaceParamsWithoutAcs(), + getInvalidPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.cpp new file mode 100644 index 000000000..8bb72a19f --- /dev/null +++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <VtsHalHidlTargetTestBase.h> +#include <android-base/logging.h> + +#include "hostapd_hidl_test_utils.h" +#include "hostapd_hidl_test_utils_1_1.h" + +using ::android::sp; +using ::android::hardware::wifi::hostapd::V1_1::IHostapd; + +sp<IHostapd> getHostapd_1_1() { return IHostapd::castFrom(getHostapd()); } diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.h b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.h new file mode 100644 index 000000000..c43ddfa20 --- /dev/null +++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HOSTAPD_HIDL_TEST_UTILS_1_1_H +#define HOSTAPD_HIDL_TEST_UTILS_1_1_H + +#include <android/hardware/wifi/hostapd/1.1/IHostapd.h> + +#include <VtsHalHidlTargetTestEnvBase.h> + +// Helper functions to obtain references to the various HIDL interface objects. +// Note: We only have a single instance of each of these objects currently. +// These helper functions should be modified to return vectors if we support +// multiple instances. +android::sp<android::hardware::wifi::hostapd::V1_1::IHostapd> getHostapd_1_1(); + +#endif /* HOSTAPD_HIDL_TEST_UTILS_1_1_H */ diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp index c6c0e7a78..1a9ae73c8 100644 --- a/wifi/offload/1.0/Android.bp +++ b/wifi/offload/1.0/Android.bp @@ -14,20 +14,6 @@ hidl_interface { interfaces: [ "android.hidl.base@1.0", ], - types: [ - "Capability", - "LogRecord", - "NetworkInfo", - "OffloadStatus", - "OffloadStatusCode", - "RecordName", - "ScanFilter", - "ScanParam", - "ScanRecord", - "ScanResult", - "ScanStats", - "SecurityMode", - ], gen_java: false, } diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp index 140e45e2d..de15aa74e 100644 --- a/wifi/offload/1.0/vts/functional/Android.bp +++ b/wifi/offload/1.0/vts/functional/Android.bp @@ -19,4 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalWifiOffloadV1_0TargetTest.cpp"], static_libs: ["android.hardware.wifi.offload@1.0"], + test_suites: ["general-tests"], } diff --git a/wifi/supplicant/1.0/Android.bp b/wifi/supplicant/1.0/Android.bp index fc7ce55e3..c99706d2f 100644 --- a/wifi/supplicant/1.0/Android.bp +++ b/wifi/supplicant/1.0/Android.bp @@ -24,13 +24,6 @@ hidl_interface { interfaces: [ "android.hidl.base@1.0", ], - types: [ - "IfaceType", - "P2pGroupCapabilityMask", - "SupplicantStatus", - "SupplicantStatusCode", - "WpsConfigMethods", - ], gen_java: true, } diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp index ee6a68e04..bdccac191 100644 --- a/wifi/supplicant/1.0/vts/functional/Android.bp +++ b/wifi/supplicant/1.0/vts/functional/Android.bp @@ -39,7 +39,6 @@ cc_test { srcs: [ "VtsHalWifiSupplicantV1_0TargetTest.cpp", "supplicant_hidl_test.cpp", - "supplicant_p2p_iface_hidl_test.cpp", "supplicant_sta_iface_hidl_test.cpp", "supplicant_sta_network_hidl_test.cpp", ], @@ -54,4 +53,25 @@ cc_test { "libwifi-system", "libwifi-system-iface", ], + test_suites: ["general-tests"], +} + +cc_test { + name: "VtsHalWifiSupplicantP2pV1_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalWifiSupplicantV1_0TargetTest.cpp", + "supplicant_p2p_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi@1.0", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], } diff --git a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp index adf2a85ab..6ca0546cf 100644 --- a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp +++ b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp @@ -44,7 +44,10 @@ int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(gEnv); ::testing::InitGoogleTest(&argc, argv); gEnv->init(&argc, argv); - int status = RUN_ALL_TESTS(); - LOG(INFO) << "Test result = " << status; + int status = gEnv->initFromOptions(argc, argv); + if (status == 0) { + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + } return status; } diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp index c6ac03ce6..436b88b81 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp @@ -30,6 +30,8 @@ using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_0::IfaceType; +extern WifiSupplicantHidlEnvironment* gEnv; + class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { @@ -72,10 +74,13 @@ TEST_F(SupplicantHidlTest, ListInterfaces) { std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) { return iface.type == IfaceType::STA; })); - EXPECT_NE(ifaces.end(), - std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) { - return iface.type == IfaceType::P2P; - })); + if (gEnv->isP2pOn) { + EXPECT_NE( + ifaces.end(), + std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) { + return iface.type == IfaceType::P2P; + })); + } } /* @@ -178,8 +183,10 @@ TEST_F(SupplicantHidlTest, SetConcurrencyPriority) { IfaceType::STA, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); - supplicant_->setConcurrencyPriority( - IfaceType::P2P, [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - }); + if (gEnv->isP2pOn) { + supplicant_->setConcurrencyPriority( + IfaceType::P2P, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + } } diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp index bdedfba25..47c305600 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp @@ -225,7 +225,9 @@ sp<ISupplicant> getSupplicant() { // For 1.1 supplicant, we need to add interfaces at initialization. if (is_1_1(supplicant)) { addSupplicantStaIface_1_1(supplicant); - addSupplicantP2pIface_1_1(supplicant); + if (gEnv->isP2pOn) { + addSupplicantP2pIface_1_1(supplicant); + } } return supplicant; } diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h index d4a768fb5..21a1ae62d 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h @@ -23,6 +23,8 @@ #include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h> #include <android/hardware/wifi/supplicant/1.1/ISupplicant.h> +#include <getopt.h> + #include <VtsHalHidlTargetTestEnvBase.h> // Used to stop the android wifi framework before every test. @@ -50,11 +52,48 @@ bool turnOnExcessiveLogging(); class WifiSupplicantHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { - public: + protected: virtual void HidlSetUp() override { stopSupplicant(); } virtual void HidlTearDown() override { startSupplicantAndWaitForHidlService(); } + + public: + // Whether P2P feature is supported on the device. + bool isP2pOn = true; + + void usage(char* me, char* arg) { + fprintf(stderr, + "unrecognized option: %s\n\n" + "usage: %s <gtest options> <test options>\n\n" + "test options are:\n\n" + "-P, --p2p_on: Whether P2P feature is supported\n", + arg, me); + } + + int initFromOptions(int argc, char** argv) { + static struct option options[] = {{"p2p_off", no_argument, 0, 'P'}, + {0, 0, 0, 0}}; + + int c; + while ((c = getopt_long(argc, argv, "P", options, NULL)) >= 0) { + switch (c) { + case 'P': + isP2pOn = false; + break; + default: + usage(argv[0], argv[optind]); + return 2; + } + } + + if (optind < argc) { + usage(argv[0], argv[optind]); + return 2; + } + + return 0; + } }; #endif /* SUPPLICANT_HIDL_TEST_UTILS_H */ diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp index 3e65453c2..353ae4b84 100644 --- a/wifi/supplicant/1.1/vts/functional/Android.bp +++ b/wifi/supplicant/1.1/vts/functional/Android.bp @@ -56,4 +56,5 @@ cc_test { "libwifi-system", "libwifi-system-iface", ], + test_suites: ["general-tests"], } diff --git a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp index 3d24fc3ee..9063a3ba4 100644 --- a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp +++ b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp @@ -30,8 +30,11 @@ class WifiSupplicantHidlEnvironment_1_1 : public WifiSupplicantHidlEnvironment { return instance; } virtual void registerTestServices() override { + registerTestService<::android::hardware::wifi::V1_0::IWifi>(); registerTestService<::android::hardware::wifi::V1_1::IWifi>(); registerTestService< + ::android::hardware::wifi::supplicant::V1_0::ISupplicant>(); + registerTestService< ::android::hardware::wifi::supplicant::V1_1::ISupplicant>(); } @@ -46,7 +49,10 @@ int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(gEnv); ::testing::InitGoogleTest(&argc, argv); gEnv->init(&argc, argv); - int status = RUN_ALL_TESTS(); - LOG(INFO) << "Test result = " << status; + int status = gEnv->initFromOptions(argc, argv); + if (status == 0) { + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + } return status; } diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp index 7e773d611..28f980cf8 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp @@ -33,6 +33,8 @@ using ::android::hardware::wifi::supplicant::V1_0::IfaceType; using ::android::hardware::wifi::supplicant::V1_1::ISupplicant; using ::android::sp; +extern WifiSupplicantHidlEnvironment* gEnv; + class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { @@ -81,6 +83,7 @@ TEST_F(SupplicantHidlTest, AddStaInterface) { * AddP2pInterface */ TEST_F(SupplicantHidlTest, AddP2pInterface) { + if (!gEnv->isP2pOn) return; ISupplicant::IfaceInfo iface_info; iface_info.name = getP2pIfaceName(); iface_info.type = IfaceType::P2P; @@ -120,6 +123,7 @@ TEST_F(SupplicantHidlTest, RemoveStaInterface) { * RemoveP2pInterface */ TEST_F(SupplicantHidlTest, RemoveP2pInterface) { + if (!gEnv->isP2pOn) return; ISupplicant::IfaceInfo iface_info; iface_info.name = getP2pIfaceName(); iface_info.type = IfaceType::P2P; diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp new file mode 100644 index 000000000..c685022b0 --- /dev/null +++ b/wifi/supplicant/1.2/Android.bp @@ -0,0 +1,24 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.wifi.supplicant@1.2", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "types.hal", + "ISupplicant.hal", + "ISupplicantP2pIface.hal", + "ISupplicantStaIface.hal", + "ISupplicantStaIfaceCallback.hal", + "ISupplicantStaNetwork.hal", + ], + interfaces: [ + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hidl.base@1.0", + ], + gen_java: true, +} + diff --git a/wifi/supplicant/1.2/ISupplicant.hal b/wifi/supplicant/1.2/ISupplicant.hal new file mode 100644 index 000000000..b0ec65db5 --- /dev/null +++ b/wifi/supplicant/1.2/ISupplicant.hal @@ -0,0 +1,30 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.supplicant@1.2; + +import @1.1::ISupplicant; + +/** + * Interface exposed by the supplicant HIDL service registered + * with the hardware service manager. + * This is the root level object for any the supplicant interactions. + * To use 1.2 features you must cast specific interfaces returned from the + * 1.1 HAL. For example V1_1::ISupplicant::addIface() adds V1_1::ISupplicantIface, + * which can be cast to V1_2::ISupplicantStaIface. + */ +interface ISupplicant extends @1.1::ISupplicant { +}; diff --git a/wifi/supplicant/1.2/ISupplicantP2pIface.hal b/wifi/supplicant/1.2/ISupplicantP2pIface.hal new file mode 100644 index 000000000..d58f46bfb --- /dev/null +++ b/wifi/supplicant/1.2/ISupplicantP2pIface.hal @@ -0,0 +1,83 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.supplicant@1.2; + +import @1.0::ISupplicantP2pIface; +import @1.0::MacAddress; +import @1.0::Ssid; +import @1.0::SupplicantStatus; + +/** + * Interface exposed by the supplicant for each P2P mode network + * interface (e.g p2p0) it controls. + * To use 1.2 features you must cast specific interfaces returned from the + * 1.2 HAL. For example V1_2::ISupplicant::addIface() adds V1_2::ISupplicantIface, + * which can be cast to V1_2::ISupplicantP2pIface. + */ +interface ISupplicantP2pIface extends @1.0::ISupplicantP2pIface { + /** + * Set up a P2P group owner or join a group as a group client + * with the specified configuration. + * + * If joinExistingGroup is false, this device sets up a P2P group owner manually (i.e., + * without group owner negotiation with a specific peer) with the specified SSID, + * passphrase, persistent mode, and frequency/band. + * + * If joinExistingGroup is true, this device acts as a group client and joins the group + * whose network name and group owner's MAC address matches the specified SSID + * and peer address without WPS process. If peerAddress is 00:00:00:00:00:00, the first found + * group whose network name matches the specified SSID is joined. + * + * @param ssid The SSID of this group. + * @param pskPassphrase The passphrase of this group. + * @param persistent Used to request a persistent group to be formed, + * only applied for the group owner. + * @param freq The required frequency or band for this group. + * only applied for the group owner. + * The following values are supported: + * 0: automatic channel selection, + * 2: for 2.4GHz channels + * 5: for 5GHz channels + * specific frequency, i.e., 2412, 5500, etc. + * If an invalid band or unsupported frequency are specified, it fails. + * @param peerAddress the group owner's MAC address, only applied for the group client. + * If the MAC is "00:00:00:00:00:00", the device must try to find a peer + * whose network name matches the specified SSID. + * @param joinExistingGroup if true, join a group as a group client; otherwise, + * create a group as a group owner. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + addGroup_1_2(Ssid ssid, string pskPassphrase, bool persistent, + uint32_t freq, MacAddress peerAddress, bool joinExistingGroup) + generates (SupplicantStatus status); + + /** + * Set MAC randomization enabled/disabled. + * + * @param enable true to enable, false to disable. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + setMacRandomization(bool enable) generates (SupplicantStatus status); +}; diff --git a/wifi/supplicant/1.2/ISupplicantStaIface.hal b/wifi/supplicant/1.2/ISupplicantStaIface.hal new file mode 100644 index 000000000..9152a647a --- /dev/null +++ b/wifi/supplicant/1.2/ISupplicantStaIface.hal @@ -0,0 +1,140 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.supplicant@1.2; + +import @1.0::SupplicantStatus; +import @1.1::ISupplicantStaIface; +import @1.2::ISupplicantStaIfaceCallback; +import @1.2::ISupplicantStaNetwork; + +/** + * Interface exposed by the supplicant for each station mode network + * interface (e.g wlan0) it controls. + */ +interface ISupplicantStaIface extends @1.1::ISupplicantStaIface { + /** + * Register for callbacks from this interface. + * + * These callbacks are invoked for events that are specific to this interface. + * Registration of multiple callback objects is supported. These objects must + * be automatically deleted when the corresponding client process is dead or + * if this interface is removed. + * + * @param callback An instance of the |ISupplicantStaIfaceCallback| HIDL + * interface object. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + registerCallback_1_2(ISupplicantStaIfaceCallback callback) + generates (SupplicantStatus status); + + /** + * Get Key management capabilities of the device + * + * @return status Status of the operation, and a bitmap of key management mask. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + getKeyMgmtCapabilities() + generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask); + + /** + * Add a DPP peer URI. URI is acquired externally, e.g. by scanning a QR code + * + * @param uri Peer's DPP URI. + * @return status Status of the operation, and an ID for the URI. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + addDppPeerUri(string uri) + generates (SupplicantStatus status, uint32_t id); + + /** + * Remove a DPP peer URI. + * + * @param id The ID of the URI, as returned by |addDppPeerUri|. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + removeDppUri(uint32_t id) + generates (SupplicantStatus status); + + /** + * Start DPP in Configurator-Initiator mode. + * + * @param peerBootstrapId Peer device's URI ID. + * @param ownBootstrapId Local device's URI ID (0 for none, optional). + * @param ssid Network SSID to send to peer (SAE/PSK mode). + * @param password Network password to send to peer (SAE/PSK mode). + * @param psk Network PSK to send to peer (PSK mode only). Either password or psk should be set. + * @param netRole Role to configure the peer, |DppNetRole.DPP_NET_ROLE_STA| or + * |DppNetRole.DPP_NET_ROLE_AP|. + * @param securityAkm Security AKM to use (See DppAkm). + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + startDppConfiguratorInitiator(uint32_t peerBootstrapId, + uint32_t ownBootstrapId, string ssid, string password, + string psk, DppNetRole netRole, DppAkm securityAkm) + generates (SupplicantStatus status); + + /** + * Start DPP in Enrollee-Initiator mode. + * + * @param peerBootstrapId Peer device's URI ID. + * @param ownBootstrapId Local device's URI ID (0 for none, optional). + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + startDppEnrolleeInitiator(uint32_t peerBootstrapId, + uint32_t ownBootstrapId) + generates (SupplicantStatus status); + + /** + * Stop DPP Initiator operation. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + stopDppInitiator() + generates (SupplicantStatus status); +}; diff --git a/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal new file mode 100644 index 000000000..3eac398f9 --- /dev/null +++ b/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal @@ -0,0 +1,51 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.supplicant@1.2; + +import @1.1::ISupplicantStaIfaceCallback; +import @1.0::Ssid; + +/** + * Callback Interface exposed by the supplicant service + * for each station mode interface (ISupplicantStaIface). + * + * Clients need to host an instance of this HIDL interface object and + * pass a reference of the object to the supplicant via the + * corresponding |ISupplicantStaIface.registerCallback_1_2| method. + */ +interface ISupplicantStaIfaceCallback extends @1.1::ISupplicantStaIfaceCallback { + /** + * Indicates DPP configuration received success event (Enrolee mode). + */ + oneway onDppSuccessConfigReceived(Ssid ssid, string password, uint8_t[32] psk, + DppAkm securityAkm); + + /** + * Indicates DPP configuration sent success event (Configurator mode). + */ + oneway onDppSuccessConfigSent(); + + /** + * Indicates a DPP progress event. + */ + oneway onDppProgress(DppProgressCode code); + + /** + * Indicates a DPP failure event. + */ + oneway onDppFailure(DppFailureCode code); +}; diff --git a/wifi/supplicant/1.2/ISupplicantStaNetwork.hal b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal new file mode 100644 index 000000000..7c3da6f4f --- /dev/null +++ b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal @@ -0,0 +1,268 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.supplicant@1.2; + +import @1.0::ISupplicantStaNetworkCallback; +import @1.0::ISupplicantStaNetwork; +import @1.0::SupplicantStatus; +import @1.1::ISupplicantStaNetwork; + +/** + * Interface exposed by the supplicant for each station mode network + * configuration it controls. + */ +interface ISupplicantStaNetwork extends @1.1::ISupplicantStaNetwork { + /** Possble mask of values for KeyMgmt param. */ + enum KeyMgmtMask : @1.0::ISupplicantStaNetwork.KeyMgmtMask { + /** WPA using EAP authentication with stronger SHA256-based algorithms */ + WPA_EAP_SHA256 = 1 << 7, + + /** WPA pre-shared key with stronger SHA256-based algorithms */ + WPA_PSK_SHA256 = 1 << 8, + + /** WPA3-Personal SAE Key management */ + SAE = 1 << 10, + + /** WPA3-Enterprise Suite-B Key management */ + SUITE_B_192 = 1 << 17, + + /** Enhacned Open (OWE) Key management */ + OWE = 1 << 22, + + /** Easy Connect (DPP) Key management */ + DPP = 1 << 23, + }; + + /** Possble mask of values for PairwiseCipher param. */ + enum PairwiseCipherMask : @1.0::ISupplicantStaNetwork.PairwiseCipherMask { + /** GCMP-256 Pairwise Cipher */ + GCMP_256 = 1 << 8, + }; + + /** Possble mask of values for GroupCipher param. */ + enum GroupCipherMask : @1.0::ISupplicantStaNetwork.GroupCipherMask { + /** GCMP-256 Group Cipher */ + GCMP_256 = 1 << 8, + }; + + /** Possble mask of values for GroupMgmtCipher param. */ + enum GroupMgmtCipherMask : uint32_t { + /** BIP_GMAC-128 Group Management Cipher */ + BIP_GMAC_128 = 1 << 11, + + /** BIP_GMAC-256 Group Management Cipher */ + BIP_GMAC_256 = 1 << 12, + + /** BIP_CMAC-256 Group Management Cipher */ + BIP_CMAC_256 = 1 << 13, + }; + + /** + * Set key management mask for the network. + * + * @param keyMgmtMask value to set. + * Combination of |KeyMgmtMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setKeyMgmt_1_2(bitfield<KeyMgmtMask> keyMgmtMask) generates (SupplicantStatus status); + + /** + * Get the key mgmt mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + * @return keyMgmtMask Combination of |KeyMgmtMask| values. + */ + getKeyMgmt_1_2() + generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask); + + /** + * Set pairwise cipher mask for the network. + * + * @param pairwiseCipherMask value to set. + * Combination of |PairwiseCipherMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setPairwiseCipher_1_2(bitfield<PairwiseCipherMask> pairwiseCipherMask) + generates (SupplicantStatus status); + + /** + * Get the pairwise cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values. + */ + getPairwiseCipher_1_2() + generates (SupplicantStatus status, + bitfield<PairwiseCipherMask> pairwiseCipherMask); + + /** + * Set group cipher mask for the network. + * + * @param groupCipherMask value to set. + * Combination of |GroupCipherMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setGroupCipher_1_2(bitfield<GroupCipherMask> groupCipherMask) + generates (SupplicantStatus status); + + /** + * Get the group cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + * @return groupCipherMask Combination of |GroupCipherMask| values. + */ + getGroupCipher_1_2() + generates (SupplicantStatus status, + bitfield<GroupCipherMask> groupCipherMask); + + /** + * Set group management cipher mask for the network. + * + * @param groupMgmtCipherMask value to set. + * Combination of |GroupMgmtCipherMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setGroupMgmtCipher(bitfield<GroupMgmtCipherMask> groupMgmtCipherMask) + generates (SupplicantStatus status); + + /** + * Get the group management cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + * @return groupMgmtCipherMask Combination of |GroupMgmtCipherMask| values. + */ + getGroupMgmtCipher() + generates (SupplicantStatus status, + bitfield<GroupMgmtCipherMask> groupMgmtCipherMask); + + /** + * Enable TLS Suite-B in EAP Phase1 + * + * @param enable Set to true to enable TLS Suite-B in EAP phase1 + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + enableTlsSuiteBEapPhase1Param(bool enable) + generates (SupplicantStatus status); + + /** + * Set EAP OpenSSL Suite-B-192 ciphers for WPA3-Enterprise + * Supported option: + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + enableSuiteBEapOpenSslCiphers() + generates (SupplicantStatus status); + + /** + * Get SAE password for WPA3-Personal + * + * @return status Status of the operation, and a string. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + getSaePassword() + generates (SupplicantStatus status, string saePassword); + + /** + * Get SAE password ID for WPA3-Personal + * + * @return status Status of the operation, and a string. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + getSaePasswordId() + generates (SupplicantStatus status, string saePasswordId); + + /** + * Set SAE password for WPA3-Personal + * + * @param saePassword string with the above option + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setSaePassword(string saePassword) + generates (SupplicantStatus status); + + /** + * Set SAE password ID for WPA3-Personal + * + * @param sae_password_id string with the above option + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setSaePasswordId(string saePasswordId) + generates (SupplicantStatus status); +}; diff --git a/wifi/supplicant/1.2/types.hal b/wifi/supplicant/1.2/types.hal new file mode 100644 index 000000000..303af195e --- /dev/null +++ b/wifi/supplicant/1.2/types.hal @@ -0,0 +1,57 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi.supplicant@1.2; + +/** + * DppAkm: The various AKMs that can be provisioned using DPP. + */ +enum DppAkm : uint32_t { + PSK, + PSK_SAE, + SAE, + DPP, +}; + +/** + * DppNetRole: The network role that the configurator offers the enrollee. + */ +enum DppNetRole: uint32_t { + STA, + AP, +}; + +/** + * DppProgressCode: Progress codes for DPP (Easy Connect) + */ +enum DppProgressCode : uint32_t { + AUTHENTICATION_SUCCESS, + RESPONSE_PENDING, +}; + +/** + * DppFailureCode: Error codes for DPP (Easy Connect) + */ +enum DppFailureCode : uint32_t { + INVALID_URI, + AUTHENTICATION, + NOT_COMPATIBLE, + CONFIGURATION, + BUSY, + TIMEOUT, + FAILURE, + NOT_SUPPORTED, +}; diff --git a/wifi/supplicant/1.2/vts/OWNERS b/wifi/supplicant/1.2/vts/OWNERS new file mode 100644 index 000000000..8bfb14882 --- /dev/null +++ b/wifi/supplicant/1.2/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp new file mode 100644 index 000000000..1b970e1ce --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/Android.bp @@ -0,0 +1,88 @@ +// +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_static { + name: "VtsHalWifiSupplicantV1_2TargetTestUtil", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["supplicant_hidl_test_utils_1_2.cpp"], + export_include_dirs: [ + "." + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_1TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi@1.0", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], +} + +cc_test { + name: "VtsHalWifiSupplicantV1_2TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalWifiSupplicantV1_2TargetTest.cpp", + "supplicant_sta_iface_hidl_test.cpp", + "supplicant_sta_network_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_1TargetTestUtil", + "VtsHalWifiSupplicantV1_2TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], + test_suites: ["general-tests"], +} + +cc_test { + name: "VtsHalWifiSupplicantP2pV1_2TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalWifiSupplicantV1_2TargetTest.cpp", + "supplicant_p2p_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_1TargetTestUtil", + "VtsHalWifiSupplicantV1_2TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], +} + diff --git a/wifi/supplicant/1.2/vts/functional/VtsHalWifiSupplicantV1_2TargetTest.cpp b/wifi/supplicant/1.2/vts/functional/VtsHalWifiSupplicantV1_2TargetTest.cpp new file mode 100644 index 000000000..267fa6736 --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/VtsHalWifiSupplicantV1_2TargetTest.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android/hardware/wifi/1.1/IWifi.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicant.h> + +#include "supplicant_hidl_test_utils.h" +#include "wifi_hidl_test_utils.h" + +class WifiSupplicantHidlEnvironment_1_2 : public WifiSupplicantHidlEnvironment { + public: + // get the test environment singleton + static WifiSupplicantHidlEnvironment_1_2* Instance() { + static WifiSupplicantHidlEnvironment_1_2* instance = + new WifiSupplicantHidlEnvironment_1_2; + return instance; + } + virtual void registerTestServices() override { + registerTestService<::android::hardware::wifi::V1_0::IWifi>(); + registerTestService<::android::hardware::wifi::V1_1::IWifi>(); + registerTestService< + ::android::hardware::wifi::supplicant::V1_0::ISupplicant>(); + registerTestService< + ::android::hardware::wifi::supplicant::V1_1::ISupplicant>(); + registerTestService< + ::android::hardware::wifi::supplicant::V1_2::ISupplicant>(); + } + + private: + WifiSupplicantHidlEnvironment_1_2() {} +}; + +WifiSupplicantHidlEnvironment* gEnv = + WifiSupplicantHidlEnvironment_1_2::Instance(); + +int main(int argc, char** argv) { + ::testing::AddGlobalTestEnvironment(gEnv); + ::testing::InitGoogleTest(&argc, argv); + gEnv->init(&argc, argv); + int status = gEnv->initFromOptions(argc, argv); + if (status == 0) { + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + } + return status; +} diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp new file mode 100644 index 000000000..f270bff67 --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <VtsHalHidlTargetTestBase.h> +#include <android-base/logging.h> + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_2.h" + +using ::android::sp; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicant; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantP2pIface; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork; + +sp<ISupplicant> getSupplicant_1_2() { + return ISupplicant::castFrom(getSupplicant()); +} + +sp<ISupplicantStaIface> getSupplicantStaIface_1_2() { + return ISupplicantStaIface::castFrom(getSupplicantStaIface()); +} + +sp<ISupplicantStaNetwork> createSupplicantStaNetwork_1_2() { + return ISupplicantStaNetwork::castFrom(createSupplicantStaNetwork()); +} + +sp<ISupplicantP2pIface> getSupplicantP2pIface_1_2() { + return ISupplicantP2pIface::castFrom(getSupplicantP2pIface()); +} diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h new file mode 100644 index 000000000..8a7ccc5da --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SUPPLICANT_HIDL_TEST_UTILS_1_2_H +#define SUPPLICANT_HIDL_TEST_UTILS_1_2_H + +#include <android/hardware/wifi/supplicant/1.2/ISupplicant.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicantP2pIface.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaIface.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaNetwork.h> + +android::sp<android::hardware::wifi::supplicant::V1_2::ISupplicant> +getSupplicant_1_2(); + +android::sp<android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface> +getSupplicantStaIface_1_2(); + +android::sp<android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork> +createSupplicantStaNetwork_1_2(); + +android::sp<android::hardware::wifi::supplicant::V1_2::ISupplicantP2pIface> +getSupplicantP2pIface_1_2(); + +#endif /* SUPPLICANT_HIDL_TEST_UTILS_1_2_H */ diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp new file mode 100644 index 000000000..36bde161c --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> + +#include <VtsHalHidlTargetTestBase.h> + +#include <android/hardware/wifi/supplicant/1.2/ISupplicantP2pIface.h> + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_2.h" + +using ::android::sp; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantP2pIface; + +namespace { +constexpr uint8_t kTestSsid[] = {'D', 'I', 'R', 'E', 'C', 'T', '-', 'x', + 'y', '-', 'H', 'E', 'L', 'L', 'O'}; +constexpr char kTestPassphrase[] = "P2pWorld1234"; +constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0}; +} // namespace + +class SupplicantP2pIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + startSupplicantAndWaitForHidlService(); + EXPECT_TRUE(turnOnExcessiveLogging()); + p2p_iface_ = getSupplicantP2pIface_1_2(); + ASSERT_NE(p2p_iface_.get(), nullptr); + } + + virtual void TearDown() override { stopSupplicant(); } + + protected: + // ISupplicantP2pIface object used for all tests in this fixture. + sp<ISupplicantP2pIface> p2p_iface_; +}; + +/* + * Verify that AddGroup_1_2 could create a group successfully. + */ +TEST_F(SupplicantP2pIfaceHidlTest, AddGroup_1_2_Success) { + std::vector<uint8_t> ssid(kTestSsid, kTestSsid + sizeof(kTestSsid)); + std::string passphrase = kTestPassphrase; + int freq = 0; + std::array<uint8_t, 6> zero_mac_addr; + memcpy(zero_mac_addr.data(), kTestZeroMacAddr, zero_mac_addr.size()); + bool persistent = false; + int is_join = false; + + p2p_iface_->addGroup_1_2(ssid, passphrase, persistent, freq, zero_mac_addr, + is_join, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, + status.code); + }); +} + +/* + * Verify that AddGroup_1_2 fails due to invalid SSID. + */ +TEST_F(SupplicantP2pIfaceHidlTest, AddGroup_1_2_FailureInvalidSsid) { + std::vector<uint8_t> ssid; + std::string passphrase = kTestPassphrase; + int freq = 0; + std::array<uint8_t, 6> zero_mac_addr; + memcpy(zero_mac_addr.data(), kTestZeroMacAddr, zero_mac_addr.size()); + bool persistent = false; + int is_join = false; + + p2p_iface_->addGroup_1_2( + ssid, passphrase, persistent, freq, zero_mac_addr, is_join, + [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::FAILURE_ARGS_INVALID, status.code); + }); +} + +/* + * Verify that AddGroup_1_2 fails due to invalid passphrase. + */ +TEST_F(SupplicantP2pIfaceHidlTest, AddGroup_1_2_FailureInvalidPassphrase) { + std::vector<uint8_t> ssid(kTestSsid, kTestSsid + sizeof(kTestSsid)); + std::string passphrase = "1234"; + int freq = 0; + std::array<uint8_t, 6> zero_mac_addr; + memcpy(zero_mac_addr.data(), kTestZeroMacAddr, zero_mac_addr.size()); + bool persistent = false; + int is_join = false; + + p2p_iface_->addGroup_1_2( + ssid, passphrase, persistent, freq, zero_mac_addr, is_join, + [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::FAILURE_ARGS_INVALID, status.code); + }); +} + +/* + * Verify that AddGroup_1_2 fails due to invalid frequency. + */ +TEST_F(SupplicantP2pIfaceHidlTest, AddGroup_1_2_FailureInvalidFrequency) { + std::vector<uint8_t> ssid(kTestSsid, kTestSsid + sizeof(kTestSsid)); + std::string passphrase = kTestPassphrase; + int freq = 9999; + std::array<uint8_t, 6> zero_mac_addr; + memcpy(zero_mac_addr.data(), kTestZeroMacAddr, zero_mac_addr.size()); + bool persistent = false; + int is_join = false; + + p2p_iface_->addGroup_1_2( + ssid, passphrase, persistent, freq, zero_mac_addr, is_join, + [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + }); +} + +/* + * Verify that setMacRandomization successes. + */ +TEST_F(SupplicantP2pIfaceHidlTest, EnableMacRandomization) { + p2p_iface_->setMacRandomization(true, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + // enable twice + p2p_iface_->setMacRandomization(true, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + p2p_iface_->setMacRandomization(false, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + // disable twice + p2p_iface_->setMacRandomization(false, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp new file mode 100644 index 000000000..2ff7751fa --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <VtsHalHidlTargetTestBase.h> +#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.h> +#include <android/hardware/wifi/supplicant/1.0/types.h> +#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaIfaceCallback.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaIface.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.h> +#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaNetwork.h> +#include <android/hardware/wifi/supplicant/1.2/types.h> +#include <hidl/HidlSupport.h> +#include <hidl/Status.h> + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_2.h" + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; +using ::android::hardware::wifi::supplicant::V1_2::DppAkm; +using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode; +using ::android::hardware::wifi::supplicant::V1_2::DppNetRole; +using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIfaceCallback; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork; + +#define TIMEOUT_PERIOD 60 +class IfaceDppCallback; + +class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + startSupplicantAndWaitForHidlService(); + EXPECT_TRUE(turnOnExcessiveLogging()); + sta_iface_ = getSupplicantStaIface_1_2(); + ASSERT_NE(sta_iface_.get(), nullptr); + count_ = 0; + } + + virtual void TearDown() override { stopSupplicant(); } + + enum DppCallbackType { + ANY_CALLBACK = -2, + INVALID = -1, + + EVENT_SUCCESS_CONFIG_SENT = 0, + EVENT_SUCCESS_CONFIG_RECEIVED, + EVENT_PROGRESS, + EVENT_FAILURE, + }; + + DppCallbackType dppCallbackType; + uint32_t code; + + /* Used as a mechanism to inform the test about data/event callback */ + inline void notify() { + std::unique_lock<std::mutex> lock(mtx_); + count_++; + cv_.notify_one(); + } + + /* Test code calls this function to wait for data/event callback */ + inline std::cv_status wait(DppCallbackType waitForCallbackType) { + std::unique_lock<std::mutex> lock(mtx_); + EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a + // non-void-returning method + auto now = std::chrono::system_clock::now(); + std::cv_status status = + cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); + return status; + } + + private: + // synchronization objects + std::mutex mtx_; + std::condition_variable cv_; + int count_; + + protected: + // ISupplicantStaIface object used for all tests in this fixture. + sp<ISupplicantStaIface> sta_iface_; + bool isDppSupported() { + uint32_t keyMgmtMask = 0; + + // We need to first get the key management capabilities from the device. + // If DPP is not supported, we just pass the test. + sta_iface_->getKeyMgmtCapabilities( + [&](const SupplicantStatus& status, uint32_t keyMgmtMaskInternal) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + + keyMgmtMask = keyMgmtMaskInternal; + }); + + if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::DPP)) { + // DPP not supported + return false; + } + + return true; + } +}; + +class IfaceCallback : public ISupplicantStaIfaceCallback { + Return<void> onNetworkAdded(uint32_t /* id */) override { return Void(); } + Return<void> onNetworkRemoved(uint32_t /* id */) override { return Void(); } + Return<void> onStateChanged( + ISupplicantStaIfaceCallback::State /* newState */, + const hidl_array<uint8_t, 6>& /*bssid */, uint32_t /* id */, + const hidl_vec<uint8_t>& /* ssid */) override { + return Void(); + } + Return<void> onAnqpQueryDone( + const hidl_array<uint8_t, 6>& /* bssid */, + const ISupplicantStaIfaceCallback::AnqpData& /* data */, + const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */) + override { + return Void(); + } + virtual Return<void> onHs20IconQueryDone( + const hidl_array<uint8_t, 6>& /* bssid */, + const hidl_string& /* fileName */, + const hidl_vec<uint8_t>& /* data */) override { + return Void(); + } + virtual Return<void> onHs20SubscriptionRemediation( + const hidl_array<uint8_t, 6>& /* bssid */, + ISupplicantStaIfaceCallback::OsuMethod /* osuMethod */, + const hidl_string& /* url*/) override { + return Void(); + } + Return<void> onHs20DeauthImminentNotice( + const hidl_array<uint8_t, 6>& /* bssid */, uint32_t /* reasonCode */, + uint32_t /* reAuthDelayInSec */, + const hidl_string& /* url */) override { + return Void(); + } + Return<void> onDisconnected(const hidl_array<uint8_t, 6>& /* bssid */, + bool /* locallyGenerated */, + ISupplicantStaIfaceCallback::ReasonCode + /* reasonCode */) override { + return Void(); + } + Return<void> onAssociationRejected( + const hidl_array<uint8_t, 6>& /* bssid */, + ISupplicantStaIfaceCallback::StatusCode /* statusCode */, + bool /*timedOut */) override { + return Void(); + } + Return<void> onAuthenticationTimeout( + const hidl_array<uint8_t, 6>& /* bssid */) override { + return Void(); + } + Return<void> onBssidChanged( + ISupplicantStaIfaceCallback::BssidChangeReason /* reason */, + const hidl_array<uint8_t, 6>& /* bssid */) override { + return Void(); + } + Return<void> onEapFailure() override { return Void(); } + Return<void> onEapFailure_1_1( + ISupplicantStaIfaceCallback::EapErrorCode /* eapErrorCode */) override { + return Void(); + } + Return<void> onWpsEventSuccess() override { return Void(); } + Return<void> onWpsEventFail( + const hidl_array<uint8_t, 6>& /* bssid */, + ISupplicantStaIfaceCallback::WpsConfigError /* configError */, + ISupplicantStaIfaceCallback::WpsErrorIndication /* errorInd */) + override { + return Void(); + } + Return<void> onWpsEventPbcOverlap() override { return Void(); } + Return<void> onExtRadioWorkStart(uint32_t /* id */) override { + return Void(); + } + Return<void> onExtRadioWorkTimeout(uint32_t /* id*/) override { + return Void(); + } + Return<void> onDppSuccessConfigReceived( + const hidl_vec<uint8_t>& /* ssid */, const hidl_string& /* password */, + const hidl_array<uint8_t, 32>& /* psk */, + DppAkm /* securityAkm */) override { + return Void(); + } + Return<void> onDppSuccessConfigSent() override { return Void(); } + Return<void> onDppProgress(DppProgressCode /* code */) override { + return Void(); + } + Return<void> onDppFailure(DppFailureCode /* code */) override { + return Void(); + } +}; + +class IfaceDppCallback : public IfaceCallback { + SupplicantStaIfaceHidlTest& parent_; + + Return<void> onDppSuccessConfigReceived( + const hidl_vec<uint8_t>& /* ssid */, const hidl_string& /* password */, + const hidl_array<uint8_t, 32>& /* psk */, + DppAkm /* securityAkm */) override { + parent_.code = 0; + parent_.dppCallbackType = SupplicantStaIfaceHidlTest::DppCallbackType:: + EVENT_SUCCESS_CONFIG_RECEIVED; + parent_.notify(); + return Void(); + } + Return<void> onDppSuccessConfigSent() override { + parent_.code = 0; + parent_.dppCallbackType = SupplicantStaIfaceHidlTest::DppCallbackType:: + EVENT_SUCCESS_CONFIG_SENT; + parent_.notify(); + return Void(); + } + Return<void> onDppProgress(DppProgressCode code) override { + parent_.code = (uint32_t)code; + parent_.dppCallbackType = + SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_PROGRESS; + parent_.notify(); + return Void(); + } + Return<void> onDppFailure(DppFailureCode code) override { + parent_.code = (uint32_t)code; + parent_.dppCallbackType = + SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE; + parent_.notify(); + return Void(); + } + + public: + IfaceDppCallback(SupplicantStaIfaceHidlTest& parent) : parent_(parent){}; +}; + +/* + * RegisterCallback_1_2 + */ +TEST_F(SupplicantStaIfaceHidlTest, RegisterCallback_1_2) { + sta_iface_->registerCallback_1_2( + new IfaceCallback(), [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + +/* + * GetKeyMgmtCapabilities + */ +TEST_F(SupplicantStaIfaceHidlTest, GetKeyMgmtCapabilities) { + sta_iface_->getKeyMgmtCapabilities( + [&](const SupplicantStatus& status, uint32_t keyMgmtMask) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + + // Even though capabilities vary, these two are always set in HAL + // v1.2 + EXPECT_TRUE(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::NONE); + EXPECT_TRUE(keyMgmtMask & + ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X); + }); +} + +/* + * AddDppPeerUriAndRomveUri + */ +TEST_F(SupplicantStaIfaceHidlTest, AddDppPeerUriAndRomveUri) { + // We need to first get the key management capabilities from the device. + // If DPP is not supported, we just pass the test. + if (!isDppSupported()) { + // DPP not supported + return; + } + + hidl_string uri = + "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj" + "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;"; + uint32_t peer_id = 0; + + // Add a peer URI + sta_iface_->addDppPeerUri( + uri, [&](const SupplicantStatus& status, uint32_t id) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_NE(0, id); + EXPECT_NE(-1, id); + + peer_id = id; + }); + + // ...and then remove it. + sta_iface_->removeDppUri(peer_id, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + +/* + * StartDppEnrolleeInitiator + */ +TEST_F(SupplicantStaIfaceHidlTest, StartDppEnrolleeInitiator) { + // We need to first get the key management capabilities from the device. + // If DPP is not supported, we just pass the test. + if (!isDppSupported()) { + // DPP not supported + return; + } + + hidl_string uri = + "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj" + "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;"; + uint32_t peer_id = 0; + + // Register callbacks + sta_iface_->registerCallback_1_2( + new IfaceDppCallback(*this), [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + // Add a peer URI + sta_iface_->addDppPeerUri( + uri, [&](const SupplicantStatus& status, uint32_t id) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_NE(0, id); + EXPECT_NE(-1, id); + + peer_id = id; + }); + + // Start DPP as Enrollee-Initiator. Since this operation requires two + // devices, we start the operation and expect a timeout. + sta_iface_->startDppEnrolleeInitiator( + peer_id, 0, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + // Wait for the timeout callback + ASSERT_EQ(std::cv_status::no_timeout, + wait(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE)); + ASSERT_EQ(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE, + dppCallbackType); + + // ...and then remove the peer URI. + sta_iface_->removeDppUri(peer_id, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + +/* + * StartDppConfiguratorInitiator + */ +TEST_F(SupplicantStaIfaceHidlTest, StartDppConfiguratorInitiator) { + // We need to first get the key management capabilities from the device. + // If DPP is not supported, we just pass the test. + if (!isDppSupported()) { + // DPP not supported + return; + } + + hidl_string uri = + "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj" + "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;"; + uint32_t peer_id = 0; + + // Register callbacks + sta_iface_->registerCallback_1_2( + new IfaceDppCallback(*this), [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + // Add a peer URI + sta_iface_->addDppPeerUri( + uri, [&](const SupplicantStatus& status, uint32_t id) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_NE(0, id); + EXPECT_NE(-1, id); + + peer_id = id; + }); + + std::string ssid = + "6D795F746573745F73736964"; // 'my_test_ssid' encoded in hex + std::string password = "746F70736563726574"; // 'topsecret' encoded in hex + + // Start DPP as Configurator-Initiator. Since this operation requires two + // devices, we start the operation and expect a timeout. + sta_iface_->startDppConfiguratorInitiator( + peer_id, 0, ssid, password, NULL, DppNetRole::STA, DppAkm::PSK, + [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + // Wait for the timeout callback + ASSERT_EQ(std::cv_status::no_timeout, + wait(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE)); + ASSERT_EQ(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE, + dppCallbackType); + + // ...and then remove the peer URI. + sta_iface_->removeDppUri(peer_id, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp new file mode 100644 index 000000000..ed421d73d --- /dev/null +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> + +#include <VtsHalHidlTargetTestBase.h> +#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaNetwork.h> + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_2.h" + +using ::android::sp; +using ::android::hardware::hidl_vec; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; +using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork; +// namespace { +// constexpr uint8_t kTestIdentity[] = {0x45, 0x67, 0x98, 0x67, 0x56}; +// constexpr uint8_t kTestEncryptedIdentity[] = {0x35, 0x37, 0x58, 0x57, 0x26}; +//} // namespace + +class SupplicantStaNetworkHidlTest + : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + startSupplicantAndWaitForHidlService(); + EXPECT_TRUE(turnOnExcessiveLogging()); + sta_network_ = createSupplicantStaNetwork_1_2(); + ASSERT_NE(sta_network_.get(), nullptr); + } + + virtual void TearDown() override { stopSupplicant(); } + + protected: + // ISupplicantStaNetwork object used for all tests in this fixture. + sp<ISupplicantStaNetwork> sta_network_; +}; + +/* + * SetGetSaePassword + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetSaePassword) { + std::string password = "topsecret"; + + sta_network_->setSaePassword(password, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->getSaePassword( + [&password](const SupplicantStatus &status, std::string passwordOut) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(passwordOut.compare(password), 0); + }); +} + +/* + * SetGetSaePasswordId + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetSaePasswordId) { + std::string passwordId = "id1"; + + sta_network_->setSaePasswordId( + passwordId, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->getSaePasswordId([&passwordId](const SupplicantStatus &status, + std::string passwordIdOut) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(passwordIdOut.compare(passwordId), 0); + }); +} + +/* + * SetGetGroupMgmtCipher + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupMgmtCipher) { + uint32_t groupMgmtCipher = + (uint32_t)ISupplicantStaNetwork::GroupMgmtCipherMask::BIP_GMAC_256; + + sta_network_->setGroupMgmtCipher( + groupMgmtCipher, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->getGroupMgmtCipher( + [&groupMgmtCipher](const SupplicantStatus &status, + uint32_t groupMgmtCipherOut) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(groupMgmtCipherOut, groupMgmtCipher); + }); +} + +/* + * SetGetKeyMgmt_1_2 + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetKeyMgmt_1_2) { + uint32_t keyMgmt = (uint32_t)ISupplicantStaNetwork::KeyMgmtMask::SAE; + + sta_network_->setKeyMgmt_1_2(keyMgmt, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->getKeyMgmt_1_2( + [&keyMgmt](const SupplicantStatus &status, uint32_t keyMgmtOut) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(keyMgmtOut, keyMgmt); + }); +} + +/* + * SetGetGroupCipher_1_2 + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupCipher_1_2) { + uint32_t groupCipher = + (uint32_t)ISupplicantStaNetwork::GroupCipherMask::GCMP_256; + + sta_network_->setGroupCipher_1_2( + groupCipher, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->getGroupCipher_1_2( + [&groupCipher](const SupplicantStatus &status, + uint32_t groupCipherOut) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(groupCipherOut, groupCipher); + }); +} + +/* + * SetGetPairwiseCipher_1_2 + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher_1_2) { + uint32_t pairwiseCipher = + (uint32_t)ISupplicantStaNetwork::PairwiseCipherMask::GCMP_256; + + sta_network_->setPairwiseCipher_1_2( + pairwiseCipher, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->getPairwiseCipher_1_2( + [&pairwiseCipher](const SupplicantStatus &status, + uint32_t pairwiseCipherOut) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(pairwiseCipherOut, pairwiseCipher); + }); +} + +/* + * EnableSuiteBEapOpenSslCiphers + */ +TEST_F(SupplicantStaNetworkHidlTest, EnableSuiteBEapOpenSslCiphers) { + sta_network_->enableSuiteBEapOpenSslCiphers( + [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->enableSuiteBEapOpenSslCiphers( + [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + +/* + * EnableTlsSuiteBEapPhase1Param + */ +TEST_F(SupplicantStaNetworkHidlTest, EnableTlsSuiteBEapPhase1Param) { + sta_network_->enableTlsSuiteBEapPhase1Param( + true, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + + sta_network_->enableTlsSuiteBEapPhase1Param( + false, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} |
