wifi: Begin NAN iface methods implementation

Start implementation of the NAN iface HIDL methods by plumbing the HIDL
stubs to the corresponding legacy HAL methods. The incoming HIDL struct
needs to be converted to legacy for the HIDL methods. The legacy HAL
structs needs to be converted to HIDL for callbacks.

This CL only has a couple of methods and some structure conversion.
etan@ will take over the rest.

Bug: 31991076
Test: Compiles
Change-Id: Ide348f4c3318822226bb7de93d091107c7465cd3
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index b4dcc0a..234f526 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -251,6 +251,487 @@
   hidl_stats->timeStampInMs = uptimeMillis();
   return true;
 }
+
+legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(
+    NanPublishType type) {
+  switch (type) {
+    case NanPublishType::UNSOLICITED:
+      return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
+    case NanPublishType::SOLICITED:
+      return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED;
+    case NanPublishType::UNSOLICITED_SOLICITED:
+      return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+  };
+}
+
+legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) {
+  switch (type) {
+    case NanTxType::BROADCAST:
+      return legacy_hal::NAN_TX_TYPE_BROADCAST;
+    case NanTxType::UNICAST:
+      return legacy_hal::NAN_TX_TYPE_UNICAST;
+  };
+}
+
+legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) {
+  switch (type) {
+    case NanMatchAlg::MATCH_ONCE:
+      return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE;
+    case NanMatchAlg::MATCH_CONTINUOUS:
+      return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+    case NanMatchAlg::MATCH_NEVER:
+      return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER;
+  };
+}
+
+legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(
+    NanSubscribeType type) {
+  switch (type) {
+    case NanSubscribeType::ACTIVE:
+      return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE;
+    case NanSubscribeType::PASSIVE:
+      return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
+  };
+}
+
+legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) {
+  switch (type) {
+    case NanSrfType::BLOOM_FILTER:
+      return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER;
+    case NanSrfType::PARTIAL_MAC_ADDR:
+      return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+  };
+}
+
+legacy_hal::NanSRFIncludeType convertHidlNanSrfIncludeTypeToLegacy(
+    NanSrfIncludeType type) {
+  switch (type) {
+    case NanSrfIncludeType::DO_NOT_RESPOND:
+      return legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+    case NanSrfIncludeType::RESPOND:
+      return legacy_hal::NAN_SRF_INCLUDE_RESPOND;
+  };
+}
+
+NanStatusType convertLegacyNanStatusTypeToHidl(
+    legacy_hal::NanStatusType /* type */) {
+  // TODO: The |NanStatusType| has changed in legacy HAL and no longer in sync
+  // with the HIDL interface.
+  return NanStatusType::SUCCESS;
+}
+
+NanResponseType convertLegacyNanResponseTypeToHidl(
+    legacy_hal::NanResponseType type) {
+  switch (type) {
+    case legacy_hal::NAN_RESPONSE_ENABLED:
+      return NanResponseType::ENABLED;
+    case legacy_hal::NAN_RESPONSE_DISABLED:
+      return NanResponseType::DISABLED;
+    case legacy_hal::NAN_RESPONSE_PUBLISH:
+      return NanResponseType::PUBLISH;
+    case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL:
+      return NanResponseType::PUBLISH_CANCEL;
+    case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP:
+      return NanResponseType::TRANSMIT_FOLLOWUP;
+    case legacy_hal::NAN_RESPONSE_SUBSCRIBE:
+      return NanResponseType::SUBSCRIBE;
+    case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL:
+      return NanResponseType::SUBSCRIBE_CANCEL;
+    case legacy_hal::NAN_RESPONSE_STATS:
+      // Not present in HIDL. Is going to be deprecated in legacy HAL as well.
+      CHECK(0);
+    case legacy_hal::NAN_RESPONSE_CONFIG:
+      return NanResponseType::CONFIG;
+    case legacy_hal::NAN_RESPONSE_TCA:
+      // Not present in HIDL. Is going to be deprecated in legacy HAL as well.
+      CHECK(0);
+    case legacy_hal::NAN_RESPONSE_ERROR:
+      return NanResponseType::ERROR;
+    case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
+      return NanResponseType::BEACON_SDF_PAYLOAD;
+    case legacy_hal::NAN_GET_CAPABILITIES:
+      return NanResponseType::GET_CAPABILITIES;
+    case legacy_hal::NAN_DP_INTERFACE_CREATE:
+      return NanResponseType::DP_INTERFACE_CREATE;
+    case legacy_hal::NAN_DP_INTERFACE_DELETE:
+      return NanResponseType::DP_INTERFACE_DELETE;
+    case legacy_hal::NAN_DP_INITIATOR_RESPONSE:
+      return NanResponseType::DP_INITIATOR_RESPONSE;
+    case legacy_hal::NAN_DP_RESPONDER_RESPONSE:
+      return NanResponseType::DP_RESPONDER_RESPONSE;
+    case legacy_hal::NAN_DP_END:
+      return NanResponseType::DP_END;
+  };
+}
+
+bool convertHidlNanEnableRequestToLegacy(
+    const NanEnableRequest& hidl_request,
+    legacy_hal::NanEnableRequest* legacy_request) {
+  if (!legacy_request) {
+    return false;
+  }
+  legacy_request->master_pref = hidl_request.masterPref;
+  legacy_request->cluster_low = hidl_request.clusterLow;
+  legacy_request->cluster_high = hidl_request.clusterHigh;
+  legacy_request->config_support_5g = hidl_request.validSupport5gVal;
+  legacy_request->support_5g_val = hidl_request.support5gVal;
+  legacy_request->config_sid_beacon = hidl_request.validSidBeaconVal;
+  legacy_request->sid_beacon_val = hidl_request.sidBeaconVal;
+  legacy_request->config_2dot4g_rssi_close =
+      hidl_request.valid2dot4gRssiCloseVal;
+  legacy_request->rssi_close_2dot4g_val = hidl_request.rssiClose2dot4gVal;
+  legacy_request->config_2dot4g_rssi_middle =
+      hidl_request.valid2dot4gRssiMiddleVal;
+  legacy_request->rssi_middle_2dot4g_val = hidl_request.rssiMiddle2dot4gVal;
+  legacy_request->config_2dot4g_rssi_proximity =
+      hidl_request.valid2dot4gRssiProximityVal;
+  legacy_request->rssi_proximity_2dot4g_val =
+      hidl_request.rssiProximity2dot4gVal;
+  legacy_request->config_hop_count_limit = hidl_request.validHopCountLimitVal;
+  legacy_request->hop_count_limit_val = hidl_request.hopCountLimitVal;
+  legacy_request->config_2dot4g_support = hidl_request.valid2dot4gSupportVal;
+  legacy_request->support_2dot4g_val = hidl_request.support2dot4gVal;
+  legacy_request->config_2dot4g_beacons = hidl_request.valid2dot4gBeaconsVal;
+  legacy_request->beacon_2dot4g_val = hidl_request.beacon2dot4gVal;
+  legacy_request->config_2dot4g_sdf = hidl_request.valid2dot4gSdfVal;
+  legacy_request->sdf_2dot4g_val = hidl_request.sdf2dot4gVal;
+  legacy_request->config_5g_beacons = hidl_request.valid5gBeaconsVal;
+  legacy_request->beacon_5g_val = hidl_request.beacon5gVal;
+  legacy_request->config_5g_sdf = hidl_request.valid5gSdfVal;
+  legacy_request->sdf_5g_val = hidl_request.sdf5gVal;
+  legacy_request->config_5g_rssi_close = hidl_request.valid5gRssiCloseVal;
+  legacy_request->rssi_close_5g_val = hidl_request.rssiClose5gVal;
+  legacy_request->config_5g_rssi_middle = hidl_request.valid5gRssiMiddleVal;
+  legacy_request->rssi_middle_5g_val = hidl_request.rssiMiddle5gVal;
+  legacy_request->config_5g_rssi_close_proximity =
+      hidl_request.valid5gRssiCloseProximityVal;
+  legacy_request->rssi_close_proximity_5g_val =
+      hidl_request.rssiCloseProximity5gVal;
+  legacy_request->config_rssi_window_size = hidl_request.validRssiWindowSizeVal;
+  legacy_request->rssi_window_size_val = hidl_request.rssiWindowSizeVal;
+  legacy_request->config_oui = hidl_request.validOuiVal;
+  legacy_request->oui_val = hidl_request.ouiVal;
+  legacy_request->config_intf_addr = hidl_request.validIntfAddrVal;
+  CHECK(hidl_request.intfAddrVal.size() ==
+        sizeof(legacy_request->intf_addr_val));
+  memcpy(legacy_request->intf_addr_val,
+         hidl_request.intfAddrVal.data(),
+         hidl_request.intfAddrVal.size());
+  legacy_request->config_cluster_attribute_val =
+      hidl_request.configClusterAttributeVal;
+  legacy_request->config_scan_params = hidl_request.validScanParamsVal;
+  if (hidl_request.scanParamsVal.dwellTime.size() >
+      sizeof(legacy_request->scan_params_val.dwell_time)) {
+    return false;
+  }
+  memcpy(legacy_request->scan_params_val.dwell_time,
+         hidl_request.scanParamsVal.dwellTime.data(),
+         hidl_request.scanParamsVal.dwellTime.size());
+  if (hidl_request.scanParamsVal.scanPeriod.size() >
+      sizeof(legacy_request->scan_params_val.scan_period)) {
+    return false;
+  }
+  memcpy(legacy_request->scan_params_val.scan_period,
+         hidl_request.scanParamsVal.scanPeriod.data(),
+         hidl_request.scanParamsVal.scanPeriod.size());
+  legacy_request->config_random_factor_force =
+      hidl_request.validRandomFactorForceVal;
+  legacy_request->random_factor_force_val = hidl_request.randomFactorForceVal;
+  legacy_request->config_hop_count_force = hidl_request.validHopCountLimitVal;
+  legacy_request->hop_count_force_val = hidl_request.hopCountLimitVal;
+  legacy_request->config_24g_channel = hidl_request.valid24gChannelVal;
+  legacy_request->channel_24g_val = hidl_request.channel24gVal;
+  legacy_request->config_5g_channel = hidl_request.valid5gChannelVal;
+  legacy_request->channel_5g_val = hidl_request.channel5gVal;
+  return true;
+}
+
+bool convertHidlNanPublishRequestToLegacy(
+    const NanPublishRequest& hidl_request,
+    legacy_hal::NanPublishRequest* legacy_request) {
+  if (!legacy_request) {
+    return false;
+  }
+  legacy_request->publish_id = hidl_request.publishId;
+  legacy_request->ttl = hidl_request.ttl;
+  legacy_request->period = hidl_request.period;
+  legacy_request->publish_type =
+      convertHidlNanPublishTypeToLegacy(hidl_request.publishType);
+  legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType);
+  legacy_request->publish_count = hidl_request.publishCount;
+  if (hidl_request.serviceName.size() > sizeof(legacy_request->service_name)) {
+    return false;
+  }
+  legacy_request->service_name_len = hidl_request.serviceName.size();
+  memcpy(legacy_request->service_name,
+         hidl_request.serviceName.c_str(),
+         hidl_request.serviceName.size());
+  legacy_request->publish_match_indicator =
+      convertHidlNanMatchAlgToLegacy(hidl_request.publishMatchIndicator);
+  if (hidl_request.serviceSpecificInfo.size() >
+      sizeof(legacy_request->service_specific_info)) {
+    return false;
+  }
+  legacy_request->service_specific_info_len =
+      hidl_request.serviceSpecificInfo.size();
+  memcpy(legacy_request->service_specific_info,
+         hidl_request.serviceSpecificInfo.data(),
+         hidl_request.serviceSpecificInfo.size());
+  if (hidl_request.rxMatchFilter.size() >
+      sizeof(legacy_request->rx_match_filter)) {
+    return false;
+  }
+  legacy_request->rx_match_filter_len = hidl_request.rxMatchFilter.size();
+  memcpy(legacy_request->rx_match_filter,
+         hidl_request.rxMatchFilter.data(),
+         hidl_request.rxMatchFilter.size());
+  if (hidl_request.txMatchFilter.size() >
+      sizeof(legacy_request->tx_match_filter)) {
+    return false;
+  }
+  legacy_request->tx_match_filter_len = hidl_request.txMatchFilter.size();
+  memcpy(legacy_request->tx_match_filter,
+         hidl_request.txMatchFilter.data(),
+         hidl_request.txMatchFilter.size());
+  legacy_request->rssi_threshold_flag = hidl_request.useRssiThreshold;
+  legacy_request->connmap = hidl_request.connmap;
+  legacy_request->recv_indication_cfg = hidl_request.recvIndicationCfg;
+  return true;
+}
+
+bool convertHidlNanPublishCancelRequestToLegacy(
+    const NanPublishCancelRequest& hidl_request,
+    legacy_hal::NanPublishCancelRequest* legacy_request) {
+  legacy_request->publish_id = hidl_request.publishId;
+  return true;
+}
+
+bool convertHidlNanSubscribeRequestToLegacy(
+    const NanSubscribeRequest& hidl_request,
+    legacy_hal::NanSubscribeRequest* legacy_request) {
+  if (!legacy_request) {
+    return false;
+  }
+  legacy_request->subscribe_id = hidl_request.subscribeId;
+  legacy_request->ttl = hidl_request.ttl;
+  legacy_request->period = hidl_request.period;
+  legacy_request->subscribe_type =
+      convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType);
+  legacy_request->serviceResponseFilter =
+      convertHidlNanSrfTypeToLegacy(hidl_request.serviceResponseFilter);
+  legacy_request->serviceResponseInclude =
+      convertHidlNanSrfIncludeTypeToLegacy(hidl_request.serviceResponseInclude);
+  legacy_request->useServiceResponseFilter =
+      hidl_request.shouldUseServiceResponseFilter
+          ? legacy_hal::NAN_USE_SRF
+          : legacy_hal::NAN_DO_NOT_USE_SRF;
+  legacy_request->ssiRequiredForMatchIndication =
+      hidl_request.isSsiRequiredForMatchIndication
+          ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
+          : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+  legacy_request->subscribe_match_indicator =
+      convertHidlNanMatchAlgToLegacy(hidl_request.subscribeMatchIndicator);
+  legacy_request->subscribe_count = hidl_request.subscribeCount;
+  if (hidl_request.serviceName.size() > sizeof(legacy_request->service_name)) {
+    return false;
+  }
+  legacy_request->service_name_len = hidl_request.serviceName.size();
+  memcpy(legacy_request->service_name,
+         hidl_request.serviceName.c_str(),
+         hidl_request.serviceName.size());
+  if (hidl_request.serviceSpecificInfo.size() >
+      sizeof(legacy_request->service_specific_info)) {
+    return false;
+  }
+  legacy_request->service_specific_info_len =
+      hidl_request.serviceSpecificInfo.size();
+  memcpy(legacy_request->service_specific_info,
+         hidl_request.serviceSpecificInfo.data(),
+         hidl_request.serviceSpecificInfo.size());
+  if (hidl_request.rxMatchFilter.size() >
+      sizeof(legacy_request->rx_match_filter)) {
+    return false;
+  }
+  legacy_request->rx_match_filter_len = hidl_request.rxMatchFilter.size();
+  memcpy(legacy_request->rx_match_filter,
+         hidl_request.rxMatchFilter.data(),
+         hidl_request.rxMatchFilter.size());
+  if (hidl_request.txMatchFilter.size() >
+      sizeof(legacy_request->tx_match_filter)) {
+    return false;
+  }
+  legacy_request->tx_match_filter_len = hidl_request.txMatchFilter.size();
+  memcpy(legacy_request->tx_match_filter,
+         hidl_request.txMatchFilter.data(),
+         hidl_request.txMatchFilter.size());
+  legacy_request->rssi_threshold_flag = hidl_request.useRssiThreshold;
+  legacy_request->connmap = hidl_request.connmap;
+  if (hidl_request.intfAddr.size() > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
+    return false;
+  }
+  legacy_request->num_intf_addr_present = hidl_request.intfAddr.size();
+  for (uint32_t i = 0; i < hidl_request.intfAddr.size(); i++) {
+    CHECK(hidl_request.intfAddr[i].size() ==
+          sizeof(legacy_request->intf_addr[i]));
+    memcpy(legacy_request->intf_addr[i],
+           hidl_request.intfAddr[i].data(),
+           hidl_request.intfAddr[i].size());
+  }
+  legacy_request->recv_indication_cfg = hidl_request.recvIndicationCfg;
+  return true;
+}
+
+bool convertHidlNanSubscribeCancelRequestToLegacy(
+    const NanSubscribeCancelRequest& /* hidl_request */,
+    legacy_hal::NanSubscribeCancelRequest* /* legacy_request */) {
+  return false;
+}
+
+bool convertHidlNanTransmitFollowupRequestToLegacy(
+    const NanTransmitFollowupRequest& /* hidl_request */,
+    legacy_hal::NanTransmitFollowupRequest* /* legacy_request */) {
+  return false;
+}
+
+bool convertHidlNanConfigRequestToLegacy(
+    const NanConfigRequest& /* hidl_request */,
+    legacy_hal::NanConfigRequest* /* legacy_request */) {
+  return false;
+}
+
+bool convertHidlNanBeaconSdfPayloadRequestToLegacy(
+    const NanBeaconSdfPayloadRequest& /* hidl_request */,
+    legacy_hal::NanBeaconSdfPayloadRequest* /* legacy_request */) {
+  return false;
+}
+
+bool convertHidlNanDataPathInitiatorRequestToLegacy(
+    const NanDataPathInitiatorRequest& /* hidl_request */,
+    legacy_hal::NanDataPathInitiatorRequest* /* legacy_request */) {
+  return false;
+}
+
+bool convertHidlNanDataPathIndicationResponseToLegacy(
+    const NanDataPathIndicationResponse& /* hidl_response */,
+    legacy_hal::NanDataPathIndicationResponse* /* legacy_response */) {
+  return false;
+}
+
+bool convertHidlNanDataPathEndRequestToLegacy(
+    const NanDataPathEndRequest& /* hidl_request */,
+    legacy_hal::NanDataPathEndRequest* /* legacy_request */) {
+  return false;
+}
+
+bool convertLegacyNanResponseHeaderToHidl(
+    const legacy_hal::NanResponseMsg& legacy_response,
+    NanResponseMsgHeader* hidl_response) {
+  if (!hidl_response) {
+    return false;
+  }
+  hidl_response->status =
+      convertLegacyNanStatusTypeToHidl(legacy_response.status);
+  hidl_response->value = legacy_response.value;
+  hidl_response->responseType =
+      convertLegacyNanResponseTypeToHidl(legacy_response.response_type);
+  return true;
+}
+
+bool convertLegacyNanPublishResponseToHidl(
+    const legacy_hal::NanPublishResponse& /* legacy_response */,
+    NanPublishResponse* /* hidl_response */) {
+  return false;
+}
+
+bool convertLegacyNanSubscribeResponseToHidl(
+    const legacy_hal::NanSubscribeResponse& /* legacy_response */,
+    NanSubscribeResponse* /* hidl_response */) {
+  return false;
+}
+
+bool convertLegacyNanDataPathResponseToHidl(
+    const legacy_hal::NanDataPathRequestResponse& /* legacy_response */,
+    NanDataPathResponse* /* hidl_response */) {
+  return false;
+}
+
+bool convertLegacyNanCapabilitiesResponseToHidl(
+    const legacy_hal::NanCapabilities& /* legacy_response */,
+    NanCapabilitiesResponse* /* hidl_response */) {
+  return false;
+}
+
+bool convertLegacyNanPublishTerminatedIndToHidl(
+    const legacy_hal::NanPublishTerminatedInd& /* legacy_ind */,
+    NanPublishTerminatedInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanMatchIndToHidl(
+    const legacy_hal::NanMatchInd& /* legacy_ind */,
+    NanMatchInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanMatchExpiredIndToHidl(
+    const legacy_hal::NanMatchExpiredInd& /* legacy_ind */,
+    NanMatchExpiredInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanSubscribeTerminatedIndToHidl(
+    const legacy_hal::NanSubscribeTerminatedInd& /* legacy_ind */,
+    NanSubscribeTerminatedInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanFollowupIndToHidl(
+    const legacy_hal::NanFollowupInd& /* legacy_ind */,
+    NanFollowupInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanDiscEngEventIndToHidl(
+    const legacy_hal::NanDiscEngEventInd& /* legacy_ind */,
+    NanDiscEngEventInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanDisabledIndToHidl(
+    const legacy_hal::NanDisabledInd& /* legacy_ind */,
+    NanDisabledInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanBeaconSdfPayloadIndToHidl(
+    const legacy_hal::NanBeaconSdfPayloadInd& /* legacy_ind */,
+    NanBeaconSdfPayloadInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanDataPathRequestIndToHidl(
+    const legacy_hal::NanDataPathRequestInd& /* legacy_ind */,
+    NanDataPathRequestInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanDataPathConfirmIndToHidl(
+    const legacy_hal::NanDataPathConfirmInd& /* legacy_ind */,
+    NanDataPathConfirmInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanDataPathEndIndToHidl(
+    const legacy_hal::NanDataPathEndInd& /* legacy_ind */,
+    NanDataPathEndInd* /* hidl_ind */) {
+  return false;
+}
+
+bool convertLegacyNanTransmitFollowupIndToHidl(
+    const legacy_hal::NanTransmitFollowupInd& /* legacy_ind */,
+    NanTransmitFollowupInd* /* hidl_ind */) {
+  return false;
+}
 }  // namespace hidl_struct_util
 }  // namespace implementation
 }  // namespace V1_0
diff --git a/wifi/1.0/default/hidl_struct_util.h b/wifi/1.0/default/hidl_struct_util.h
index 6c91e03..ae1cf70 100644
--- a/wifi/1.0/default/hidl_struct_util.h
+++ b/wifi/1.0/default/hidl_struct_util.h
@@ -36,7 +36,7 @@
 namespace implementation {
 namespace hidl_struct_util {
 
-// Convert hidl gscan params to legacy gscan params.
+// STA iface conversion methods.
 bool convertHidlScanParamsToLegacy(
     const StaBackgroundScanParameters& hidl_scan_params,
     legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
@@ -59,6 +59,89 @@
 bool convertLegacyLinkLayerStatsToHidl(
     const legacy_hal::LinkLayerStats& legacy_stats,
     StaLinkLayerStats* hidl_stats);
+
+// NAN iface conversion methods.
+bool convertHidlNanEnableRequestToLegacy(
+    const NanEnableRequest& hidl_request,
+    legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanPublishRequestToLegacy(
+    const NanPublishRequest& hidl_request,
+    legacy_hal::NanPublishRequest* legacy_request);
+bool convertHidlNanPublishCancelRequestToLegacy(
+    const NanPublishCancelRequest& hidl_request,
+    legacy_hal::NanPublishCancelRequest* legacy_request);
+bool convertHidlNanSubscribeRequestToLegacy(
+    const NanSubscribeRequest& hidl_request,
+    legacy_hal::NanSubscribeRequest* legacy_request);
+bool convertHidlNanSubscribeCancelRequestToLegacy(
+    const NanSubscribeCancelRequest& hidl_request,
+    legacy_hal::NanSubscribeCancelRequest* legacy_request);
+bool convertHidlNanTransmitFollowupRequestToLegacy(
+    const NanTransmitFollowupRequest& hidl_request,
+    legacy_hal::NanTransmitFollowupRequest* legacy_request);
+bool convertHidlNanConfigRequestToLegacy(
+    const NanConfigRequest& hidl_request,
+    legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanBeaconSdfPayloadRequestToLegacy(
+    const NanBeaconSdfPayloadRequest& hidl_request,
+    legacy_hal::NanBeaconSdfPayloadRequest* legacy_request);
+bool convertHidlNanDataPathInitiatorRequestToLegacy(
+    const NanDataPathInitiatorRequest& hidl_request,
+    legacy_hal::NanDataPathInitiatorRequest* legacy_request);
+bool convertHidlNanDataPathIndicationResponseToLegacy(
+    const NanDataPathIndicationResponse& hidl_response,
+    legacy_hal::NanDataPathIndicationResponse* legacy_response);
+bool convertHidlNanDataPathEndRequestToLegacy(
+    const NanDataPathEndRequest& hidl_request,
+    legacy_hal::NanDataPathEndRequest* legacy_request);
+bool convertLegacyNanResponseHeaderToHidl(
+    const legacy_hal::NanResponseMsg& legacy_response,
+    NanResponseMsgHeader* hidl_response);
+bool convertLegacyNanPublishResponseToHidl(
+    const legacy_hal::NanPublishResponse& legacy_response,
+    NanPublishResponse* hidl_response);
+bool convertLegacyNanSubscribeResponseToHidl(
+    const legacy_hal::NanSubscribeResponse& legacy_response,
+    NanSubscribeResponse* hidl_response);
+bool convertLegacyNanDataPathResponseToHidl(
+    const legacy_hal::NanDataPathRequestResponse& legacy_response,
+    NanDataPathResponse* hidl_response);
+bool convertLegacyNanCapabilitiesResponseToHidl(
+    const legacy_hal::NanCapabilities& legacy_response,
+    NanCapabilitiesResponse* hidl_response);
+bool convertLegacyNanPublishTerminatedIndToHidl(
+    const legacy_hal::NanPublishTerminatedInd& legacy_ind,
+    NanPublishTerminatedInd* hidl_ind);
+bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
+                                    NanMatchInd* hidl_ind);
+bool convertLegacyNanMatchExpiredIndToHidl(
+    const legacy_hal::NanMatchExpiredInd& legacy_ind,
+    NanMatchExpiredInd* hidl_ind);
+bool convertLegacyNanSubscribeTerminatedIndToHidl(
+    const legacy_hal::NanSubscribeTerminatedInd& legacy_ind,
+    NanSubscribeTerminatedInd* hidl_ind);
+bool convertLegacyNanFollowupIndToHidl(
+    const legacy_hal::NanFollowupInd& legacy_ind, NanFollowupInd* hidl_ind);
+bool convertLegacyNanDiscEngEventIndToHidl(
+    const legacy_hal::NanDiscEngEventInd& legacy_ind,
+    NanDiscEngEventInd* hidl_ind);
+bool convertLegacyNanDisabledIndToHidl(
+    const legacy_hal::NanDisabledInd& legacy_ind, NanDisabledInd* hidl_ind);
+bool convertLegacyNanBeaconSdfPayloadIndToHidl(
+    const legacy_hal::NanBeaconSdfPayloadInd& legacy_ind,
+    NanBeaconSdfPayloadInd* hidl_ind);
+bool convertLegacyNanDataPathRequestIndToHidl(
+    const legacy_hal::NanDataPathRequestInd& legacy_ind,
+    NanDataPathRequestInd* hidl_ind);
+bool convertLegacyNanDataPathConfirmIndToHidl(
+    const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+    NanDataPathConfirmInd* hidl_ind);
+bool convertLegacyNanDataPathEndIndToHidl(
+    const legacy_hal::NanDataPathEndInd& legacy_ind,
+    NanDataPathEndInd* hidl_ind);
+bool convertLegacyNanTransmitFollowupIndToHidl(
+    const legacy_hal::NanTransmitFollowupInd& legacy_ind,
+    NanTransmitFollowupInd* hidl_ind);
 }  // namespace hidl_struct_util
 }  // namespace implementation
 }  // namespace V1_0
diff --git a/wifi/1.0/default/wifi_nan_iface.cpp b/wifi/1.0/default/wifi_nan_iface.cpp
index 48e75a5..a897520 100644
--- a/wifi/1.0/default/wifi_nan_iface.cpp
+++ b/wifi/1.0/default/wifi_nan_iface.cpp
@@ -17,6 +17,7 @@
 #include <android-base/logging.h>
 
 #include "hidl_return_util.h"
+#include "hidl_struct_util.h"
 #include "wifi_nan_iface.h"
 #include "wifi_status_util.h"
 
@@ -30,7 +31,47 @@
 WifiNanIface::WifiNanIface(
     const std::string& ifname,
     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
+    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {
+  // Register all the callbacks here. these should be valid for the lifetime
+  // of the object. Whenever the mode changes legacy HAL will remove
+  // all of these callbacks.
+  legacy_hal::NanCallbackHandlers callback_handlers;
+
+  // Callback for response.
+  callback_handlers.on_notify_response = [&](
+      legacy_hal::transaction_id id, const legacy_hal::NanResponseMsg& msg) {
+    NanResponseMsgHeader hidl_header;
+    if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(msg,
+                                                                &hidl_header)) {
+      LOG(ERROR) << "Failed to convert nan response header";
+      return;
+    }
+    // TODO: This is a union in the legacy HAL. Need to convert to appropriate
+    // callback based on type.
+    // Assuming |NanPublishResponseMsg| type here.
+    NanPublishResponse hidl_body;
+    if (!hidl_struct_util::convertLegacyNanPublishResponseToHidl(
+            msg.body.publish_response, &hidl_body)) {
+      LOG(ERROR) << "Failed to convert nan publish response";
+      return;
+    }
+    NanPublishResponseMsg hidl_msg;
+    hidl_msg.header = hidl_header;
+    hidl_msg.body = hidl_body;
+    for (const auto& callback : event_callbacks_) {
+      if (!callback->notifyPublishResponse(id, hidl_msg).getStatus().isOk()) {
+        LOG(ERROR) << "Failed to invoke the callback";
+      }
+    }
+  };
+  // TODO: Register the remaining callbacks.
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->nanRegisterCallbackHandlers(callback_handlers);
+  if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
+    invalidate();
+  }
+}
 
 void WifiNanIface::invalidate() {
   legacy_hal_.reset();
@@ -258,33 +299,60 @@
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-WifiStatus WifiNanIface::enableRequestInternal(
-    uint32_t /* cmd_id */, const NanEnableRequest& /* msg */) {
-  // TODO implement
-  return createWifiStatus(WifiStatusCode::SUCCESS);
+WifiStatus WifiNanIface::enableRequestInternal(uint32_t cmd_id,
+                                               const NanEnableRequest& msg) {
+  legacy_hal::NanEnableRequest legacy_msg;
+  if (!hidl_struct_util::convertHidlNanEnableRequestToLegacy(msg,
+                                                             &legacy_msg)) {
+    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+  }
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->nanEnableRequest(cmd_id, legacy_msg);
+  return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiNanIface::disableRequestInternal(uint32_t /* cmd_id */) {
-  // TODO implement
-  return createWifiStatus(WifiStatusCode::SUCCESS);
+WifiStatus WifiNanIface::disableRequestInternal(uint32_t cmd_id) {
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->nanDisableRequest(cmd_id);
+  return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiNanIface::publishRequestInternal(
-    uint32_t /* cmd_id */, const NanPublishRequest& /* msg */) {
-  // TODO implement
-  return createWifiStatus(WifiStatusCode::SUCCESS);
+WifiStatus WifiNanIface::publishRequestInternal(uint32_t cmd_id,
+                                                const NanPublishRequest& msg) {
+  legacy_hal::NanPublishRequest legacy_msg;
+  if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg,
+                                                              &legacy_msg)) {
+    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+  }
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->nanPublishRequest(cmd_id, legacy_msg);
+  return createWifiStatusFromLegacyError(legacy_status);
 }
 
 WifiStatus WifiNanIface::publishCancelRequestInternal(
-    uint32_t /* cmd_id */, const NanPublishCancelRequest& /* msg */) {
-  // TODO implement
-  return createWifiStatus(WifiStatusCode::SUCCESS);
+    uint32_t cmd_id, const NanPublishCancelRequest& msg) {
+  legacy_hal::NanPublishCancelRequest legacy_msg;
+  if (!hidl_struct_util::convertHidlNanPublishCancelRequestToLegacy(
+          msg, &legacy_msg)) {
+    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+  }
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->nanPublishCancelRequest(cmd_id, legacy_msg);
+  return createWifiStatusFromLegacyError(legacy_status);
 }
+
 WifiStatus WifiNanIface::subscribeRequestInternal(
-    uint32_t /* cmd_id */, const NanSubscribeRequest& /* msg */) {
-  // TODO implement
-  return createWifiStatus(WifiStatusCode::SUCCESS);
+    uint32_t cmd_id, const NanSubscribeRequest& msg) {
+  legacy_hal::NanSubscribeRequest legacy_msg;
+  if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(msg,
+                                                                &legacy_msg)) {
+    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+  }
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->nanSubscribeRequest(cmd_id, legacy_msg);
+  return createWifiStatusFromLegacyError(legacy_status);
 }
+
 WifiStatus WifiNanIface::subscribeCancelRequestInternal(
     uint32_t /* cmd_id */, const NanSubscribeCancelRequest& /* msg */) {
   // TODO implement