diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp index 14ea5b1b20..100b36bfdb 100644 --- a/wifi/1.2/Android.bp +++ b/wifi/1.2/Android.bp @@ -11,6 +11,7 @@ hidl_interface { "IWifi.hal", "IWifiChip.hal", "IWifiNanIface.hal", + "IWifiNanIfaceEventCallback.hal", ], interfaces: [ "android.hardware.wifi@1.0", @@ -19,6 +20,9 @@ hidl_interface { ], types: [ "NanConfigRequestSupplemental", + "NanDataPathChannelInfo", + "NanDataPathConfirmInd", + "NanDataPathScheduleUpdateInd", ], gen_java: true, } diff --git a/wifi/1.2/IWifiNanIface.hal b/wifi/1.2/IWifiNanIface.hal index 7f7b4d0616..0260162ddf 100644 --- a/wifi/1.2/IWifiNanIface.hal +++ b/wifi/1.2/IWifiNanIface.hal @@ -21,6 +21,7 @@ import @1.0::IWifiNanIface; import @1.0::NanConfigRequest; import @1.0::NanEnableRequest; import @1.0::WifiStatus; +import IWifiNanIfaceEventCallback; /** * Interface used to represent a single NAN (Neighbour Aware Network) iface. @@ -29,6 +30,24 @@ import @1.0::WifiStatus; * Networking (NAN) Technical Specification". */ interface IWifiNanIface extends @1.0::IWifiNanIface { + /** + * 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.0::IWifiNanIface.registerEventCallback() method which is deprecated + * as of HAL version 1.2. + * + * @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_2(IWifiNanIfaceEventCallback callback) + generates (WifiStatus status); + /** * Enable NAN: configures and activates NAN clustering (does not start * a discovery session or set up data-interfaces or data-paths). Use the diff --git a/wifi/1.2/IWifiNanIfaceEventCallback.hal b/wifi/1.2/IWifiNanIfaceEventCallback.hal new file mode 100644 index 0000000000..efd5479a1b --- /dev/null +++ b/wifi/1.2/IWifiNanIfaceEventCallback.hal @@ -0,0 +1,46 @@ +/* + * Copyright 2017 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.2; + +import @1.0::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.0::IWifiNanIfaceEventCallback { + /** + * Asynchronous callback indicating a data-path (NDP) setup has been completed: received by + * both Initiator and Responder. + * + * Note: supersedes the @1.0::IWifiNanIfaceEventCallback.eventDataPathConfirm() method which is + * deprecated as of HAL version 1.2. + * + * @param event: NanDataPathConfirmInd containing event details. + */ + oneway eventDataPathConfirm_1_2(NanDataPathConfirmInd event); + + /** + * Asynchronous callback indicating a data-path (NDP) schedule has been updated (e.g. channels + * have been changed). + * + * @param event: NanDataPathScheduleUpdateInd containing event details. + */ + oneway eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event); +}; \ No newline at end of file diff --git a/wifi/1.2/default/hidl_struct_util.cpp b/wifi/1.2/default/hidl_struct_util.cpp index b1b6f641eb..3ca35f73b2 100644 --- a/wifi/1.2/default/hidl_struct_util.cpp +++ b/wifi/1.2/default/hidl_struct_util.cpp @@ -1956,6 +1956,22 @@ bool convertLegacyNanDataPathRequestIndToHidl( return true; } +bool convertLegacyNdpChannelInfoToHidl( + const legacy_hal::NanChannelInfo& legacy_struct, + NanDataPathChannelInfo* hidl_struct) { + if (!hidl_struct) { + LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null"; + return false; + } + *hidl_struct = {}; + + hidl_struct->channelFreq = legacy_struct.channel; + hidl_struct->channelBandwidth = legacy_struct.bandwidth; + hidl_struct->numSpatialStreams = legacy_struct.nss; + + return true; +} + bool convertLegacyNanDataPathConfirmIndToHidl( const legacy_hal::NanDataPathConfirmInd& legacy_ind, NanDataPathConfirmInd* hidl_ind) { @@ -1966,18 +1982,60 @@ bool convertLegacyNanDataPathConfirmIndToHidl( } *hidl_ind = {}; - hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id; - hidl_ind->dataPathSetupSuccess = + hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id; + hidl_ind->V1_0.dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT; - hidl_ind->peerNdiMacAddr = + hidl_ind->V1_0.peerNdiMacAddr = hidl_array(legacy_ind.peer_ndi_mac_addr); - hidl_ind->appInfo = + hidl_ind->V1_0.appInfo = std::vector(legacy_ind.app_info.ndp_app_info, legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len); - hidl_ind->status.status = + hidl_ind->V1_0.status.status = convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code); - hidl_ind->status.description = ""; // TODO: b/34059183 + hidl_ind->V1_0.status.description = ""; // TODO: b/34059183 + + std::vector channelInfo; + for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { + NanDataPathChannelInfo hidl_struct; + if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], + &hidl_struct)) { + return false; + } + channelInfo.push_back(hidl_struct); + } + hidl_ind->channelInfo = channelInfo; + + return true; +} + +bool convertLegacyNanDataPathScheduleUpdateIndToHidl( + const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, + NanDataPathScheduleUpdateInd* hidl_ind) { + if (!hidl_ind) { + LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: " + "hidl_ind is null"; + return false; + } + *hidl_ind = {}; + + hidl_ind->peerDiscoveryAddress = + hidl_array(legacy_ind.peer_mac_addr); + std::vector channelInfo; + for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { + NanDataPathChannelInfo hidl_struct; + if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], + &hidl_struct)) { + return false; + } + channelInfo.push_back(hidl_struct); + } + hidl_ind->channelInfo = channelInfo; + std::vector ndpInstanceIds; + for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) { + ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]); + } + hidl_ind->ndpInstanceIds = ndpInstanceIds; return true; } diff --git a/wifi/1.2/default/hidl_struct_util.h b/wifi/1.2/default/hidl_struct_util.h index e44ab7dfd9..1208afd0a8 100644 --- a/wifi/1.2/default/hidl_struct_util.h +++ b/wifi/1.2/default/hidl_struct_util.h @@ -147,6 +147,9 @@ bool convertLegacyNanDataPathRequestIndToHidl( bool convertLegacyNanDataPathConfirmIndToHidl( const legacy_hal::NanDataPathConfirmInd& legacy_ind, NanDataPathConfirmInd* hidl_ind); +bool convertLegacyNanDataPathScheduleUpdateIndToHidl( + const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, + NanDataPathScheduleUpdateInd* hidl_ind); // RTT controller conversion methods. bool convertHidlVectorOfRttConfigToLegacy( diff --git a/wifi/1.2/default/wifi_nan_iface.cpp b/wifi/1.2/default/wifi_nan_iface.cpp index e93e6bee21..535e3d3d0c 100644 --- a/wifi/1.2/default/wifi_nan_iface.cpp +++ b/wifi/1.2/default/wifi_nan_iface.cpp @@ -428,7 +428,7 @@ WifiNanIface::WifiNanIface( } for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDataPathConfirm(hidl_struct).isOk()) { + if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) { LOG(ERROR) << "Failed to invoke the callback"; } } @@ -467,10 +467,28 @@ WifiNanIface::WifiNanIface( LOG(ERROR) << "on_event_range_report - should not be called"; }; - callback_handlers.on_event_schedule_update = - [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& /* msg */) { - LOG(ERROR) << "on_event_schedule_update - should not be called"; - }; + callback_handlers + .on_event_schedule_update = [weak_ptr_this]( + const legacy_hal:: + NanDataPathScheduleUpdateInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanDataPathScheduleUpdateInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl( + msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, @@ -511,7 +529,7 @@ Return WifiNanIface::getType(getType_cb hidl_status_cb) { } Return WifiNanIface::registerEventCallback( - const sp& callback, + const sp& callback, registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiNanIface::registerEventCallbackInternal, @@ -628,6 +646,14 @@ Return WifiNanIface::terminateDataPathRequest( hidl_status_cb, cmd_id, ndpInstanceId); } +Return WifiNanIface::registerEventCallback_1_2( + const sp& callback, + registerEventCallback_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallback_1_2Internal, + hidl_status_cb, callback); +} + Return WifiNanIface::enableRequest_1_2( uint16_t cmd_id, const NanEnableRequest& msg1, const NanConfigRequestSupplemental& msg2, @@ -655,11 +681,8 @@ std::pair WifiNanIface::getTypeInternal() { } WifiStatus WifiNanIface::registerEventCallbackInternal( - const sp& callback) { - if (!event_cb_handler_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); + const sp& /*callback*/) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t cmd_id) { @@ -784,6 +807,14 @@ WifiStatus WifiNanIface::terminateDataPathRequestInternal( return createWifiStatusFromLegacyError(legacy_status); } +WifiStatus WifiNanIface::registerEventCallback_1_2Internal( + const sp& callback) { + if (!event_cb_handler_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + WifiStatus WifiNanIface::enableRequest_1_2Internal( uint16_t cmd_id, const NanEnableRequest& msg1, const NanConfigRequestSupplemental& msg2) { diff --git a/wifi/1.2/default/wifi_nan_iface.h b/wifi/1.2/default/wifi_nan_iface.h index 2ded3a8112..a2dcf3a52e 100644 --- a/wifi/1.2/default/wifi_nan_iface.h +++ b/wifi/1.2/default/wifi_nan_iface.h @@ -47,7 +47,7 @@ class WifiNanIface : public V1_2::IWifiNanIface { Return getName(getName_cb hidl_status_cb) override; Return getType(getType_cb hidl_status_cb) override; Return registerEventCallback( - const sp& callback, + const sp& callback, registerEventCallback_cb hidl_status_cb) override; Return getCapabilitiesRequest( uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; @@ -88,6 +88,9 @@ class WifiNanIface : public V1_2::IWifiNanIface { uint16_t cmd_id, uint32_t ndpInstanceId, terminateDataPathRequest_cb hidl_status_cb) override; + Return registerEventCallback_1_2( + const sp& callback, + registerEventCallback_1_2_cb hidl_status_cb) override; Return enableRequest_1_2( uint16_t cmd_id, const NanEnableRequest& msg1, const NanConfigRequestSupplemental& msg2, @@ -102,7 +105,7 @@ class WifiNanIface : public V1_2::IWifiNanIface { std::pair getNameInternal(); std::pair getTypeInternal(); WifiStatus registerEventCallbackInternal( - const sp& callback); + const sp& callback); WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id); WifiStatus enableRequestInternal(uint16_t cmd_id, const NanEnableRequest& msg); @@ -128,6 +131,8 @@ class WifiNanIface : public V1_2::IWifiNanIface { WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId); + WifiStatus registerEventCallback_1_2Internal( + const sp& callback); WifiStatus enableRequest_1_2Internal( uint16_t cmd_id, const NanEnableRequest& msg1, const NanConfigRequestSupplemental& msg2); diff --git a/wifi/1.2/types.hal b/wifi/1.2/types.hal index 9151295db4..60f4b1f169 100644 --- a/wifi/1.2/types.hal +++ b/wifi/1.2/types.hal @@ -16,6 +16,10 @@ package android.hardware.wifi@1.2; +import @1.0::MacAddress; +import @1.0::NanDataPathConfirmInd; +import @1.0::WifiChannelInMhz; + /** * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous * versions. @@ -47,3 +51,60 @@ struct NanConfigRequestSupplemental { bool enableDiscoveryWindowEarlyTermination; }; +/** + * NAN data path channel information provided to the framework. + */ +struct NanDataPathChannelInfo { + /** + * Channel frequency in MHz. + */ + WifiChannelInMhz channelFreq; + /** + * Channel bandwidth in MHz. + */ + uint32_t channelBandwidth; + /** + * Number of spatial streams used in the channel. + */ + uint32_t numSpatialStreams; +}; + +/** + * NAN Data path confirmation Indication structure. + * Event indication is received on both initiator and responder side when negotiation for a + * data-path finish: on success or failure. + */ +struct NanDataPathConfirmInd { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::NanDataPathConfirmInd V1_0; + /** + * The channel(s) on which the NDP is scheduled to operate. + * Updates to the operational channels are provided using the |eventDataPathScheduleUpdate| + * event. + */ + vec channelInfo; +}; + +/** + * NAN data path channel information update indication structure. + * Event indication is received by all NDP owners whenever the channels on which the NDP operates + * are updated. + * Note: multiple NDPs may share the same schedule, the indication specifies all NDPs to which it + * applies. + */ +struct NanDataPathScheduleUpdateInd { + /** + * The discovery address (NMI) of the peer to which the NDP is connected. + */ + MacAddress peerDiscoveryAddress; + /** + * The updated channel(s) information. + */ + vec channelInfo; + /** + * The list of NDPs to which this update applies. + */ + vec ndpInstanceIds; +};