1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Nanache 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.6/IWifi.h>
21 #include <android/hardware/wifi/1.6/IWifiNanIface.h>
22 #include <android/hardware/wifi/1.6/IWifiNanIfaceEventCallback.h>
23 #include <gtest/gtest.h>
24 #include <hidl/GtestPrinter.h>
25 #include <hidl/ServiceManagement.h>
26 #include <chrono>
27 #include <condition_variable>
28 #include <mutex>
29 #include <vector>
30 
31 #include "wifi_hidl_call_util.h"
32 #include "wifi_hidl_test_utils.h"
33 
34 using namespace ::android::hardware::wifi::V1_0;
35 using namespace ::android::hardware::wifi::V1_2;
36 using namespace ::android::hardware::wifi::V1_4;
37 using namespace ::android::hardware::wifi::V1_5;
38 using namespace ::android::hardware::wifi::V1_6;
39 
40 using ::android::sp;
41 using ::android::hardware::Return;
42 using ::android::hardware::Void;
43 
44 #define TIMEOUT_PERIOD 10
45 
getWifiNanIface_1_6(const std::string & instance_name)46 android::sp<android::hardware::wifi::V1_6::IWifiNanIface> getWifiNanIface_1_6(
47         const std::string& instance_name) {
48     return android::hardware::wifi::V1_6::IWifiNanIface::castFrom(getWifiNanIface(instance_name));
49 }
50 
51 /**
52  * Fixture to use for all NAN Iface HIDL interface tests.
53  */
54 class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
55   public:
SetUp()56     virtual void SetUp() override {
57         if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
58             GTEST_SKIP() << "Skipping this test since NAN is not supported.";
59         // Make sure to start with a clean state
60         stopWifi(GetInstanceName());
61 
62         iwifiNanIface = getWifiNanIface_1_6(GetInstanceName());
63         ASSERT_NE(nullptr, iwifiNanIface.get());
64         ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_6,
65                                                        new WifiNanIfaceEventCallback(*this))
66                                                    .code);
67     }
68 
TearDown()69     virtual void TearDown() override { stopWifi(GetInstanceName()); }
70 
71 
72     enum CallbackType {
73         ANY_CALLBACK = -1,
74         INVALID = 0,
75         NOTIFY_CAPABILITIES_RESPONSE = 0,
76         NOTIFY_ENABLE_RESPONSE,
77         NOTIFY_CONFIG_RESPONSE,
78         NOTIFY_DISABLE_RESPONSE,
79         NOTIFY_START_PUBLISH_RESPONSE,
80         NOTIFY_STOP_PUBLISH_RESPONSE,
81         NOTIFY_START_SUBSCRIBE_RESPONSE,
82         NOTIFY_STOP_SUBSCRIBE_RESPONSE,
83         NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
84         NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
85         NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
86         NOTIFY_INITIATE_DATA_PATH_RESPONSE,
87         NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
88         NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
89         NOTIFY_CAPABILITIES_RESPONSE_1_5,
90         NOTIFY_CAPABILITIES_RESPONSE_1_6,
91 
92         EVENT_CLUSTER_EVENT,
93         EVENT_DISABLED,
94         EVENT_PUBLISH_TERMINATED,
95         EVENT_SUBSCRIBE_TERMINATED,
96         EVENT_MATCH,
97         EVENT_MATCH_EXPIRED,
98         EVENT_FOLLOWUP_RECEIVED,
99         EVENT_TRANSMIT_FOLLOWUP,
100         EVENT_DATA_PATH_REQUEST,
101         EVENT_DATA_PATH_CONFIRM,
102         EVENT_DATA_PATH_TERMINATED,
103         EVENT_DATA_PATH_CONFIRM_1_2,
104         EVENT_DATA_PATH_SCHEDULE_UPDATE,
105         EVENT_MATCH_1_6,
106         EVENT_DATA_PATH_SCHEDULE_UPDATE_1_6,
107         EVENT_DATA_PATH_CONFIRM_1_6,
108     };
109 
110     /* Used as a mechanism to inform the test about data/event callback */
notify(CallbackType callbackType)111     inline void notify(CallbackType callbackType) {
112         std::unique_lock<std::mutex> lock(mtx_);
113         callbackEventBitMap |= (0x1 << callbackType);
114         cv_.notify_one();
115     }
116     /* Test code calls this function to wait for data/event callback */
117     /* Must set callbackEventBitMap = INVALID before call this function */
wait(CallbackType waitForCallbackType)118     inline std::cv_status wait(CallbackType waitForCallbackType) {
119         std::unique_lock<std::mutex> lock(mtx_);
120 
121         EXPECT_NE(INVALID, waitForCallbackType);  // can't ASSERT in a
122                                                   // non-void-returning method
123 
124         std::cv_status status = std::cv_status::no_timeout;
125         auto now = std::chrono::system_clock::now();
126         while (!(callbackEventBitMap & (0x1 << waitForCallbackType))) {
127             status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
128             if (status == std::cv_status::timeout)
129                 return status;
130         }
131         return status;
132     }
133 
134     class WifiNanIfaceEventCallback
135         : public ::android::hardware::wifi::V1_6::IWifiNanIfaceEventCallback {
136         WifiNanIfaceHidlTest& parent_;
137 
138       public:
WifiNanIfaceEventCallback(WifiNanIfaceHidlTest & parent)139         WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent) : parent_(parent){};
140 
141         virtual ~WifiNanIfaceEventCallback() = default;
142 
notifyCapabilitiesResponse(uint16_t id,const WifiNanStatus & status,const::android::hardware::wifi::V1_0::NanCapabilities & capabilities)143         Return<void> notifyCapabilitiesResponse(
144                 uint16_t id, const WifiNanStatus& status,
145                 const ::android::hardware::wifi::V1_0::NanCapabilities& capabilities) override {
146             parent_.id = id;
147             parent_.status = status;
148             parent_.capabilities = capabilities;
149 
150             parent_.notify(NOTIFY_CAPABILITIES_RESPONSE);
151             return Void();
152         }
153 
notifyCapabilitiesResponse_1_5(uint16_t id,const WifiNanStatus & status,const::android::hardware::wifi::V1_5::NanCapabilities & capabilities)154         Return<void> notifyCapabilitiesResponse_1_5(
155                 uint16_t id, const WifiNanStatus& status,
156                 const ::android::hardware::wifi::V1_5::NanCapabilities& capabilities) override {
157             parent_.id = id;
158             parent_.status = status;
159             parent_.capabilities_1_5 = capabilities;
160 
161             parent_.notify(NOTIFY_CAPABILITIES_RESPONSE_1_5);
162             return Void();
163         }
164 
notifyEnableResponse(uint16_t id,const WifiNanStatus & status)165         Return<void> notifyEnableResponse(uint16_t id, const WifiNanStatus& status) override {
166             parent_.id = id;
167             parent_.status = status;
168 
169             parent_.notify(NOTIFY_ENABLE_RESPONSE);
170             return Void();
171         }
172 
notifyConfigResponse(uint16_t id,const WifiNanStatus & status)173         Return<void> notifyConfigResponse(uint16_t id, const WifiNanStatus& status) override {
174             parent_.id = id;
175             parent_.status = status;
176 
177             parent_.notify(NOTIFY_CONFIG_RESPONSE);
178             return Void();
179         }
180 
notifyDisableResponse(uint16_t id,const WifiNanStatus & status)181         Return<void> notifyDisableResponse(uint16_t id, const WifiNanStatus& status) override {
182             parent_.id = id;
183             parent_.status = status;
184 
185             parent_.notify(NOTIFY_DISABLE_RESPONSE);
186             return Void();
187         }
188 
notifyStartPublishResponse(uint16_t id,const WifiNanStatus & status,uint8_t sessionId)189         Return<void> notifyStartPublishResponse(uint16_t id, const WifiNanStatus& status,
190                                                 uint8_t sessionId) override {
191             parent_.id = id;
192             parent_.status = status;
193             parent_.sessionId = sessionId;
194 
195             parent_.notify(NOTIFY_START_PUBLISH_RESPONSE);
196             return Void();
197         }
198 
notifyStopPublishResponse(uint16_t id,const WifiNanStatus & status)199         Return<void> notifyStopPublishResponse(uint16_t id, const WifiNanStatus& status) override {
200             parent_.id = id;
201             parent_.status = status;
202 
203             parent_.notify(NOTIFY_STOP_PUBLISH_RESPONSE);
204             return Void();
205         }
206 
notifyStartSubscribeResponse(uint16_t id,const WifiNanStatus & status,uint8_t sessionId)207         Return<void> notifyStartSubscribeResponse(uint16_t id, const WifiNanStatus& status,
208                                                   uint8_t sessionId) override {
209             parent_.id = id;
210             parent_.status = status;
211             parent_.sessionId = sessionId;
212 
213             parent_.notify(NOTIFY_START_SUBSCRIBE_RESPONSE);
214             return Void();
215         }
216 
notifyStopSubscribeResponse(uint16_t id,const WifiNanStatus & status)217         Return<void> notifyStopSubscribeResponse(uint16_t id,
218                                                  const WifiNanStatus& status) override {
219             parent_.id = id;
220             parent_.status = status;
221 
222             parent_.notify(NOTIFY_STOP_SUBSCRIBE_RESPONSE);
223             return Void();
224         }
225 
notifyTransmitFollowupResponse(uint16_t id,const WifiNanStatus & status)226         Return<void> notifyTransmitFollowupResponse(uint16_t id,
227                                                     const WifiNanStatus& status) override {
228             parent_.id = id;
229             parent_.status = status;
230 
231             parent_.notify(NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE);
232             return Void();
233         }
234 
notifyCreateDataInterfaceResponse(uint16_t id,const WifiNanStatus & status)235         Return<void> notifyCreateDataInterfaceResponse(uint16_t id,
236                                                        const WifiNanStatus& status) override {
237             parent_.id = id;
238             parent_.status = status;
239 
240             parent_.notify(NOTIFY_CREATE_DATA_INTERFACE_RESPONSE);
241             return Void();
242         }
243 
notifyDeleteDataInterfaceResponse(uint16_t id,const WifiNanStatus & status)244         Return<void> notifyDeleteDataInterfaceResponse(uint16_t id,
245                                                        const WifiNanStatus& status) override {
246             parent_.id = id;
247             parent_.status = status;
248 
249             parent_.notify(NOTIFY_DELETE_DATA_INTERFACE_RESPONSE);
250             return Void();
251         }
252 
notifyInitiateDataPathResponse(uint16_t id,const WifiNanStatus & status,uint32_t ndpInstanceId)253         Return<void> notifyInitiateDataPathResponse(uint16_t id, const WifiNanStatus& status,
254                                                     uint32_t ndpInstanceId) override {
255             parent_.id = id;
256             parent_.status = status;
257             parent_.ndpInstanceId = ndpInstanceId;
258 
259             parent_.notify(NOTIFY_INITIATE_DATA_PATH_RESPONSE);
260             return Void();
261         }
262 
notifyRespondToDataPathIndicationResponse(uint16_t id,const WifiNanStatus & status)263         Return<void> notifyRespondToDataPathIndicationResponse(
264                 uint16_t id, const WifiNanStatus& status) override {
265             parent_.id = id;
266             parent_.status = status;
267 
268             parent_.notify(NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE);
269             return Void();
270         }
271 
notifyTerminateDataPathResponse(uint16_t id,const WifiNanStatus & status)272         Return<void> notifyTerminateDataPathResponse(uint16_t id,
273                                                      const WifiNanStatus& status) override {
274             parent_.id = id;
275             parent_.status = status;
276 
277             parent_.notify(NOTIFY_TERMINATE_DATA_PATH_RESPONSE);
278             return Void();
279         }
280 
eventClusterEvent(const NanClusterEventInd & event)281         Return<void> eventClusterEvent(const NanClusterEventInd& event) override {
282             parent_.nanClusterEventInd = event;
283 
284             parent_.notify(EVENT_CLUSTER_EVENT);
285             return Void();
286         }
287 
eventDisabled(const WifiNanStatus & status)288         Return<void> eventDisabled(const WifiNanStatus& status) override {
289             parent_.status = status;
290 
291             parent_.notify(EVENT_DISABLED);
292             return Void();
293         }
294 
eventPublishTerminated(uint8_t sessionId,const WifiNanStatus & status)295         Return<void> eventPublishTerminated(uint8_t sessionId,
296                                             const WifiNanStatus& status) override {
297             parent_.sessionId = sessionId;
298             parent_.status = status;
299 
300             parent_.notify(EVENT_PUBLISH_TERMINATED);
301             return Void();
302         }
303 
eventSubscribeTerminated(uint8_t sessionId,const WifiNanStatus & status)304         Return<void> eventSubscribeTerminated(uint8_t sessionId,
305                                               const WifiNanStatus& status) override {
306             parent_.sessionId = sessionId;
307             parent_.status = status;
308 
309             parent_.notify(EVENT_SUBSCRIBE_TERMINATED);
310             return Void();
311         }
312 
eventMatch(const::android::hardware::wifi::V1_0::NanMatchInd & event)313         Return<void> eventMatch(
314                 const ::android::hardware::wifi::V1_0::NanMatchInd& event) override {
315             parent_.nanMatchInd = event;
316 
317             parent_.notify(EVENT_MATCH);
318             return Void();
319         }
320 
eventMatchExpired(uint8_t discoverySessionId,uint32_t peerId)321         Return<void> eventMatchExpired(uint8_t discoverySessionId, uint32_t peerId) override {
322             parent_.sessionId = discoverySessionId;
323             parent_.peerId = peerId;
324 
325             parent_.notify(EVENT_MATCH_EXPIRED);
326             return Void();
327         }
328 
eventFollowupReceived(const NanFollowupReceivedInd & event)329         Return<void> eventFollowupReceived(const NanFollowupReceivedInd& event) override {
330             parent_.nanFollowupReceivedInd = event;
331 
332             parent_.notify(EVENT_FOLLOWUP_RECEIVED);
333             return Void();
334         }
335 
eventTransmitFollowup(uint16_t id,const WifiNanStatus & status)336         Return<void> eventTransmitFollowup(uint16_t id, const WifiNanStatus& status) override {
337             parent_.id = id;
338             parent_.status = status;
339 
340             parent_.notify(EVENT_TRANSMIT_FOLLOWUP);
341             return Void();
342         }
343 
eventDataPathRequest(const NanDataPathRequestInd & event)344         Return<void> eventDataPathRequest(const NanDataPathRequestInd& event) override {
345             parent_.nanDataPathRequestInd = event;
346 
347             parent_.notify(EVENT_DATA_PATH_REQUEST);
348             return Void();
349         }
350 
eventDataPathConfirm(const::android::hardware::wifi::V1_0::NanDataPathConfirmInd & event)351         Return<void> eventDataPathConfirm(
352                 const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event) override {
353             parent_.nanDataPathConfirmInd = event;
354 
355             parent_.notify(EVENT_DATA_PATH_CONFIRM);
356             return Void();
357         }
358 
eventDataPathTerminated(uint32_t ndpInstanceId)359         Return<void> eventDataPathTerminated(uint32_t ndpInstanceId) override {
360             parent_.ndpInstanceId = ndpInstanceId;
361 
362             parent_.notify(EVENT_DATA_PATH_TERMINATED);
363             return Void();
364         }
365 
eventDataPathConfirm_1_2(const::android::hardware::wifi::V1_2::NanDataPathConfirmInd & event)366         Return<void> eventDataPathConfirm_1_2(
367                 const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event) override {
368             parent_.nanDataPathConfirmInd_1_2 = event;
369 
370             parent_.notify(EVENT_DATA_PATH_CONFIRM_1_2);
371             return Void();
372         }
373 
eventDataPathScheduleUpdate(const::android::hardware::wifi::V1_2::NanDataPathScheduleUpdateInd & event)374         Return<void> eventDataPathScheduleUpdate(
375                 const ::android::hardware::wifi::V1_2::NanDataPathScheduleUpdateInd& event)
376                 override {
377             parent_.nanDataPathScheduleUpdateInd_1_2 = event;
378 
379             parent_.notify(EVENT_DATA_PATH_SCHEDULE_UPDATE);
380             return Void();
381         }
382 
eventMatch_1_6(const::android::hardware::wifi::V1_6::NanMatchInd & event)383         Return<void> eventMatch_1_6(
384                 const ::android::hardware::wifi::V1_6::NanMatchInd& event) override {
385             parent_.nanMatchInd_1_6 = event;
386 
387             parent_.notify(EVENT_MATCH_1_6);
388             return Void();
389         }
390 
notifyCapabilitiesResponse_1_6(uint16_t id,const WifiNanStatus & status,const::android::hardware::wifi::V1_6::NanCapabilities & capabilities)391         Return<void> notifyCapabilitiesResponse_1_6(
392                 uint16_t id, const WifiNanStatus& status,
393                 const ::android::hardware::wifi::V1_6::NanCapabilities& capabilities) override {
394             parent_.id = id;
395             parent_.status = status;
396             parent_.capabilities_1_6 = capabilities;
397 
398             parent_.notify(NOTIFY_CAPABILITIES_RESPONSE_1_6);
399             return Void();
400         }
401 
eventDataPathScheduleUpdate_1_6(const::android::hardware::wifi::V1_6::NanDataPathScheduleUpdateInd & event)402         Return<void> eventDataPathScheduleUpdate_1_6(
403                 const ::android::hardware::wifi::V1_6::NanDataPathScheduleUpdateInd& event)
404                 override {
405             parent_.nanDataPathScheduleUpdateInd_1_6 = event;
406 
407             parent_.notify(EVENT_DATA_PATH_SCHEDULE_UPDATE_1_6);
408             return Void();
409         }
410 
eventDataPathConfirm_1_6(const::android::hardware::wifi::V1_6::NanDataPathConfirmInd & event)411         Return<void> eventDataPathConfirm_1_6(
412                 const ::android::hardware::wifi::V1_6::NanDataPathConfirmInd& event) override {
413             parent_.nanDataPathConfirmInd_1_6 = event;
414 
415             parent_.notify(EVENT_DATA_PATH_CONFIRM_1_6);
416             return Void();
417         }
418     };
419 
420   private:
421     // synchronization objects
422     std::mutex mtx_;
423     std::condition_variable cv_;
424 
425   protected:
426     android::sp<::android::hardware::wifi::V1_6::IWifiNanIface> iwifiNanIface;
427 
428     // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of
429     // all arguments to all callbacks. They are set by the callback
430     // (notifications or events) and can be retrieved by tests.
431     uint32_t callbackEventBitMap;
432     uint16_t id;
433     WifiNanStatus status;
434     uint8_t sessionId;
435     uint32_t ndpInstanceId;
436     NanClusterEventInd nanClusterEventInd;
437     ::android::hardware::wifi::V1_0::NanMatchInd nanMatchInd;
438     ::android::hardware::wifi::V1_6::NanMatchInd nanMatchInd_1_6;
439     uint32_t peerId;
440     NanFollowupReceivedInd nanFollowupReceivedInd;
441     NanDataPathRequestInd nanDataPathRequestInd;
442     ::android::hardware::wifi::V1_0::NanCapabilities capabilities;
443     ::android::hardware::wifi::V1_5::NanCapabilities capabilities_1_5;
444     ::android::hardware::wifi::V1_6::NanCapabilities capabilities_1_6;
445     ::android::hardware::wifi::V1_0::NanDataPathConfirmInd nanDataPathConfirmInd;
446     ::android::hardware::wifi::V1_2::NanDataPathConfirmInd nanDataPathConfirmInd_1_2;
447     ::android::hardware::wifi::V1_6::NanDataPathConfirmInd nanDataPathConfirmInd_1_6;
448     ::android::hardware::wifi::V1_2::NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd_1_2;
449     ::android::hardware::wifi::V1_6::NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd_1_6;
450 
GetInstanceName()451     std::string GetInstanceName() { return GetParam(); }
452 };
453 
454 /*
455  * Create:
456  * Ensures that an instance of the IWifiNanIface proxy object is
457  * successfully created.
458  */
TEST_P(WifiNanIfaceHidlTest,Create)459 TEST_P(WifiNanIfaceHidlTest, Create) {
460     // The creation of a proxy object is tested as part of SetUp method.
461 }
462 
463 /*
464  * enableRequest_1_6InvalidArgs: validate that fails with invalid arguments
465  */
TEST_P(WifiNanIfaceHidlTest,enableRequest_1_6InvalidArgs)466 TEST_P(WifiNanIfaceHidlTest, enableRequest_1_6InvalidArgs) {
467     uint16_t inputCmdId = 10;
468     callbackEventBitMap = INVALID;
469     ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
470     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
471     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, enableRequest_1_6, inputCmdId,
472                                         nanEnableRequest, nanConfigRequestSupp);
473     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
474         ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code);
475 
476         // wait for a callback
477         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
478         ASSERT_EQ(0x1 << NOTIFY_ENABLE_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_ENABLE_RESPONSE));
479         ASSERT_EQ(id, inputCmdId);
480         ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
481     }
482 }
483 
484 /*
485  * enableRequest_1_6ShimInvalidArgs: validate that fails with invalid arguments
486  * to the shim
487  */
TEST_P(WifiNanIfaceHidlTest,enableRequest_1_6ShimInvalidArgs)488 TEST_P(WifiNanIfaceHidlTest, enableRequest_1_6ShimInvalidArgs) {
489     uint16_t inputCmdId = 10;
490     ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
491     nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = 128;  // must be <= 127
492     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
493     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, enableRequest_1_6, inputCmdId,
494                                         nanEnableRequest, nanConfigRequestSupp);
495     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
496         ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code);
497     }
498 }
499 
500 /*
501  * configRequest_1_6InvalidArgs: validate that fails with invalid arguments
502  */
TEST_P(WifiNanIfaceHidlTest,configRequest_1_6InvalidArgs)503 TEST_P(WifiNanIfaceHidlTest, configRequest_1_6InvalidArgs) {
504     uint16_t inputCmdId = 10;
505     callbackEventBitMap = INVALID;
506     ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
507     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
508     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, configRequest_1_6, inputCmdId,
509                                         nanConfigRequest, nanConfigRequestSupp);
510 
511     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
512         ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code);
513 
514         // wait for a callback
515         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
516         ASSERT_EQ(0x1 << NOTIFY_CONFIG_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_CONFIG_RESPONSE));
517         ASSERT_EQ(id, inputCmdId);
518         ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
519     }
520 }
521 
522 /*
523  * configRequest_1_6ShimInvalidArgs: validate that fails with invalid arguments
524  * to the shim
525  */
TEST_P(WifiNanIfaceHidlTest,configRequest_1_6ShimInvalidArgs)526 TEST_P(WifiNanIfaceHidlTest, configRequest_1_6ShimInvalidArgs) {
527     uint16_t inputCmdId = 10;
528     ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
529     nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128;  // must be <= 127
530     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
531     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, configRequest_1_6, inputCmdId,
532                                         nanConfigRequest, nanConfigRequestSupp);
533     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
534         ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code);
535     }
536 }
537 
538 /*
539  * notifyCapabilitiesResponse_1_6: validate that returns capabilities.
540  */
TEST_P(WifiNanIfaceHidlTest,notifyCapabilitiesResponse_1_6)541 TEST_P(WifiNanIfaceHidlTest, notifyCapabilitiesResponse_1_6) {
542     uint16_t inputCmdId = 10;
543     callbackEventBitMap = INVALID;
544     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest_1_5, inputCmdId).code;
545     ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus);
546     // wait for a callback
547     ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE_1_6));
548     ASSERT_EQ(0x1 << NOTIFY_CAPABILITIES_RESPONSE_1_6, callbackEventBitMap & (0x1 << NOTIFY_CAPABILITIES_RESPONSE_1_6));
549     ASSERT_EQ(id, inputCmdId);
550     ASSERT_EQ(status.status, NanStatusType::SUCCESS);
551 
552     // check for reasonable capability values
553     EXPECT_GT(capabilities_1_6.maxConcurrentClusters, (unsigned int)0);
554     EXPECT_GT(capabilities_1_6.maxPublishes, (unsigned int)0);
555     EXPECT_GT(capabilities_1_6.maxSubscribes, (unsigned int)0);
556     EXPECT_EQ(capabilities_1_6.maxServiceNameLen, (unsigned int)255);
557     EXPECT_EQ(capabilities_1_6.maxMatchFilterLen, (unsigned int)255);
558     EXPECT_GT(capabilities_1_6.maxTotalMatchFilterLen, (unsigned int)255);
559     EXPECT_EQ(capabilities_1_6.maxServiceSpecificInfoLen, (unsigned int)255);
560     EXPECT_GE(capabilities_1_6.maxExtendedServiceSpecificInfoLen, (unsigned int)255);
561     EXPECT_GT(capabilities_1_6.maxNdiInterfaces, (unsigned int)0);
562     EXPECT_GT(capabilities_1_6.maxNdpSessions, (unsigned int)0);
563     EXPECT_GT(capabilities_1_6.maxAppInfoLen, (unsigned int)0);
564     EXPECT_GT(capabilities_1_6.maxQueuedTransmitFollowupMsgs, (unsigned int)0);
565     EXPECT_GT(capabilities_1_6.maxSubscribeInterfaceAddresses, (unsigned int)0);
566     EXPECT_NE(capabilities_1_6.supportedCipherSuites, (unsigned int)0);
567     EXPECT_TRUE(capabilities_1_6.instantCommunicationModeSupportFlag ||
568                 !capabilities_1_6.instantCommunicationModeSupportFlag);
569 }
570 
571 /*
572  * startPublishRequest_1_6: validate that success with valid arguments
573  */
TEST_P(WifiNanIfaceHidlTest,startPublishRequest_1_6)574 TEST_P(WifiNanIfaceHidlTest, startPublishRequest_1_6) {
575     uint16_t inputCmdId = 10;
576     ::android::hardware::wifi::V1_0::NanBandSpecificConfig config24 = {};
577     config24.rssiClose = 60;
578     config24.rssiMiddle = 70;
579     config24.rssiCloseProximity = 60;
580     config24.dwellTimeMs = 200;
581     config24.scanPeriodSec = 20;
582     config24.validDiscoveryWindowIntervalVal = false;
583     config24.discoveryWindowIntervalVal = 0;
584 
585     ::android::hardware::wifi::V1_0::NanBandSpecificConfig config5 = {};
586     config5.rssiClose = 60;
587     config5.rssiMiddle = 75;
588     config5.rssiCloseProximity = 60;
589     config5.dwellTimeMs = 200;
590     config5.scanPeriodSec = 20;
591     config5.validDiscoveryWindowIntervalVal = false;
592     config5.discoveryWindowIntervalVal = 0;
593     ::android::hardware::wifi::V1_4::NanEnableRequest req = {};
594     req.operateInBand[(size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_24GHZ] = true;
595     req.operateInBand[(size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_5GHZ] = false;
596     req.hopCountMax = 2;
597     req.configParams.masterPref = 0;
598     req.configParams.disableDiscoveryAddressChangeIndication = true;
599     req.configParams.disableStartedClusterIndication = true;
600     req.configParams.disableJoinedClusterIndication = true;
601     req.configParams.includePublishServiceIdsInBeacon = true;
602     req.configParams.numberOfPublishServiceIdsInBeacon = 0;
603     req.configParams.includeSubscribeServiceIdsInBeacon = true;
604     req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
605     req.configParams.rssiWindowSize = 8;
606     req.configParams.macAddressRandomizationIntervalSec = 1800;
607     req.configParams.bandSpecificConfig[(
608             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_24GHZ] = config24;
609     req.configParams.bandSpecificConfig[(
610             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_5GHZ] = config5;
611 
612     req.debugConfigs.validClusterIdVals = true;
613     req.debugConfigs.clusterIdTopRangeVal = 65535;
614     req.debugConfigs.clusterIdBottomRangeVal = 0;
615     req.debugConfigs.validIntfAddrVal = false;
616     req.debugConfigs.validOuiVal = false;
617     req.debugConfigs.ouiVal = 0;
618     req.debugConfigs.validRandomFactorForceVal = false;
619     req.debugConfigs.randomFactorForceVal = 0;
620     req.debugConfigs.validHopCountForceVal = false;
621     req.debugConfigs.hopCountForceVal = 0;
622     req.debugConfigs.validDiscoveryChannelVal = false;
623     req.debugConfigs.discoveryChannelMhzVal[(
624             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_24GHZ] = 0;
625     req.debugConfigs.discoveryChannelMhzVal[(
626             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_5GHZ] = 0;
627     req.debugConfigs.validUseBeaconsInBandVal = false;
628     req.debugConfigs.useBeaconsInBandVal[(
629             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_24GHZ] = true;
630     req.debugConfigs.useBeaconsInBandVal[(
631             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_5GHZ] = true;
632     req.debugConfigs.validUseSdfInBandVal = false;
633     req.debugConfigs.useSdfInBandVal[(
634             size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_24GHZ] = true;
635     req.debugConfigs
636             .useSdfInBandVal[(size_t)::android::hardware::wifi::V1_4::NanBandIndex::NAN_BAND_5GHZ] =
637             true;
638 
639     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
640     nanConfigRequestSupp.V1_5.V1_2.discoveryBeaconIntervalMs = 20;
641     nanConfigRequestSupp.V1_5.V1_2.numberOfSpatialStreamsInDiscovery = 0;
642     nanConfigRequestSupp.V1_5.V1_2.enableDiscoveryWindowEarlyTermination = false;
643 
644     callbackEventBitMap = INVALID;
645 
646     const auto& halStatus =
647             HIDL_INVOKE(iwifiNanIface, enableRequest_1_6, inputCmdId, req, nanConfigRequestSupp);
648     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
649         ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code);
650 
651         // wait for a callback
652         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
653         ASSERT_EQ(0x1 << NOTIFY_ENABLE_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_ENABLE_RESPONSE));
654         ASSERT_EQ(id, inputCmdId);
655         ASSERT_EQ(status.status, NanStatusType::SUCCESS);
656     }
657     ::android::hardware::wifi::V1_6::NanPublishRequest nanPublishRequest = {};
658     nanPublishRequest.baseConfigs.sessionId = 0;
659     nanPublishRequest.baseConfigs.ttlSec = 0;
660     nanPublishRequest.baseConfigs.discoveryWindowPeriod = 1;
661     nanPublishRequest.baseConfigs.discoveryCount = 0;
662     nanPublishRequest.baseConfigs.serviceName = {97};
663 
664     nanPublishRequest.baseConfigs.discoveryMatchIndicator = NanMatchAlg::MATCH_NEVER;
665     nanPublishRequest.baseConfigs.useRssiThreshold = false;
666     nanPublishRequest.baseConfigs.disableDiscoveryTerminationIndication = false;
667     nanPublishRequest.baseConfigs.disableMatchExpirationIndication = true;
668     nanPublishRequest.baseConfigs.disableFollowupReceivedIndication = false;
669     nanPublishRequest.baseConfigs.securityConfig.securityType = NanDataPathSecurityType::OPEN;
670     nanPublishRequest.autoAcceptDataPathRequests = false;
671     nanPublishRequest.publishType = NanPublishType::UNSOLICITED;
672     nanPublishRequest.txType = NanTxType::BROADCAST;
673 
674     const auto& halStatus1 =
675             HIDL_INVOKE(iwifiNanIface, startPublishRequest_1_6, inputCmdId + 1, nanPublishRequest);
676 
677     if (halStatus1.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
678         ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus1.code);
679 
680         // wait for a callback
681         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_START_PUBLISH_RESPONSE));
682         ASSERT_EQ(0x1 << NOTIFY_START_PUBLISH_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_START_PUBLISH_RESPONSE));
683         ASSERT_EQ(id, inputCmdId + 1);
684         ASSERT_EQ(status.status, NanStatusType::SUCCESS);
685     }
686 }
687 
688 /*
689  * respondToDataPathIndicationRequest_1_6InvalidArgs: validate that fails with invalid arguments
690  */
TEST_P(WifiNanIfaceHidlTest,respondToDataPathIndicationRequest_1_6ShimInvalidArgs)691 TEST_P(WifiNanIfaceHidlTest, respondToDataPathIndicationRequest_1_6ShimInvalidArgs) {
692     uint16_t inputCmdId = 10;
693     callbackEventBitMap = INVALID;
694     ::android::hardware::wifi::V1_6::NanRespondToDataPathIndicationRequest
695             nanRespondToDataPathIndicationRequest = {};
696     nanRespondToDataPathIndicationRequest.ifaceName = "AwareinterfaceNameTooLong";
697     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, respondToDataPathIndicationRequest_1_6,
698                                         inputCmdId, nanRespondToDataPathIndicationRequest);
699 
700     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
701         ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code);
702     }
703 }
704 
705 /*
706  * initiateDataPathRequest_1_6InvalidArgs: validate that fails with invalid arguments
707  */
TEST_P(WifiNanIfaceHidlTest,initiateDataPathRequest_1_6ShimInvalidArgs)708 TEST_P(WifiNanIfaceHidlTest, initiateDataPathRequest_1_6ShimInvalidArgs) {
709     uint16_t inputCmdId = 10;
710     callbackEventBitMap = INVALID;
711     ::android::hardware::wifi::V1_6::NanInitiateDataPathRequest nanInitiateDataPathRequest = {};
712     nanInitiateDataPathRequest.ifaceName = "AwareinterfaceNameTooLong";
713     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, initiateDataPathRequest_1_6, inputCmdId,
714                                         nanInitiateDataPathRequest);
715 
716     if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
717         ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code);
718     }
719 }
720 
721 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest);
722 INSTANTIATE_TEST_SUITE_P(PerInstance, WifiNanIfaceHidlTest,
723                          testing::ValuesIn(android::hardware::getAllHalInstanceNames(
724                                  ::android::hardware::wifi::V1_6::IWifi::descriptor)),
725                          android::hardware::PrintInstanceNameToString);
726