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