From 3ec6781c357ed30e1d4abbef4ea6c1b36fcbba60 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 24 Aug 2020 11:04:31 -0700 Subject: [PATCH] [AWARE] Add support for instant communication mode Bug: 160725208 Test: atest WifiNanIfaceTest,VtsHalWifiNanV1_0TargetTest, VtsHalWifiNanV1_2TargetTest, VtsHalWifiNanV1_4TargetTest, VtsHalWifiNanV1_5TargetTest Change-Id: I66c8532dcd50d5702edbcd89005b9e7373659594 --- wifi/1.0/vts/functional/Android.bp | 5 + .../functional/wifi_nan_iface_hidl_test.cpp | 11 + wifi/1.4/vts/functional/Android.bp | 1 + .../functional/wifi_nan_iface_hidl_test.cpp | 46 ++ wifi/1.5/Android.bp | 2 + wifi/1.5/IWifiNanIface.hal | 113 ++++ wifi/1.5/IWifiNanIfaceEventCallback.hal | 44 ++ wifi/1.5/default/hidl_struct_util.cpp | 98 ++- wifi/1.5/default/hidl_struct_util.h | 13 +- .../tests/wifi_nan_iface_unit_tests.cpp | 11 +- wifi/1.5/default/wifi_nan_iface.cpp | 96 ++- wifi/1.5/default/wifi_nan_iface.h | 32 +- wifi/1.5/types.hal | 32 + wifi/1.5/vts/OWNERS | 2 + wifi/1.5/vts/functional/Android.bp | 39 ++ .../functional/wifi_nan_iface_hidl_test.cpp | 628 ++++++++++++++++++ 16 files changed, 1127 insertions(+), 46 deletions(-) create mode 100644 wifi/1.5/IWifiNanIface.hal create mode 100644 wifi/1.5/IWifiNanIfaceEventCallback.hal create mode 100644 wifi/1.5/vts/OWNERS create mode 100644 wifi/1.5/vts/functional/Android.bp create mode 100644 wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index cad54feb5c..30512a9f1a 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -73,6 +73,11 @@ cc_test { static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp index 17abbd7096..a74987cf24 100644 --- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -483,6 +484,16 @@ TEST_P(WifiNanIfaceHidlTest, FailOnIfaceInvalid) { TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest) { uint16_t inputCmdId = 10; callbackType = INVALID; + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } + ASSERT_EQ( WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId).code); diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp index 59a35e0262..0051d27d6b 100644 --- a/wifi/1.4/vts/functional/Android.bp +++ b/wifi/1.4/vts/functional/Android.bp @@ -52,6 +52,7 @@ cc_test { "android.hardware.wifi@1.2", "android.hardware.wifi@1.3", "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp index 9b69f57233..3ac047d2c8 100644 --- a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -488,6 +489,17 @@ TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4InvalidArgs) { callbackType = INVALID; ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {}; NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, + nanEnableRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, nanEnableRequest, nanConfigRequestSupp) @@ -509,6 +521,17 @@ TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4ShimInvalidArgs) { nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127 NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, + nanEnableRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, nanEnableRequest, nanConfigRequestSupp) @@ -523,6 +546,17 @@ TEST_P(WifiNanIfaceHidlTest, configRequest_1_4InvalidArgs) { callbackType = INVALID; ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, + nanConfigRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, nanConfigRequest, nanConfigRequestSupp) @@ -543,6 +577,18 @@ TEST_P(WifiNanIfaceHidlTest, configRequest_1_4ShimInvalidArgs) { ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127 NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, + nanConfigRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } + ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, nanConfigRequest, nanConfigRequestSupp) diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 53047603b9..ecb0a35f18 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -7,6 +7,8 @@ hidl_interface { "types.hal", "IWifi.hal", "IWifiChip.hal", + "IWifiNanIface.hal", + "IWifiNanIfaceEventCallback.hal", ], interfaces: [ "android.hardware.wifi@1.0", diff --git a/wifi/1.5/IWifiNanIface.hal b/wifi/1.5/IWifiNanIface.hal new file mode 100644 index 0000000000..93257b525a --- /dev/null +++ b/wifi/1.5/IWifiNanIface.hal @@ -0,0 +1,113 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.5; + +import @1.0::CommandIdShort; +import @1.0::WifiStatus; +import @1.4::IWifiNanIface; +import @1.4::NanConfigRequest; +import @1.4::NanEnableRequest; +import IWifiNanIfaceEventCallback; +import NanConfigRequestSupplemental; + +/** + * Interface used to represent a single NAN (Neighbour Aware Network) iface. + * + * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness + * Networking (NAN) Technical Specification". + */ +interface IWifiNanIface extends @1.4::IWifiNanIface { + /** + * Enable NAN: configures and activates NAN clustering (does not start + * a discovery session or set up data-interfaces or data-paths). Use the + * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled + * NAN interface. + * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|. + * + * Note: supersedes the @1.4::IWifiNanIface.enableRequest() method which is deprecated as of + * HAL version 1.5. + * + * @param cmdId command Id to use for this invocation. + * @param msg1 Instance of |NanEnableRequest|. + * @param msg2 Instance of |NanConfigRequestSupplemental|. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + enableRequest_1_5(CommandIdShort cmdId, NanEnableRequest msg1, + NanConfigRequestSupplemental msg2) generates (WifiStatus status); + + /** + * Configure NAN: configures an existing NAN functionality (i.e. assumes + * |IWifiNanIface.enableRequest| already submitted and succeeded). + * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|. + * + * Note: supersedes the @1.4::IWifiNanIface.configRequest() method which is deprecated as of + * HAL version 1.5. + * + * @param cmdId command Id to use for this invocation. + * @param msg1 Instance of |NanConfigRequest|. + * @param msg2 Instance of |NanConfigRequestSupplemental|. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + configRequest_1_5(CommandIdShort cmdId, NanConfigRequest msg1, + NanConfigRequestSupplemental msg2) generates (WifiStatus status); + + /** + * Requests notifications of significant events on this iface. Multiple calls + * to this must register multiple callbacks each of which must receive all + * events. + * + * Note: supersedes the @1.2::IWifiNanIface.registerEventCallback() method which is deprecated + * as of HAL version 1.5. + * + * @param callback An instance of the |IWifiNanIfaceEventCallback| HIDL interface + * object. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID| + */ + registerEventCallback_1_5(IWifiNanIfaceEventCallback callback) + generates (WifiStatus status); + + /** + * Get NAN capabilities. Asynchronous response is with + * |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|. + + * Note: supersedes the @1.0::IWifiNanIface.getCapabilitiesRequest() method which is deprecated + * as of HAL version 1.5. + * + * @param cmdId command Id to use for this invocation. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status); +}; \ No newline at end of file diff --git a/wifi/1.5/IWifiNanIfaceEventCallback.hal b/wifi/1.5/IWifiNanIfaceEventCallback.hal new file mode 100644 index 0000000000..867c03c47e --- /dev/null +++ b/wifi/1.5/IWifiNanIfaceEventCallback.hal @@ -0,0 +1,44 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.5; + +import @1.0::CommandIdShort; +import @1.0::WifiNanStatus; +import @1.2::IWifiNanIfaceEventCallback; + +/** + * NAN Response and Asynchronous Event Callbacks. + * + * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness + * Networking (NAN) Technical Specification". + */ +interface IWifiNanIfaceEventCallback extends @1.2::IWifiNanIfaceEventCallback { + /** + * Asynchronous callback invoked in response to a capability request + * |IWifiNanIface.getCapabilitiesRequest|. + * + * Note: supersedes the @1.2::IWifiNanIfaceEventCallback.notifyCapabilitiesResponse() method + * which is deprecated as of HAL version 1.5. + * + * @param cmdId command Id corresponding to the original request. + * @param status WifiNanStatus of the operation. Possible status codes are: + * |NanStatusType.SUCCESS| + * @param capabilities Capability data. + */ + oneway notifyCapabilitiesResponse_1_5(CommandIdShort id, WifiNanStatus status, + NanCapabilities capabilities); +}; \ No newline at end of file diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 91a82a7661..578f3e2f0f 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -1280,7 +1280,7 @@ bool convertHidlNanEnableRequestToLegacy( bool convertHidlNanEnableRequest_1_4ToLegacy( const V1_4::NanEnableRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) @@ -1295,14 +1295,60 @@ bool convertHidlNanEnableRequest_1_4ToLegacy( legacy_request->config_discovery_beacon_int = 1; legacy_request->discovery_beacon_interval = - hidl_request2.discoveryBeaconIntervalMs; + hidl_request2.V1_2.discoveryBeaconIntervalMs; legacy_request->config_nss = 1; - legacy_request->nss = hidl_request2.numberOfSpatialStreamsInDiscovery; + legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; legacy_request->config_dw_early_termination = 1; legacy_request->enable_dw_termination = - hidl_request2.enableDiscoveryWindowEarlyTermination; + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; legacy_request->config_enable_ranging = 1; - legacy_request->enable_ranging = hidl_request2.enableRanging; + legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; + + return true; +} + +bool convertHidlNanEnableRequest_1_5ToLegacy( + const V1_4::NanEnableRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) + << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request"; + return false; + } + + *legacy_request = {}; + if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2, + legacy_request)) { + return false; + } + + legacy_request->config_enable_instant_mode = 1; + legacy_request->enable_instant_mode = + hidl_request2.enableInstantCommunicationMode; + + return true; +} + +bool convertHidlNanConfigRequest_1_5ToLegacy( + const V1_4::NanConfigRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) + << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request"; + return false; + } + + *legacy_request = {}; + if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2, + legacy_request)) { + return false; + } + + legacy_request->config_enable_instant_mode = 1; + legacy_request->enable_instant_mode = + hidl_request2.enableInstantCommunicationMode; return true; } @@ -1794,7 +1840,7 @@ bool convertHidlNanConfigRequestToLegacy( bool convertHidlNanConfigRequest_1_4ToLegacy( const V1_4::NanConfigRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request " @@ -1809,14 +1855,14 @@ bool convertHidlNanConfigRequest_1_4ToLegacy( legacy_request->config_discovery_beacon_int = 1; legacy_request->discovery_beacon_interval = - hidl_request2.discoveryBeaconIntervalMs; + hidl_request2.V1_2.discoveryBeaconIntervalMs; legacy_request->config_nss = 1; - legacy_request->nss = hidl_request2.numberOfSpatialStreamsInDiscovery; + legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; legacy_request->config_dw_early_termination = 1; legacy_request->enable_dw_termination = - hidl_request2.enableDiscoveryWindowEarlyTermination; + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; legacy_request->config_enable_ranging = 1; - legacy_request->enable_ranging = hidl_request2.enableRanging; + legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; return true; } @@ -2023,27 +2069,31 @@ bool convertLegacyNanCapabilitiesResponseToHidl( } *hidl_response = {}; - hidl_response->maxConcurrentClusters = + hidl_response->V1_0.maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters; - hidl_response->maxPublishes = legacy_response.max_publishes; - hidl_response->maxSubscribes = legacy_response.max_subscribes; - hidl_response->maxServiceNameLen = legacy_response.max_service_name_len; - hidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len; - hidl_response->maxTotalMatchFilterLen = + hidl_response->V1_0.maxPublishes = legacy_response.max_publishes; + hidl_response->V1_0.maxSubscribes = legacy_response.max_subscribes; + hidl_response->V1_0.maxServiceNameLen = + legacy_response.max_service_name_len; + hidl_response->V1_0.maxMatchFilterLen = + legacy_response.max_match_filter_len; + hidl_response->V1_0.maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len; - hidl_response->maxServiceSpecificInfoLen = + hidl_response->V1_0.maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len; - hidl_response->maxExtendedServiceSpecificInfoLen = + hidl_response->V1_0.maxExtendedServiceSpecificInfoLen = legacy_response.max_sdea_service_specific_info_len; - hidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces; - hidl_response->maxNdpSessions = legacy_response.max_ndp_sessions; - hidl_response->maxAppInfoLen = legacy_response.max_app_info_len; - hidl_response->maxQueuedTransmitFollowupMsgs = + hidl_response->V1_0.maxNdiInterfaces = legacy_response.max_ndi_interfaces; + hidl_response->V1_0.maxNdpSessions = legacy_response.max_ndp_sessions; + hidl_response->V1_0.maxAppInfoLen = legacy_response.max_app_info_len; + hidl_response->V1_0.maxQueuedTransmitFollowupMsgs = legacy_response.max_queued_transmit_followup_msgs; - hidl_response->maxSubscribeInterfaceAddresses = + hidl_response->V1_0.maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address; - hidl_response->supportedCipherSuites = + hidl_response->V1_0.supportedCipherSuites = legacy_response.cipher_suites_supported; + hidl_response->instantCommunicationModeSupportFlag = + legacy_response.is_instant_mode_supported; return true; } diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index c6dc692367..b0b1d22dfe 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "wifi_legacy_hal.h" @@ -122,11 +123,19 @@ bool convertHidlNanConfigRequestToLegacy( legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanEnableRequest_1_4ToLegacy( const V1_4::NanEnableRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request); bool convertHidlNanConfigRequest_1_4ToLegacy( const V1_4::NanConfigRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanEnableRequest_1_5ToLegacy( + const V1_4::NanEnableRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequest_1_5ToLegacy( + const V1_4::NanConfigRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanPublishRequestToLegacy( const NanPublishRequest& hidl_request, diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp index 411190b01a..52f0c2bcde 100644 --- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp @@ -41,7 +41,6 @@ namespace wifi { namespace V1_5 { namespace implementation { -using android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback; using android::hardware::wifi::V1_2::NanDataPathConfirmInd; bool CaptureIfaceEventHandlers( @@ -56,9 +55,10 @@ class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { public: MockNanIfaceEventCallback() = default; - MOCK_METHOD3(notifyCapabilitiesResponse, - Return(uint16_t, const WifiNanStatus&, - const NanCapabilities&)); + MOCK_METHOD3( + notifyCapabilitiesResponse, + Return(uint16_t, const WifiNanStatus&, + const android::hardware::wifi::V1_0::NanCapabilities&)); MOCK_METHOD2(notifyEnableResponse, Return(uint16_t, const WifiNanStatus&)); MOCK_METHOD2(notifyConfigResponse, @@ -108,6 +108,9 @@ class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { Return(const NanDataPathConfirmInd&)); MOCK_METHOD1(eventDataPathScheduleUpdate, Return(const NanDataPathScheduleUpdateInd&)); + MOCK_METHOD3(notifyCapabilitiesResponse_1_5, + Return(uint16_t, const WifiNanStatus&, + const NanCapabilities&)); }; class WifiNanIfaceTest : public Test { diff --git a/wifi/1.5/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp index e2b0332a22..0cc6cd5fce 100644 --- a/wifi/1.5/default/wifi_nan_iface.cpp +++ b/wifi/1.5/default/wifi_nan_iface.cpp @@ -166,10 +166,10 @@ WifiNanIface::WifiNanIface( return; } for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { + shared_ptr_this->getEventCallbacks_1_5()) { if (!callback - ->notifyCapabilitiesResponse(id, wifiNanStatus, - hidl_struct) + ->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, + hidl_struct) .isOk()) { LOG(ERROR) << "Failed to invoke the callback"; } @@ -545,6 +545,7 @@ void WifiNanIface::invalidate() { legacy_hal_.reset(); event_cb_handler_.invalidate(); event_cb_handler_1_2_.invalidate(); + event_cb_handler_1_5_.invalidate(); is_valid_ = false; if (is_dedicated_iface_) { // If using a dedicated iface, set the iface down. @@ -566,6 +567,10 @@ WifiNanIface::getEventCallbacks_1_2() { return event_cb_handler_1_2_.getCallbacks(); } +std::set> WifiNanIface::getEventCallbacks_1_5() { + return event_cb_handler_1_5_.getCallbacks(); +} + Return WifiNanIface::getName(getName_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiNanIface::getNameInternal, hidl_status_cb); @@ -738,6 +743,39 @@ Return WifiNanIface::configRequest_1_4( hidl_status_cb, cmd_id, msg1, msg2); } +Return WifiNanIface::registerEventCallback_1_5( + const sp& callback, + registerEventCallback_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallback_1_5Internal, + hidl_status_cb, callback); +} + +Return WifiNanIface::enableRequest_1_5( + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const NanConfigRequestSupplemental& msg2, + enableRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_5Internal, + hidl_status_cb, cmd_id, msg1, msg2); +} + +Return WifiNanIface::configRequest_1_5( + uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const NanConfigRequestSupplemental& msg2, + configRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_5Internal, + hidl_status_cb, cmd_id, msg1, msg2); +} + +Return WifiNanIface::getCapabilitiesRequest_1_5( + uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getCapabilitiesRequest_1_5Internal, + hidl_status_cb, cmd_id); +} + std::pair WifiNanIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -754,10 +792,8 @@ WifiStatus WifiNanIface::registerEventCallbackInternal( return createWifiStatus(WifiStatusCode::SUCCESS); } -WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); +WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } WifiStatus WifiNanIface::enableRequestInternal( @@ -890,7 +926,7 @@ WifiStatus WifiNanIface::registerEventCallback_1_2Internal( WifiStatus WifiNanIface::enableRequest_1_2Internal( uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /*msg2 */) { + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } @@ -901,10 +937,44 @@ WifiStatus WifiNanIface::configRequest_1_2Internal( } WifiStatus WifiNanIface::enableRequest_1_4Internal( + uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequest_1_4Internal( + uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::registerEventCallback_1_5Internal( + const sp& callback) { + sp callback_1_0 = callback; + if (!event_cb_handler_.addCallback(callback_1_0)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + sp callback_1_2 = callback; + if (!event_cb_handler_1_2_.addCallback(callback_1_2)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + if (!event_cb_handler_1_5_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::enableRequest_1_5Internal( uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2) { + const NanConfigRequestSupplemental& msg2) { legacy_hal::NanEnableRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanEnableRequest_1_4ToLegacy( + if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy( msg1, msg2, &legacy_msg)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } @@ -913,11 +983,11 @@ WifiStatus WifiNanIface::enableRequest_1_4Internal( return createWifiStatusFromLegacyError(legacy_status); } -WifiStatus WifiNanIface::configRequest_1_4Internal( +WifiStatus WifiNanIface::configRequest_1_5Internal( uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2) { + const NanConfigRequestSupplemental& msg2) { legacy_hal::NanConfigRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanConfigRequest_1_4ToLegacy( + if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy( msg1, msg2, &legacy_msg)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } diff --git a/wifi/1.5/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h index efdb2da65e..fb9c047ff6 100644 --- a/wifi/1.5/default/wifi_nan_iface.h +++ b/wifi/1.5/default/wifi_nan_iface.h @@ -18,8 +18,8 @@ #define WIFI_NAN_IFACE_H_ #include -#include -#include +#include +#include #include "hidl_callback_util.h" #include "wifi_iface_util.h" @@ -36,7 +36,7 @@ using namespace android::hardware::wifi::V1_2; /** * HIDL interface object used to control a NAN Iface instance. */ -class WifiNanIface : public V1_4::IWifiNanIface { +class WifiNanIface : public V1_5::IWifiNanIface { public: WifiNanIface(const std::string& ifname, bool is_dedicated_iface, const std::weak_ptr legacy_hal, @@ -112,6 +112,19 @@ class WifiNanIface : public V1_4::IWifiNanIface { uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2, configRequest_1_4_cb hidl_status_cb) override; + Return registerEventCallback_1_5( + const sp& callback, + registerEventCallback_1_5_cb hidl_status_cb) override; + Return enableRequest_1_5( + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) override; + Return configRequest_1_5( + uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) override; + Return getCapabilitiesRequest_1_5( + uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -158,11 +171,22 @@ class WifiNanIface : public V1_4::IWifiNanIface { WifiStatus configRequest_1_4Internal( uint16_t cmd_id, const V1_4::NanConfigRequest& msg, const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus registerEventCallback_1_5Internal( + const sp& callback); + WifiStatus enableRequest_1_5Internal( + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_5Internal( + uint16_t cmd_id, const V1_4::NanConfigRequest& msg, + const NanConfigRequestSupplemental& msg2); + WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id); // all 1_0 and descendant callbacks std::set> getEventCallbacks(); // all 1_2 and descendant callbacks std::set> getEventCallbacks_1_2(); + // all 1_5 and descendant callbacks + std::set> getEventCallbacks_1_5(); std::string ifname_; bool is_dedicated_iface_; @@ -173,6 +197,8 @@ class WifiNanIface : public V1_4::IWifiNanIface { event_cb_handler_; hidl_callback_util::HidlCallbackHandler event_cb_handler_1_2_; + hidl_callback_util::HidlCallbackHandler + event_cb_handler_1_5_; DISALLOW_COPY_AND_ASSIGN(WifiNanIface); }; diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 71f0679ed9..5873f79b3b 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -17,6 +17,9 @@ package android.hardware.wifi@1.5; import @1.0::WifiBand; +import @1.0::NanCipherSuiteType; +import @1.0::NanCapabilities; +import @1.2::NanConfigRequestSupplemental; /** * Wifi bands defined in 80211 spec. @@ -35,3 +38,32 @@ enum WifiBand : @1.0::WifiBand { */ BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31, }; + +/** + * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous + * versions. + */ +struct NanConfigRequestSupplemental { + /** + * Baseline information as defined in HAL 1.2. + */ + @1.2::NanConfigRequestSupplemental V1_2; + /** + * Controls whether NAN instant communication mode is enabled. + */ + bool enableInstantCommunicationMode; +}; + +/** + * NDP Capabilities response. + */ +struct NanCapabilities { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::NanCapabilities V1_0; + /** + * Flag to indicate id instant communication mode is supported. + */ + bool instantCommunicationModeSupportFlag; +}; \ No newline at end of file diff --git a/wifi/1.5/vts/OWNERS b/wifi/1.5/vts/OWNERS new file mode 100644 index 0000000000..8bfb14882c --- /dev/null +++ b/wifi/1.5/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp new file mode 100644 index 0000000000..a7ba498103 --- /dev/null +++ b/wifi/1.5/vts/functional/Android.bp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// These tests are split out so that they can be conditioned on presence of the +// "android.hardware.wifi.aware" feature. +cc_test { + name: "VtsHalWifiNanV1_5TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "wifi_nan_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp new file mode 100644 index 0000000000..803d39df15 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -0,0 +1,628 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Nanache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using namespace ::android::hardware::wifi::V1_0; +using namespace ::android::hardware::wifi::V1_2; +using namespace ::android::hardware::wifi::V1_4; +using namespace ::android::hardware::wifi::V1_5; + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; + +#define TIMEOUT_PERIOD 10 + +android::sp getWifiNanIface_1_5( + const std::string& instance_name) { + return android::hardware::wifi::V1_5::IWifiNanIface::castFrom( + getWifiNanIface(instance_name)); +} + +/** + * Fixture to use for all NAN Iface HIDL interface tests. + */ +class WifiNanIfaceHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) + GTEST_SKIP() << "Skipping this test since NAN is not supported."; + // Make sure to start with a clean state + stopWifi(GetInstanceName()); + + iwifiNanIface = getWifiNanIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, iwifiNanIface.get()); + ASSERT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_5, + new WifiNanIfaceEventCallback(*this)) + .code); + } + + virtual void TearDown() override { stopWifi(GetInstanceName()); } + + /* Used as a mechanism to inform the test about data/event callback */ + inline void notify() { + std::unique_lock lock(mtx_); + count_++; + cv_.notify_one(); + } + + enum CallbackType { + INVALID = -2, + ANY_CALLBACK = -1, + + NOTIFY_CAPABILITIES_RESPONSE = 0, + NOTIFY_ENABLE_RESPONSE, + NOTIFY_CONFIG_RESPONSE, + NOTIFY_DISABLE_RESPONSE, + NOTIFY_START_PUBLISH_RESPONSE, + NOTIFY_STOP_PUBLISH_RESPONSE, + NOTIFY_START_SUBSCRIBE_RESPONSE, + NOTIFY_STOP_SUBSCRIBE_RESPONSE, + NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE, + NOTIFY_CREATE_DATA_INTERFACE_RESPONSE, + NOTIFY_DELETE_DATA_INTERFACE_RESPONSE, + NOTIFY_INITIATE_DATA_PATH_RESPONSE, + NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE, + NOTIFY_TERMINATE_DATA_PATH_RESPONSE, + NOTIFY_CAPABILITIES_RESPONSE_1_5, + + EVENT_CLUSTER_EVENT, + EVENT_DISABLED, + EVENT_PUBLISH_TERMINATED, + EVENT_SUBSCRIBE_TERMINATED, + EVENT_MATCH, + EVENT_MATCH_EXPIRED, + EVENT_FOLLOWUP_RECEIVED, + EVENT_TRANSMIT_FOLLOWUP, + EVENT_DATA_PATH_REQUEST, + EVENT_DATA_PATH_CONFIRM, + EVENT_DATA_PATH_TERMINATED, + EVENT_DATA_PATH_CONFIRM_1_2, + EVENT_DATA_PATH_SCHEDULE_UPDATE + }; + + /* Test code calls this function to wait for data/event callback */ + /* Must set callbackType = INVALID before call this function */ + inline std::cv_status wait(CallbackType waitForCallbackType) { + std::unique_lock lock(mtx_); + + EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a + // non-void-returning method + + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count_ == 0) { + status = cv_.wait_until(lock, + now + std::chrono::seconds(TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) return status; + if (waitForCallbackType != ANY_CALLBACK && + callbackType != INVALID && + callbackType != waitForCallbackType) { + count_--; + } + } + count_--; + return status; + } + + class WifiNanIfaceEventCallback + : public ::android::hardware::wifi::V1_5::IWifiNanIfaceEventCallback { + WifiNanIfaceHidlTest& parent_; + + public: + WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent) + : parent_(parent){}; + + virtual ~WifiNanIfaceEventCallback() = default; + + Return notifyCapabilitiesResponse( + uint16_t id, const WifiNanStatus& status, + const ::android::hardware::wifi::V1_0::NanCapabilities& + capabilities) override { + parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.capabilities = capabilities; + + parent_.notify(); + return Void(); + } + + Return notifyCapabilitiesResponse_1_5( + uint16_t id, const WifiNanStatus& status, + const ::android::hardware::wifi::V1_5::NanCapabilities& + capabilities) override { + parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE_1_5; + + parent_.id = id; + parent_.status = status; + parent_.capabilities_1_5 = capabilities; + + parent_.notify(); + return Void(); + } + + Return notifyEnableResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_ENABLE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyConfigResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_CONFIG_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyDisableResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_DISABLE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyStartPublishResponse(uint16_t id, + const WifiNanStatus& status, + uint8_t sessionId) override { + parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.sessionId = sessionId; + + parent_.notify(); + return Void(); + } + + Return notifyStopPublishResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyStartSubscribeResponse(uint16_t id, + const WifiNanStatus& status, + uint8_t sessionId) override { + parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.sessionId = sessionId; + + parent_.notify(); + return Void(); + } + + Return notifyStopSubscribeResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyTransmitFollowupResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyCreateDataInterfaceResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyDeleteDataInterfaceResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyInitiateDataPathResponse( + uint16_t id, const WifiNanStatus& status, + uint32_t ndpInstanceId) override { + parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.ndpInstanceId = ndpInstanceId; + + parent_.notify(); + return Void(); + } + + Return notifyRespondToDataPathIndicationResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = + NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyTerminateDataPathResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventClusterEvent( + const NanClusterEventInd& event) override { + parent_.callbackType = EVENT_CLUSTER_EVENT; + + parent_.nanClusterEventInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDisabled(const WifiNanStatus& status) override { + parent_.callbackType = EVENT_DISABLED; + + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventPublishTerminated( + uint8_t sessionId, const WifiNanStatus& status) override { + parent_.callbackType = EVENT_PUBLISH_TERMINATED; + + parent_.sessionId = sessionId; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventSubscribeTerminated( + uint8_t sessionId, const WifiNanStatus& status) override { + parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED; + + parent_.sessionId = sessionId; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventMatch(const NanMatchInd& event) override { + parent_.callbackType = EVENT_MATCH; + + parent_.nanMatchInd = event; + + parent_.notify(); + return Void(); + } + + Return eventMatchExpired(uint8_t discoverySessionId, + uint32_t peerId) override { + parent_.callbackType = EVENT_MATCH_EXPIRED; + + parent_.sessionId = discoverySessionId; + parent_.peerId = peerId; + + parent_.notify(); + return Void(); + } + + Return eventFollowupReceived( + const NanFollowupReceivedInd& event) override { + parent_.callbackType = EVENT_FOLLOWUP_RECEIVED; + + parent_.nanFollowupReceivedInd = event; + + parent_.notify(); + return Void(); + } + + Return eventTransmitFollowup( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventDataPathRequest( + const NanDataPathRequestInd& event) override { + parent_.callbackType = EVENT_DATA_PATH_REQUEST; + + parent_.nanDataPathRequestInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathConfirm( + const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event) + override { + parent_.callbackType = EVENT_DATA_PATH_CONFIRM; + + parent_.nanDataPathConfirmInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathTerminated(uint32_t ndpInstanceId) override { + parent_.callbackType = EVENT_DATA_PATH_TERMINATED; + + parent_.ndpInstanceId = ndpInstanceId; + + parent_.notify(); + return Void(); + } + + Return eventDataPathConfirm_1_2( + const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event) + override { + parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2; + + parent_.nanDataPathConfirmInd_1_2 = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathScheduleUpdate( + const NanDataPathScheduleUpdateInd& event) override { + parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE; + + parent_.nanDataPathScheduleUpdateInd = event; + + parent_.notify(); + return Void(); + } + }; + + private: + // synchronization objects + std::mutex mtx_; + std::condition_variable cv_; + int count_ = 0; + + protected: + android::sp<::android::hardware::wifi::V1_5::IWifiNanIface> iwifiNanIface; + + // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of + // all arguments to all callbacks. They are set by the callback + // (notifications or events) and can be retrieved by tests. + CallbackType callbackType; + uint16_t id; + WifiNanStatus status; + uint8_t sessionId; + uint32_t ndpInstanceId; + NanClusterEventInd nanClusterEventInd; + NanMatchInd nanMatchInd; + uint32_t peerId; + NanFollowupReceivedInd nanFollowupReceivedInd; + NanDataPathRequestInd nanDataPathRequestInd; + ::android::hardware::wifi::V1_0::NanCapabilities capabilities; + ::android::hardware::wifi::V1_5::NanCapabilities capabilities_1_5; + ::android::hardware::wifi::V1_0::NanDataPathConfirmInd + nanDataPathConfirmInd; + ::android::hardware::wifi::V1_2::NanDataPathConfirmInd + nanDataPathConfirmInd_1_2; + NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd; + + std::string GetInstanceName() { return GetParam(); } +}; + +/* + * Create: + * Ensures that an instance of the IWifiNanIface proxy object is + * successfully created. + */ +TEST_P(WifiNanIfaceHidlTest, Create) { + // The creation of a proxy object is tested as part of SetUp method. +} + +/* + * enableRequest_1_5InvalidArgs: validate that fails with invalid arguments + */ +TEST_P(WifiNanIfaceHidlTest, enableRequest_1_5InvalidArgs) { + uint16_t inputCmdId = 10; + callbackType = INVALID; + ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {}; + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, enableRequest_1_5, inputCmdId, + nanEnableRequest, nanConfigRequestSupp); + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code); + + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE)); + ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType); + ASSERT_EQ(id, inputCmdId); + ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS); + } +} + +/* + * enableRequest_1_5ShimInvalidArgs: validate that fails with invalid arguments + * to the shim + */ +TEST_P(WifiNanIfaceHidlTest, enableRequest_1_5ShimInvalidArgs) { + uint16_t inputCmdId = 10; + ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {}; + nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = + 128; // must be <= 127 + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, enableRequest_1_5, inputCmdId, + nanEnableRequest, nanConfigRequestSupp); + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code); + } +} + +/* + * configRequest_1_5InvalidArgs: validate that fails with invalid arguments + */ +TEST_P(WifiNanIfaceHidlTest, configRequest_1_5InvalidArgs) { + uint16_t inputCmdId = 10; + callbackType = INVALID; + ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, configRequest_1_5, inputCmdId, + nanConfigRequest, nanConfigRequestSupp); + + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code); + + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE)); + ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType); + ASSERT_EQ(id, inputCmdId); + ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS); + } +} + +/* + * configRequest_1_5ShimInvalidArgs: validate that fails with invalid arguments + * to the shim + */ +TEST_P(WifiNanIfaceHidlTest, configRequest_1_5ShimInvalidArgs) { + uint16_t inputCmdId = 10; + ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; + nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127 + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, configRequest_1_5, inputCmdId, + nanConfigRequest, nanConfigRequestSupp); + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code); + } +} + +/* + * getCapabilitiesRequest: validate that returns capabilities. + */ +TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest_1_5) { + uint16_t inputCmdId = 10; + callbackType = INVALID; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest_1_5, inputCmdId).code; + ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus); + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, + wait(NOTIFY_CAPABILITIES_RESPONSE_1_5)); + ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE_1_5, callbackType); + ASSERT_EQ(id, inputCmdId); + + // check for reasonable capability values + EXPECT_GT(capabilities_1_5.V1_0.maxConcurrentClusters, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxPublishes, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxSubscribes, (unsigned int)0); + EXPECT_EQ(capabilities_1_5.V1_0.maxServiceNameLen, (unsigned int)255); + EXPECT_EQ(capabilities_1_5.V1_0.maxMatchFilterLen, (unsigned int)255); + EXPECT_GT(capabilities_1_5.V1_0.maxTotalMatchFilterLen, (unsigned int)255); + EXPECT_EQ(capabilities_1_5.V1_0.maxServiceSpecificInfoLen, + (unsigned int)255); + EXPECT_GE(capabilities_1_5.V1_0.maxExtendedServiceSpecificInfoLen, + (unsigned int)255); + EXPECT_GT(capabilities_1_5.V1_0.maxNdiInterfaces, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxNdpSessions, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxAppInfoLen, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxQueuedTransmitFollowupMsgs, + (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxSubscribeInterfaceAddresses, + (unsigned int)0); + EXPECT_NE(capabilities_1_5.V1_0.supportedCipherSuites, (unsigned int)0); + EXPECT_TRUE(capabilities_1_5.instantCommunicationModeSupportFlag || + !capabilities_1_5.instantCommunicationModeSupportFlag); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WifiNanIfaceHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ::android::hardware::wifi::V1_5::IWifi::descriptor)), + android::hardware::PrintInstanceNameToString);