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