1 /*
2  * Copyright (C) 2019 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.2/IWifiNanIfaceEventCallback.h>
21 #include <android/hardware/wifi/1.4/IWifi.h>
22 #include <android/hardware/wifi/1.4/IWifiNanIface.h>
23 #include <android/hardware/wifi/1.5/IWifiNanIface.h>
24 #include <gtest/gtest.h>
25 #include <hidl/GtestPrinter.h>
26 #include <hidl/ServiceManagement.h>
27 #include <chrono>
28 #include <condition_variable>
29 #include <mutex>
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 
38 using ::android::sp;
39 using ::android::hardware::Return;
40 using ::android::hardware::Void;
41 
42 #define TIMEOUT_PERIOD 10
43 
getWifiNanIface_1_4(const std::string & instance_name)44 android::sp<android::hardware::wifi::V1_4::IWifiNanIface> getWifiNanIface_1_4(
45     const std::string& instance_name) {
46     return android::hardware::wifi::V1_4::IWifiNanIface::castFrom(
47         getWifiNanIface(instance_name));
48 }
49 
50 /**
51  * Fixture to use for all NAN Iface HIDL interface tests.
52  */
53 class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
54    public:
SetUp()55     virtual void SetUp() override {
56         if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
57             GTEST_SKIP() << "Skipping this test since NAN is not supported.";
58         // Make sure to start with a clean state
59         stopWifi(GetInstanceName());
60 
61         iwifiNanIface = getWifiNanIface_1_4(GetInstanceName());
62         ASSERT_NE(nullptr, iwifiNanIface.get());
63         ASSERT_EQ(WifiStatusCode::SUCCESS,
64                   HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_2,
65                               new WifiNanIfaceEventCallback(*this))
66                       .code);
67     }
68 
TearDown()69     virtual void TearDown() override { stopWifi(GetInstanceName()); }
70 
71     /* Used as a mechanism to inform the test about data/event callback */
notify()72     inline void notify() {
73         std::unique_lock<std::mutex> lock(mtx_);
74         count_++;
75         cv_.notify_one();
76     }
77 
78     enum CallbackType {
79         INVALID = -2,
80         ANY_CALLBACK = -1,
81 
82         NOTIFY_CAPABILITIES_RESPONSE = 0,
83         NOTIFY_ENABLE_RESPONSE,
84         NOTIFY_CONFIG_RESPONSE,
85         NOTIFY_DISABLE_RESPONSE,
86         NOTIFY_START_PUBLISH_RESPONSE,
87         NOTIFY_STOP_PUBLISH_RESPONSE,
88         NOTIFY_START_SUBSCRIBE_RESPONSE,
89         NOTIFY_STOP_SUBSCRIBE_RESPONSE,
90         NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
91         NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
92         NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
93         NOTIFY_INITIATE_DATA_PATH_RESPONSE,
94         NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
95         NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
96 
97         EVENT_CLUSTER_EVENT,
98         EVENT_DISABLED,
99         EVENT_PUBLISH_TERMINATED,
100         EVENT_SUBSCRIBE_TERMINATED,
101         EVENT_MATCH,
102         EVENT_MATCH_EXPIRED,
103         EVENT_FOLLOWUP_RECEIVED,
104         EVENT_TRANSMIT_FOLLOWUP,
105         EVENT_DATA_PATH_REQUEST,
106         EVENT_DATA_PATH_CONFIRM,
107         EVENT_DATA_PATH_TERMINATED,
108         EVENT_DATA_PATH_CONFIRM_1_2,
109         EVENT_DATA_PATH_SCHEDULE_UPDATE
110     };
111 
112     /* Test code calls this function to wait for data/event callback */
113     /* Must set callbackType = INVALID before call this function */
wait(CallbackType waitForCallbackType)114     inline std::cv_status wait(CallbackType waitForCallbackType) {
115         std::unique_lock<std::mutex> lock(mtx_);
116 
117         EXPECT_NE(INVALID, waitForCallbackType);  // can't ASSERT in a
118                                                   // non-void-returning method
119 
120         std::cv_status status = std::cv_status::no_timeout;
121         auto now = std::chrono::system_clock::now();
122         while (count_ == 0) {
123             status = cv_.wait_until(lock,
124                                     now + std::chrono::seconds(TIMEOUT_PERIOD));
125             if (status == std::cv_status::timeout) return status;
126             if (waitForCallbackType != ANY_CALLBACK &&
127                 callbackType != INVALID &&
128                 callbackType != waitForCallbackType) {
129                 count_--;
130             }
131         }
132         count_--;
133         return status;
134     }
135 
136     class WifiNanIfaceEventCallback
137         : public ::android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback {
138         WifiNanIfaceHidlTest& parent_;
139 
140        public:
WifiNanIfaceEventCallback(WifiNanIfaceHidlTest & parent)141         WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent)
142             : parent_(parent){};
143 
144         virtual ~WifiNanIfaceEventCallback() = default;
145 
notifyCapabilitiesResponse(uint16_t id,const WifiNanStatus & status,const NanCapabilities & capabilities)146         Return<void> notifyCapabilitiesResponse(
147             uint16_t id, const WifiNanStatus& status,
148             const NanCapabilities& capabilities) override {
149             parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE;
150 
151             parent_.id = id;
152             parent_.status = status;
153             parent_.capabilities = capabilities;
154 
155             parent_.notify();
156             return Void();
157         }
158 
notifyEnableResponse(uint16_t id,const WifiNanStatus & status)159         Return<void> notifyEnableResponse(
160             uint16_t id, const WifiNanStatus& status) override {
161             parent_.callbackType = NOTIFY_ENABLE_RESPONSE;
162 
163             parent_.id = id;
164             parent_.status = status;
165 
166             parent_.notify();
167             return Void();
168         }
169 
notifyConfigResponse(uint16_t id,const WifiNanStatus & status)170         Return<void> notifyConfigResponse(
171             uint16_t id, const WifiNanStatus& status) override {
172             parent_.callbackType = NOTIFY_CONFIG_RESPONSE;
173 
174             parent_.id = id;
175             parent_.status = status;
176 
177             parent_.notify();
178             return Void();
179         }
180 
notifyDisableResponse(uint16_t id,const WifiNanStatus & status)181         Return<void> notifyDisableResponse(
182             uint16_t id, const WifiNanStatus& status) override {
183             parent_.callbackType = NOTIFY_DISABLE_RESPONSE;
184 
185             parent_.id = id;
186             parent_.status = status;
187 
188             parent_.notify();
189             return Void();
190         }
191 
notifyStartPublishResponse(uint16_t id,const WifiNanStatus & status,uint8_t sessionId)192         Return<void> notifyStartPublishResponse(uint16_t id,
193                                                 const WifiNanStatus& status,
194                                                 uint8_t sessionId) override {
195             parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE;
196 
197             parent_.id = id;
198             parent_.status = status;
199             parent_.sessionId = sessionId;
200 
201             parent_.notify();
202             return Void();
203         }
204 
notifyStopPublishResponse(uint16_t id,const WifiNanStatus & status)205         Return<void> notifyStopPublishResponse(
206             uint16_t id, const WifiNanStatus& status) override {
207             parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE;
208 
209             parent_.id = id;
210             parent_.status = status;
211 
212             parent_.notify();
213             return Void();
214         }
215 
notifyStartSubscribeResponse(uint16_t id,const WifiNanStatus & status,uint8_t sessionId)216         Return<void> notifyStartSubscribeResponse(uint16_t id,
217                                                   const WifiNanStatus& status,
218                                                   uint8_t sessionId) override {
219             parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE;
220 
221             parent_.id = id;
222             parent_.status = status;
223             parent_.sessionId = sessionId;
224 
225             parent_.notify();
226             return Void();
227         }
228 
notifyStopSubscribeResponse(uint16_t id,const WifiNanStatus & status)229         Return<void> notifyStopSubscribeResponse(
230             uint16_t id, const WifiNanStatus& status) override {
231             parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
232 
233             parent_.id = id;
234             parent_.status = status;
235 
236             parent_.notify();
237             return Void();
238         }
239 
notifyTransmitFollowupResponse(uint16_t id,const WifiNanStatus & status)240         Return<void> notifyTransmitFollowupResponse(
241             uint16_t id, const WifiNanStatus& status) override {
242             parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
243 
244             parent_.id = id;
245             parent_.status = status;
246 
247             parent_.notify();
248             return Void();
249         }
250 
notifyCreateDataInterfaceResponse(uint16_t id,const WifiNanStatus & status)251         Return<void> notifyCreateDataInterfaceResponse(
252             uint16_t id, const WifiNanStatus& status) override {
253             parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
254 
255             parent_.id = id;
256             parent_.status = status;
257 
258             parent_.notify();
259             return Void();
260         }
261 
notifyDeleteDataInterfaceResponse(uint16_t id,const WifiNanStatus & status)262         Return<void> notifyDeleteDataInterfaceResponse(
263             uint16_t id, const WifiNanStatus& status) override {
264             parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
265 
266             parent_.id = id;
267             parent_.status = status;
268 
269             parent_.notify();
270             return Void();
271         }
272 
notifyInitiateDataPathResponse(uint16_t id,const WifiNanStatus & status,uint32_t ndpInstanceId)273         Return<void> notifyInitiateDataPathResponse(
274             uint16_t id, const WifiNanStatus& status,
275             uint32_t ndpInstanceId) override {
276             parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
277 
278             parent_.id = id;
279             parent_.status = status;
280             parent_.ndpInstanceId = ndpInstanceId;
281 
282             parent_.notify();
283             return Void();
284         }
285 
notifyRespondToDataPathIndicationResponse(uint16_t id,const WifiNanStatus & status)286         Return<void> notifyRespondToDataPathIndicationResponse(
287             uint16_t id, const WifiNanStatus& status) override {
288             parent_.callbackType =
289                 NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
290 
291             parent_.id = id;
292             parent_.status = status;
293 
294             parent_.notify();
295             return Void();
296         }
297 
notifyTerminateDataPathResponse(uint16_t id,const WifiNanStatus & status)298         Return<void> notifyTerminateDataPathResponse(
299             uint16_t id, const WifiNanStatus& status) override {
300             parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
301 
302             parent_.id = id;
303             parent_.status = status;
304 
305             parent_.notify();
306             return Void();
307         }
308 
eventClusterEvent(const NanClusterEventInd & event)309         Return<void> eventClusterEvent(
310             const NanClusterEventInd& event) override {
311             parent_.callbackType = EVENT_CLUSTER_EVENT;
312 
313             parent_.nanClusterEventInd = event;
314 
315             parent_.notify();
316             return Void();
317         }
318 
eventDisabled(const WifiNanStatus & status)319         Return<void> eventDisabled(const WifiNanStatus& status) override {
320             parent_.callbackType = EVENT_DISABLED;
321 
322             parent_.status = status;
323 
324             parent_.notify();
325             return Void();
326         }
327 
eventPublishTerminated(uint8_t sessionId,const WifiNanStatus & status)328         Return<void> eventPublishTerminated(
329             uint8_t sessionId, const WifiNanStatus& status) override {
330             parent_.callbackType = EVENT_PUBLISH_TERMINATED;
331 
332             parent_.sessionId = sessionId;
333             parent_.status = status;
334 
335             parent_.notify();
336             return Void();
337         }
338 
eventSubscribeTerminated(uint8_t sessionId,const WifiNanStatus & status)339         Return<void> eventSubscribeTerminated(
340             uint8_t sessionId, const WifiNanStatus& status) override {
341             parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED;
342 
343             parent_.sessionId = sessionId;
344             parent_.status = status;
345 
346             parent_.notify();
347             return Void();
348         }
349 
eventMatch(const NanMatchInd & event)350         Return<void> eventMatch(const NanMatchInd& event) override {
351             parent_.callbackType = EVENT_MATCH;
352 
353             parent_.nanMatchInd = event;
354 
355             parent_.notify();
356             return Void();
357         }
358 
eventMatchExpired(uint8_t discoverySessionId,uint32_t peerId)359         Return<void> eventMatchExpired(uint8_t discoverySessionId,
360                                        uint32_t peerId) override {
361             parent_.callbackType = EVENT_MATCH_EXPIRED;
362 
363             parent_.sessionId = discoverySessionId;
364             parent_.peerId = peerId;
365 
366             parent_.notify();
367             return Void();
368         }
369 
eventFollowupReceived(const NanFollowupReceivedInd & event)370         Return<void> eventFollowupReceived(
371             const NanFollowupReceivedInd& event) override {
372             parent_.callbackType = EVENT_FOLLOWUP_RECEIVED;
373 
374             parent_.nanFollowupReceivedInd = event;
375 
376             parent_.notify();
377             return Void();
378         }
379 
eventTransmitFollowup(uint16_t id,const WifiNanStatus & status)380         Return<void> eventTransmitFollowup(
381             uint16_t id, const WifiNanStatus& status) override {
382             parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP;
383 
384             parent_.id = id;
385             parent_.status = status;
386 
387             parent_.notify();
388             return Void();
389         }
390 
eventDataPathRequest(const NanDataPathRequestInd & event)391         Return<void> eventDataPathRequest(
392             const NanDataPathRequestInd& event) override {
393             parent_.callbackType = EVENT_DATA_PATH_REQUEST;
394 
395             parent_.nanDataPathRequestInd = event;
396 
397             parent_.notify();
398             return Void();
399         }
400 
eventDataPathConfirm(const::android::hardware::wifi::V1_0::NanDataPathConfirmInd & event)401         Return<void> eventDataPathConfirm(
402             const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event)
403             override {
404             parent_.callbackType = EVENT_DATA_PATH_CONFIRM;
405 
406             parent_.nanDataPathConfirmInd = event;
407 
408             parent_.notify();
409             return Void();
410         }
411 
eventDataPathTerminated(uint32_t ndpInstanceId)412         Return<void> eventDataPathTerminated(uint32_t ndpInstanceId) override {
413             parent_.callbackType = EVENT_DATA_PATH_TERMINATED;
414 
415             parent_.ndpInstanceId = ndpInstanceId;
416 
417             parent_.notify();
418             return Void();
419         }
420 
eventDataPathConfirm_1_2(const::android::hardware::wifi::V1_2::NanDataPathConfirmInd & event)421         Return<void> eventDataPathConfirm_1_2(
422             const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event)
423             override {
424             parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2;
425 
426             parent_.nanDataPathConfirmInd_1_2 = event;
427 
428             parent_.notify();
429             return Void();
430         }
431 
eventDataPathScheduleUpdate(const NanDataPathScheduleUpdateInd & event)432         Return<void> eventDataPathScheduleUpdate(
433             const NanDataPathScheduleUpdateInd& event) override {
434             parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE;
435 
436             parent_.nanDataPathScheduleUpdateInd = event;
437 
438             parent_.notify();
439             return Void();
440         }
441     };
442 
443    private:
444     // synchronization objects
445     std::mutex mtx_;
446     std::condition_variable cv_;
447     int count_ = 0;
448 
449    protected:
450     android::sp<::android::hardware::wifi::V1_4::IWifiNanIface> iwifiNanIface;
451 
452     // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of
453     // all arguments to all callbacks. They are set by the callback
454     // (notifications or events) and can be retrieved by tests.
455     CallbackType callbackType;
456     uint16_t id;
457     WifiNanStatus status;
458     NanCapabilities capabilities;
459     uint8_t sessionId;
460     uint32_t ndpInstanceId;
461     NanClusterEventInd nanClusterEventInd;
462     NanMatchInd nanMatchInd;
463     uint32_t peerId;
464     NanFollowupReceivedInd nanFollowupReceivedInd;
465     NanDataPathRequestInd nanDataPathRequestInd;
466     ::android::hardware::wifi::V1_0::NanDataPathConfirmInd
467         nanDataPathConfirmInd;
468     ::android::hardware::wifi::V1_2::NanDataPathConfirmInd
469         nanDataPathConfirmInd_1_2;
470     NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd;
471 
GetInstanceName()472     std::string GetInstanceName() { return GetParam(); }
473 };
474 
475 /*
476  * Create:
477  * Ensures that an instance of the IWifiNanIface proxy object is
478  * successfully created.
479  */
TEST_P(WifiNanIfaceHidlTest,Create)480 TEST_P(WifiNanIfaceHidlTest, Create) {
481     // The creation of a proxy object is tested as part of SetUp method.
482 }
483 
484 /*
485  * enableRequest_1_4InvalidArgs: validate that fails with invalid arguments
486  */
TEST_P(WifiNanIfaceHidlTest,enableRequest_1_4InvalidArgs)487 TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4InvalidArgs) {
488     uint16_t inputCmdId = 10;
489     callbackType = INVALID;
490     ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
491     NanConfigRequestSupplemental nanConfigRequestSupp = {};
492 
493     sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
494         ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
495     if (iface_converted != nullptr) {
496         ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
497                   HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
498                               nanEnableRequest, nanConfigRequestSupp)
499                       .code);
500         // Skip this test since this API is deprecated in this newer HAL version
501         return;
502     }
503     ASSERT_EQ(WifiStatusCode::SUCCESS,
504               HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
505                           nanEnableRequest, nanConfigRequestSupp)
506                   .code);
507     // wait for a callback
508     ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
509     ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType);
510     ASSERT_EQ(id, inputCmdId);
511     ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
512 }
513 
514 /*
515  * enableRequest_1_4ShimInvalidArgs: validate that fails with invalid arguments
516  * to the shim
517  */
TEST_P(WifiNanIfaceHidlTest,enableRequest_1_4ShimInvalidArgs)518 TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4ShimInvalidArgs) {
519     uint16_t inputCmdId = 10;
520     ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
521     nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon =
522         128;  // must be <= 127
523     NanConfigRequestSupplemental nanConfigRequestSupp = {};
524 
525     sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
526         ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
527     if (iface_converted != nullptr) {
528         ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
529                   HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
530                               nanEnableRequest, nanConfigRequestSupp)
531                       .code);
532         // Skip this test since this API is deprecated in this newer HAL version
533         return;
534     }
535     ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
536               HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
537                           nanEnableRequest, nanConfigRequestSupp)
538                   .code);
539 }
540 
541 /*
542  * configRequest_1_4InvalidArgs: validate that fails with invalid arguments
543  */
TEST_P(WifiNanIfaceHidlTest,configRequest_1_4InvalidArgs)544 TEST_P(WifiNanIfaceHidlTest, configRequest_1_4InvalidArgs) {
545     uint16_t inputCmdId = 10;
546     callbackType = INVALID;
547     ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
548     NanConfigRequestSupplemental nanConfigRequestSupp = {};
549 
550     sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
551         ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
552     if (iface_converted != nullptr) {
553         ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
554                   HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
555                               nanConfigRequest, nanConfigRequestSupp)
556                       .code);
557         // Skip this test since this API is deprecated in this newer HAL version
558         return;
559     }
560     ASSERT_EQ(WifiStatusCode::SUCCESS,
561               HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
562                           nanConfigRequest, nanConfigRequestSupp)
563                   .code);
564     // wait for a callback
565     ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
566     ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType);
567     ASSERT_EQ(id, inputCmdId);
568     ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
569 }
570 
571 /*
572  * configRequest_1_4ShimInvalidArgs: validate that fails with invalid arguments
573  * to the shim
574  */
TEST_P(WifiNanIfaceHidlTest,configRequest_1_4ShimInvalidArgs)575 TEST_P(WifiNanIfaceHidlTest, configRequest_1_4ShimInvalidArgs) {
576     uint16_t inputCmdId = 10;
577     ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
578     nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128;  // must be <= 127
579     NanConfigRequestSupplemental nanConfigRequestSupp = {};
580 
581     sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
582         ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
583     if (iface_converted != nullptr) {
584         ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
585                   HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
586                               nanConfigRequest, nanConfigRequestSupp)
587                       .code);
588         // Skip this test since this API is deprecated in this newer HAL version
589         return;
590     }
591 
592     ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
593               HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
594                           nanConfigRequest, nanConfigRequestSupp)
595                   .code);
596 }
597 
598 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest);
599 INSTANTIATE_TEST_SUITE_P(
600     PerInstance, WifiNanIfaceHidlTest,
601     testing::ValuesIn(android::hardware::getAllHalInstanceNames(
602         ::android::hardware::wifi::V1_4::IWifi::descriptor)),
603     android::hardware::PrintInstanceNameToString);
604