1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android-base/logging.h>
18 
19 #include <VtsCoreUtil.h>
20 #include <android/hardware/wifi/1.0/IWifi.h>
21 #include <android/hardware/wifi/1.0/IWifiChip.h>
22 #include <gtest/gtest.h>
23 #include <hidl/GtestPrinter.h>
24 #include <hidl/ServiceManagement.h>
25 
26 #include "wifi_hidl_call_util.h"
27 #include "wifi_hidl_test_utils.h"
28 
29 using ::android::sp;
30 using ::android::hardware::wifi::V1_0::ChipModeId;
31 using ::android::hardware::wifi::V1_0::IfaceType;
32 using ::android::hardware::wifi::V1_0::IWifi;
33 using ::android::hardware::wifi::V1_0::IWifiChip;
34 using ::android::hardware::wifi::V1_0::IWifiIface;
35 using ::android::hardware::wifi::V1_0::IWifiNanIface;
36 using ::android::hardware::wifi::V1_0::WifiStatus;
37 using ::android::hardware::wifi::V1_0::WifiStatusCode;
38 
39 /**
40  * Fixture for IWifiChip tests that are conditioned on NAN support.
41  */
42 class WifiChipHidlNanTest : public ::testing::TestWithParam<std::string> {
43    public:
SetUp()44     virtual void SetUp() override {
45         if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
46             GTEST_SKIP() << "Skipping this test since NAN is not supported.";
47 
48         // Make sure test starts with a clean state
49         stopWifi(GetInstanceName());
50 
51         wifi_chip_ = getWifiChip(GetInstanceName());
52         ASSERT_NE(nullptr, wifi_chip_.get());
53     }
54 
TearDown()55     virtual void TearDown() override { stopWifi(GetInstanceName()); }
56 
57    protected:
58     // Helper function to configure the Chip in one of the supported modes.
59     // Most of the non-mode-configuration-related methods require chip
60     // to be first configured.
configureChipForIfaceType(IfaceType type,bool expectSuccess)61     ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) {
62         ChipModeId mode_id;
63         EXPECT_EQ(expectSuccess,
64                   configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
65         return mode_id;
66     }
67 
getIfaceName(const sp<IWifiIface> & iface)68     std::string getIfaceName(const sp<IWifiIface>& iface) {
69         const auto& status_and_name = HIDL_INVOKE(iface, getName);
70         EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
71         return status_and_name.second;
72     }
73 
createNanIface(sp<IWifiNanIface> * nan_iface)74     WifiStatusCode createNanIface(sp<IWifiNanIface>* nan_iface) {
75         const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createNanIface);
76         *nan_iface = status_and_iface.second;
77         return status_and_iface.first.code;
78     }
79 
removeNanIface(const std::string & name)80     WifiStatusCode removeNanIface(const std::string& name) {
81         return HIDL_INVOKE(wifi_chip_, removeNanIface, name).code;
82     }
83 
84     sp<IWifiChip> wifi_chip_;
85 
86    private:
GetInstanceName()87     std::string GetInstanceName() { return GetParam(); }
88 };
89 
90 /*
91  * CreateNanIface
92  * Configures the chip in NAN mode and ensures that at least 1 iface creation
93  * succeeds.
94  */
TEST_P(WifiChipHidlNanTest,CreateNanIface)95 TEST_P(WifiChipHidlNanTest, CreateNanIface) {
96     configureChipForIfaceType(IfaceType::NAN, true);
97 
98     sp<IWifiNanIface> iface;
99     ASSERT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
100     EXPECT_NE(nullptr, iface.get());
101 }
102 
103 /*
104  * GetNanIfaceNames
105  * Configures the chip in NAN mode and ensures that the iface list is empty
106  * before creating the iface. Then, create the iface and ensure that
107  * iface name is returned via the list.
108  */
TEST_P(WifiChipHidlNanTest,GetNanIfaceNames)109 TEST_P(WifiChipHidlNanTest, GetNanIfaceNames) {
110     configureChipForIfaceType(IfaceType::NAN, true);
111 
112     const auto& status_and_iface_names1 =
113         HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
114     ASSERT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code);
115     EXPECT_EQ(0u, status_and_iface_names1.second.size());
116 
117     sp<IWifiNanIface> iface;
118     EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
119     EXPECT_NE(nullptr, iface.get());
120 
121     std::string iface_name = getIfaceName(iface);
122     const auto& status_and_iface_names2 =
123         HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
124     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code);
125     EXPECT_EQ(1u, status_and_iface_names2.second.size());
126     EXPECT_EQ(iface_name, status_and_iface_names2.second[0]);
127 
128     EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
129     const auto& status_and_iface_names3 =
130         HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
131     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code);
132     EXPECT_EQ(0u, status_and_iface_names3.second.size());
133 }
134 
135 /*
136  * GetNanIface
137  * Configures the chip in NAN mode and create an iface. Then, retrieve
138  * the iface object using the correct name and ensure any other name
139  * doesn't retrieve an iface object.
140  */
TEST_P(WifiChipHidlNanTest,GetNanIface)141 TEST_P(WifiChipHidlNanTest, GetNanIface) {
142     configureChipForIfaceType(IfaceType::NAN, true);
143 
144     sp<IWifiNanIface> nan_iface;
145     EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
146     EXPECT_NE(nullptr, nan_iface.get());
147 
148     std::string iface_name = getIfaceName(nan_iface);
149     const auto& status_and_iface1 =
150         HIDL_INVOKE(wifi_chip_, getNanIface, iface_name);
151     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code);
152     EXPECT_NE(nullptr, status_and_iface1.second.get());
153 
154     std::string invalid_name = iface_name + "0";
155     const auto& status_and_iface2 =
156         HIDL_INVOKE(wifi_chip_, getNanIface, invalid_name);
157     EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code);
158     EXPECT_EQ(nullptr, status_and_iface2.second.get());
159 }
160 
161 /*
162  * RemoveNanIface
163  * Configures the chip in NAN mode and create an iface. Then, remove
164  * the iface object using the correct name and ensure any other name
165  * doesn't remove the iface.
166  */
TEST_P(WifiChipHidlNanTest,RemoveNanIface)167 TEST_P(WifiChipHidlNanTest, RemoveNanIface) {
168     configureChipForIfaceType(IfaceType::NAN, true);
169 
170     sp<IWifiNanIface> nan_iface;
171     EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
172     EXPECT_NE(nullptr, nan_iface.get());
173 
174     std::string iface_name = getIfaceName(nan_iface);
175     std::string invalid_name = iface_name + "0";
176     EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(invalid_name));
177 
178     EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
179 
180     // No such iface exists now. So, this should return failure.
181     EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name));
182 }
183 
184 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlNanTest);
185 INSTANTIATE_TEST_SUITE_P(
186     PerInstance, WifiChipHidlNanTest,
187     testing::ValuesIn(
188         android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
189     android::hardware::PrintInstanceNameToString);
190