• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 <VtsHalHidlTargetTestBase.h>
18 #include <android-base/logging.h>
19 #include <cutils/properties.h>
20 
21 #include <android/hidl/manager/1.0/IServiceManager.h>
22 #include <android/hidl/manager/1.0/IServiceNotification.h>
23 #include <hidl/HidlTransportSupport.h>
24 
25 #include <wifi_system/interface_tool.h>
26 #include <wifi_system/supplicant_manager.h>
27 
28 #include "supplicant_hidl_test_utils.h"
29 #include "wifi_hidl_test_utils.h"
30 
31 using ::android::sp;
32 using ::android::hardware::configureRpcThreadpool;
33 using ::android::hardware::joinRpcThreadpool;
34 using ::android::hardware::hidl_string;
35 using ::android::hardware::hidl_vec;
36 using ::android::hardware::Return;
37 using ::android::hardware::Void;
38 using ::android::hardware::wifi::V1_0::ChipModeId;
39 using ::android::hardware::wifi::V1_0::IWifiChip;
40 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
41 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
42 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
43 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
44 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
45 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
46 using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
47 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
48 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
49 using ::android::hidl::manager::V1_0::IServiceNotification;
50 using ::android::wifi_system::InterfaceTool;
51 using ::android::wifi_system::SupplicantManager;
52 
53 extern WifiSupplicantHidlEnvironment* gEnv;
54 
55 namespace {
56 
57 // Helper function to initialize the driver and firmware to STA mode
58 // using the vendor HAL HIDL interface.
initilializeDriverAndFirmware()59 void initilializeDriverAndFirmware() {
60     sp<IWifiChip> wifi_chip = getWifiChip();
61     ChipModeId mode_id;
62     EXPECT_TRUE(configureChipToSupportIfaceType(
63         wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
64 }
65 
66 // Helper function to deinitialize the driver and firmware
67 // using the vendor HAL HIDL interface.
deInitilializeDriverAndFirmware()68 void deInitilializeDriverAndFirmware() { stopWifi(); }
69 
70 // Helper function to find any iface of the desired type exposed.
findIfaceOfType(sp<ISupplicant> supplicant,IfaceType desired_type,ISupplicant::IfaceInfo * out_info)71 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
72                      ISupplicant::IfaceInfo* out_info) {
73     bool operation_failed = false;
74     std::vector<ISupplicant::IfaceInfo> iface_infos;
75     supplicant->listInterfaces([&](const SupplicantStatus& status,
76                                    hidl_vec<ISupplicant::IfaceInfo> infos) {
77         if (status.code != SupplicantStatusCode::SUCCESS) {
78             operation_failed = true;
79             return;
80         }
81         iface_infos = infos;
82     });
83     if (operation_failed) {
84         return false;
85     }
86     for (const auto& info : iface_infos) {
87         if (info.type == desired_type) {
88             *out_info = info;
89             return true;
90         }
91     }
92     return false;
93 }
94 
getStaIfaceName()95 std::string getStaIfaceName() {
96     std::array<char, PROPERTY_VALUE_MAX> buffer;
97     property_get("wifi.interface", buffer.data(), "wlan0");
98     return buffer.data();
99 }
100 
getP2pIfaceName()101 std::string getP2pIfaceName() {
102     std::array<char, PROPERTY_VALUE_MAX> buffer;
103     property_get("wifi.direct.interface", buffer.data(), "p2p0");
104     return buffer.data();
105 }
106 }  // namespace
107 
108 // Utility class to wait for wpa_supplicant's HIDL service registration.
109 class ServiceNotificationListener : public IServiceNotification {
110    public:
onRegistration(const hidl_string & fully_qualified_name,const hidl_string & instance_name,bool pre_existing)111     Return<void> onRegistration(const hidl_string& fully_qualified_name,
112                                 const hidl_string& instance_name,
113                                 bool pre_existing) override {
114         if (pre_existing) {
115             return Void();
116         }
117         std::unique_lock<std::mutex> lock(mutex_);
118         registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
119                               instance_name.c_str());
120         lock.unlock();
121         condition_.notify_one();
122         return Void();
123     }
124 
registerForHidlServiceNotifications(const std::string & instance_name)125     bool registerForHidlServiceNotifications(const std::string& instance_name) {
126         if (!ISupplicant::registerForNotifications(instance_name, this)) {
127             return false;
128         }
129         configureRpcThreadpool(2, false);
130         return true;
131     }
132 
waitForHidlService(uint32_t timeout_in_millis,const std::string & instance_name)133     bool waitForHidlService(uint32_t timeout_in_millis,
134                             const std::string& instance_name) {
135         std::unique_lock<std::mutex> lock(mutex_);
136         condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
137                             [&]() { return registered_.size() >= 1; });
138         if (registered_.size() != 1) {
139             return false;
140         }
141         std::string exptected_registered =
142             std::string(ISupplicant::descriptor) + "/" + instance_name;
143         if (registered_[0] != exptected_registered) {
144             LOG(ERROR) << "Expected: " << exptected_registered
145                        << ", Got: " << registered_[0];
146             return false;
147         }
148         return true;
149     }
150 
151    private:
152     std::vector<std::string> registered_{};
153     std::mutex mutex_;
154     std::condition_variable condition_;
155 };
156 
stopSupplicant()157 void stopSupplicant() {
158     SupplicantManager supplicant_manager;
159 
160     ASSERT_TRUE(supplicant_manager.StopSupplicant());
161     deInitilializeDriverAndFirmware();
162     ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
163 }
164 
startSupplicantAndWaitForHidlService()165 void startSupplicantAndWaitForHidlService() {
166     initilializeDriverAndFirmware();
167 
168     android::sp<ServiceNotificationListener> notification_listener =
169         new ServiceNotificationListener();
170     string service_name = gEnv->getServiceName<ISupplicant>();
171     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
172         service_name));
173 
174     SupplicantManager supplicant_manager;
175     ASSERT_TRUE(supplicant_manager.StartSupplicant());
176     ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
177 
178     ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
179 }
180 
is_1_1(const sp<ISupplicant> & supplicant)181 bool is_1_1(const sp<ISupplicant>& supplicant) {
182     sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
183         supplicant_1_1 =
184             ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
185                 supplicant);
186     return supplicant_1_1.get() != nullptr;
187 }
188 
addSupplicantStaIface_1_1(const sp<ISupplicant> & supplicant)189 void addSupplicantStaIface_1_1(const sp<ISupplicant>& supplicant) {
190     sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
191         supplicant_1_1 =
192             ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
193                 supplicant);
194     ASSERT_TRUE(supplicant_1_1.get());
195     ISupplicant::IfaceInfo info = {IfaceType::STA, getStaIfaceName()};
196     supplicant_1_1->addInterface(
197         info, [&](const SupplicantStatus& status,
198                   const sp<ISupplicantIface>& /* iface */) {
199             ASSERT_TRUE(
200                 (SupplicantStatusCode::SUCCESS == status.code) ||
201                 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
202         });
203 }
204 
addSupplicantP2pIface_1_1(const sp<ISupplicant> & supplicant)205 void addSupplicantP2pIface_1_1(const sp<ISupplicant>& supplicant) {
206     sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
207         supplicant_1_1 =
208             ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
209                 supplicant);
210     ASSERT_TRUE(supplicant_1_1.get());
211     ISupplicant::IfaceInfo info = {IfaceType::P2P, getP2pIfaceName()};
212     supplicant_1_1->addInterface(
213         info, [&](const SupplicantStatus& status,
214                   const sp<ISupplicantIface>& /* iface */) {
215             ASSERT_TRUE(
216                 (SupplicantStatusCode::SUCCESS == status.code) ||
217                 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
218         });
219 }
220 
getSupplicant()221 sp<ISupplicant> getSupplicant() {
222     sp<ISupplicant> supplicant =
223         ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
224             gEnv->getServiceName<ISupplicant>());
225     // For 1.1 supplicant, we need to add interfaces at initialization.
226     if (is_1_1(supplicant)) {
227         addSupplicantStaIface_1_1(supplicant);
228         if (gEnv->isP2pOn) {
229             addSupplicantP2pIface_1_1(supplicant);
230         }
231     }
232     return supplicant;
233 }
234 
getSupplicantStaIface()235 sp<ISupplicantStaIface> getSupplicantStaIface() {
236     sp<ISupplicant> supplicant = getSupplicant();
237     if (!supplicant.get()) {
238         return nullptr;
239     }
240     ISupplicant::IfaceInfo info;
241     if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
242         return nullptr;
243     }
244     bool operation_failed = false;
245     sp<ISupplicantStaIface> sta_iface;
246     supplicant->getInterface(info, [&](const SupplicantStatus& status,
247                                        const sp<ISupplicantIface>& iface) {
248         if (status.code != SupplicantStatusCode::SUCCESS) {
249             operation_failed = true;
250             return;
251         }
252         sta_iface = ISupplicantStaIface::castFrom(iface);
253     });
254     if (operation_failed) {
255         return nullptr;
256     }
257     return sta_iface;
258 }
259 
createSupplicantStaNetwork()260 sp<ISupplicantStaNetwork> createSupplicantStaNetwork() {
261     sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
262     if (!sta_iface.get()) {
263         return nullptr;
264     }
265     bool operation_failed = false;
266     sp<ISupplicantStaNetwork> sta_network;
267     sta_iface->addNetwork([&](const SupplicantStatus& status,
268                               const sp<ISupplicantNetwork>& network) {
269         if (status.code != SupplicantStatusCode::SUCCESS) {
270             operation_failed = true;
271             return;
272         }
273         sta_network = ISupplicantStaNetwork::castFrom(network);
274     });
275     if (operation_failed) {
276         return nullptr;
277     }
278     return sta_network;
279 }
280 
getSupplicantP2pIface()281 sp<ISupplicantP2pIface> getSupplicantP2pIface() {
282     sp<ISupplicant> supplicant = getSupplicant();
283     if (!supplicant.get()) {
284         return nullptr;
285     }
286     ISupplicant::IfaceInfo info;
287     if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
288         return nullptr;
289     }
290     bool operation_failed = false;
291     sp<ISupplicantP2pIface> p2p_iface;
292     supplicant->getInterface(info, [&](const SupplicantStatus& status,
293                                        const sp<ISupplicantIface>& iface) {
294         if (status.code != SupplicantStatusCode::SUCCESS) {
295             operation_failed = true;
296             return;
297         }
298         p2p_iface = ISupplicantP2pIface::castFrom(iface);
299     });
300     if (operation_failed) {
301         return nullptr;
302     }
303     return p2p_iface;
304 }
305 
turnOnExcessiveLogging()306 bool turnOnExcessiveLogging() {
307     sp<ISupplicant> supplicant = getSupplicant();
308     if (!supplicant.get()) {
309         return false;
310     }
311     bool operation_failed = false;
312     supplicant->setDebugParams(
313         ISupplicant::DebugLevel::EXCESSIVE,
314         true,  // show timestamps
315         true,  // show keys
316         [&](const SupplicantStatus& status) {
317             if (status.code != SupplicantStatusCode::SUCCESS) {
318                 operation_failed = true;
319             }
320         });
321     return !operation_failed;
322 }
323