[AWARE] Add NDP channel info to HAL 1.2
Enhance HAL 1.2 to include NDP channel info:
- NDP confirmation message update
- New event (indication) on NDP channel change
Results in a new event callback registration API.
Bug: 37007030
Test: integration tests
Change-Id: If9dee4eca9d6774b03fc295ad239a6a4e7397cba
diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp
index 14ea5b1..100b36b 100644
--- a/wifi/1.2/Android.bp
+++ b/wifi/1.2/Android.bp
@@ -11,6 +11,7 @@
"IWifi.hal",
"IWifiChip.hal",
"IWifiNanIface.hal",
+ "IWifiNanIfaceEventCallback.hal",
],
interfaces: [
"android.hardware.wifi@1.0",
@@ -19,6 +20,9 @@
],
types: [
"NanConfigRequestSupplemental",
+ "NanDataPathChannelInfo",
+ "NanDataPathConfirmInd",
+ "NanDataPathScheduleUpdateInd",
],
gen_java: true,
}
diff --git a/wifi/1.2/IWifiNanIface.hal b/wifi/1.2/IWifiNanIface.hal
index 7f7b4d0..0260162 100644
--- a/wifi/1.2/IWifiNanIface.hal
+++ b/wifi/1.2/IWifiNanIface.hal
@@ -21,6 +21,7 @@
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.
@@ -30,6 +31,24 @@
*/
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
* |IWifiNanIface.configureRequest| method to change the configuration of an already enabled
diff --git a/wifi/1.2/IWifiNanIfaceEventCallback.hal b/wifi/1.2/IWifiNanIfaceEventCallback.hal
new file mode 100644
index 0000000..efd5479
--- /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 b1b6f64..3ca35f7 100644
--- a/wifi/1.2/default/hidl_struct_util.cpp
+++ b/wifi/1.2/default/hidl_struct_util.cpp
@@ -1956,6 +1956,22 @@
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 @@
}
*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<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr);
- hidl_ind->appInfo =
+ hidl_ind->V1_0.appInfo =
std::vector<uint8_t>(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<NanDataPathChannelInfo> 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<uint8_t, 6>(legacy_ind.peer_mac_addr);
+ std::vector<NanDataPathChannelInfo> 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<uint32_t> 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 e44ab7d..1208afd 100644
--- a/wifi/1.2/default/hidl_struct_util.h
+++ b/wifi/1.2/default/hidl_struct_util.h
@@ -147,6 +147,9 @@
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 e93e6be..535e3d3 100644
--- a/wifi/1.2/default/wifi_nan_iface.cpp
+++ b/wifi/1.2/default/wifi_nan_iface.cpp
@@ -428,7 +428,7 @@
}
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 @@
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<void> WifiNanIface::registerEventCallback(
- const sp<IWifiNanIfaceEventCallback>& callback,
+ const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
registerEventCallback_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiNanIface::registerEventCallbackInternal,
@@ -628,6 +646,14 @@
hidl_status_cb, cmd_id, ndpInstanceId);
}
+Return<void> WifiNanIface::registerEventCallback_1_2(
+ const sp<IWifiNanIfaceEventCallback>& 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<void> WifiNanIface::enableRequest_1_2(
uint16_t cmd_id, const NanEnableRequest& msg1,
const NanConfigRequestSupplemental& msg2,
@@ -655,11 +681,8 @@
}
WifiStatus WifiNanIface::registerEventCallbackInternal(
- const sp<IWifiNanIfaceEventCallback>& callback) {
- if (!event_cb_handler_.addCallback(callback)) {
- return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
- }
- return createWifiStatus(WifiStatusCode::SUCCESS);
+ const sp<V1_0::IWifiNanIfaceEventCallback>& /*callback*/) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t cmd_id) {
@@ -784,6 +807,14 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+WifiStatus WifiNanIface::registerEventCallback_1_2Internal(
+ const sp<IWifiNanIfaceEventCallback>& 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 2ded3a8..a2dcf3a 100644
--- a/wifi/1.2/default/wifi_nan_iface.h
+++ b/wifi/1.2/default/wifi_nan_iface.h
@@ -47,7 +47,7 @@
Return<void> getName(getName_cb hidl_status_cb) override;
Return<void> getType(getType_cb hidl_status_cb) override;
Return<void> registerEventCallback(
- const sp<IWifiNanIfaceEventCallback>& callback,
+ const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
registerEventCallback_cb hidl_status_cb) override;
Return<void> getCapabilitiesRequest(
uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override;
@@ -88,6 +88,9 @@
uint16_t cmd_id, uint32_t ndpInstanceId,
terminateDataPathRequest_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_2(
+ const sp<IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_2_cb hidl_status_cb) override;
Return<void> enableRequest_1_2(
uint16_t cmd_id, const NanEnableRequest& msg1,
const NanConfigRequestSupplemental& msg2,
@@ -102,7 +105,7 @@
std::pair<WifiStatus, std::string> getNameInternal();
std::pair<WifiStatus, IfaceType> getTypeInternal();
WifiStatus registerEventCallbackInternal(
- const sp<IWifiNanIfaceEventCallback>& callback);
+ const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
WifiStatus enableRequestInternal(uint16_t cmd_id,
const NanEnableRequest& msg);
@@ -128,6 +131,8 @@
WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id,
uint32_t ndpInstanceId);
+ WifiStatus registerEventCallback_1_2Internal(
+ const sp<IWifiNanIfaceEventCallback>& 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 9151295..60f4b1f 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 @@
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<NanDataPathChannelInfo> 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<NanDataPathChannelInfo> channelInfo;
+ /**
+ * The list of NDPs to which this update applies.
+ */
+ vec<uint32_t> ndpInstanceIds;
+};