Merge changes Ia9b1d24c,I86980cd2

* changes:
  wifi: Add keep alive packet sending functionality
  wifi: Add nd offload functionality
diff --git a/wifi/1.0/IWifiStaIface.hal b/wifi/1.0/IWifiStaIface.hal
index 98af043..0d6b560 100644
--- a/wifi/1.0/IWifiStaIface.hal
+++ b/wifi/1.0/IWifiStaIface.hal
@@ -81,9 +81,13 @@
      */
     TDLS_OFFCHANNEL = 1 << 11,
     /**
+     * Support for keep alive packet offload.
+     */
+    KEEP_ALIVE = 1 << 12,
+    /**
      * Support for tracking connection packets' fate.
      */
-    DEBUG_PACKET_FATE = 1 << 12
+    DEBUG_PACKET_FATE = 1 << 13
   };
 
   /**
@@ -379,6 +383,55 @@
   setRoamingState(StaRoamingState state) generates (WifiStatus status);
 
   /**
+   * Enable/Disable Neighbour discovery offload functionality in the firmware.
+   *
+   * @param enable true to enable, false to disable.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   */
+  enableNdOffload(bool enable) generates (WifiStatus status);
+
+  /**
+   * Start sending the specified keep alive packets periodically.
+   *
+   * @param cmdId command Id to use for this invocation.
+   * @param ipPacketData IP packet contents to be transmitted.
+   * @param etherType 16 bit ether type to be set in the ethernet frame
+   *        transmitted.
+   * @param srcAddress Source MAC address of the packet.
+   * @param dstAddress Destination MAC address of the packet.
+   * @param periodInMs Interval at which this packet must be transmitted.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   */
+  startSendingKeepAlivePackets(
+      CommandId cmdId, vec<uint8_t> ipPacketData, uint16_t etherType,
+      MacAddress srcAddress, MacAddress dstAddress, uint32_t periodInMs)
+      generates (WifiStatus status);
+
+  /**
+   * Stop sending the specified keep alive packets.
+   *
+   * @param cmdId command Id corresponding to the request.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   */
+  stopSendingKeepAlivePackets(CommandId cmdId) generates (WifiStatus status);
+
+  /**
    * API to start packet fate monitoring.
    * - Once stared, monitoring must remain active until HAL is unloaded.
    * - When HAL is unloaded, all packet fate buffers must be cleared.
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index 9cc57bb..80cc56e 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -82,6 +82,8 @@
       return HidlStaIfaceCaps::TDLS;
     case WIFI_FEATURE_TDLS_OFFCHANNEL:
       return HidlStaIfaceCaps::TDLS_OFFCHANNEL;
+    case WIFI_FEATURE_MKEEP_ALIVE:
+      return HidlStaIfaceCaps::KEEP_ALIVE;
   };
   CHECK(false) << "Unknown legacy feature: " << feature;
   return {};
@@ -239,7 +241,8 @@
                              WIFI_FEATURE_HOTSPOT,
                              WIFI_FEATURE_PNO,
                              WIFI_FEATURE_TDLS,
-                             WIFI_FEATURE_TDLS_OFFCHANNEL}) {
+                             WIFI_FEATURE_TDLS_OFFCHANNEL,
+                             WIFI_FEATURE_MKEEP_ALIVE}) {
     if (feature & legacy_feature_set) {
       *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
     }
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index 3b99e60..3bfd2bb 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -633,15 +633,46 @@
   return {status, caps};
 }
 
+wifi_error WifiLegacyHal::configureRoaming(const wifi_roaming_config& config) {
+  wifi_roaming_config config_internal = config;
+  return global_func_table_.wifi_configure_roaming(wlan_interface_handle_,
+                                                   &config_internal);
+}
+
 wifi_error WifiLegacyHal::enableFirmwareRoaming(fw_roaming_state_t state) {
   return global_func_table_.wifi_enable_firmware_roaming(wlan_interface_handle_,
                                                          state);
 }
 
-wifi_error WifiLegacyHal::configureRoaming(const wifi_roaming_config& config) {
-  wifi_roaming_config config_internal = config;
-  return global_func_table_.wifi_configure_roaming(wlan_interface_handle_,
-                                                   &config_internal);
+wifi_error WifiLegacyHal::configureNdOffload(bool enable) {
+  return global_func_table_.wifi_configure_nd_offload(wlan_interface_handle_,
+                                                      enable);
+}
+
+wifi_error WifiLegacyHal::startSendingOffloadedPacket(
+    uint32_t cmd_id,
+    const std::vector<uint8_t>& ip_packet_data,
+    const std::array<uint8_t, 6>& src_address,
+    const std::array<uint8_t, 6>& dst_address,
+    uint32_t period_in_ms) {
+  std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
+  std::vector<uint8_t> src_address_internal(
+      src_address.data(), src_address.data() + src_address.size());
+  std::vector<uint8_t> dst_address_internal(
+      dst_address.data(), dst_address.data() + dst_address.size());
+  return global_func_table_.wifi_start_sending_offloaded_packet(
+      cmd_id,
+      wlan_interface_handle_,
+      ip_packet_data_internal.data(),
+      ip_packet_data_internal.size(),
+      src_address_internal.data(),
+      dst_address_internal.data(),
+      period_in_ms);
+}
+
+wifi_error WifiLegacyHal::stopSendingOffloadedPacket(uint32_t cmd_id) {
+  return global_func_table_.wifi_stop_sending_offloaded_packet(
+      cmd_id, wlan_interface_handle_);
 }
 
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
index b585314..a3ac075 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -182,8 +182,16 @@
                                      on_threshold_breached_callback);
   wifi_error stopRssiMonitoring(wifi_request_id id);
   std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities();
-  wifi_error enableFirmwareRoaming(fw_roaming_state_t state);
   wifi_error configureRoaming(const wifi_roaming_config& config);
+  wifi_error enableFirmwareRoaming(fw_roaming_state_t state);
+  wifi_error configureNdOffload(bool enable);
+  wifi_error startSendingOffloadedPacket(
+      uint32_t cmd_id,
+      const std::vector<uint8_t>& ip_packet_data,
+      const std::array<uint8_t, 6>& src_address,
+      const std::array<uint8_t, 6>& dst_address,
+      uint32_t period_in_ms);
+  wifi_error stopSendingOffloadedPacket(uint32_t cmd_id);
   // Logger/debug functions.
   std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
   wifi_error startPktFateMonitoring();
diff --git a/wifi/1.0/default/wifi_sta_iface.cpp b/wifi/1.0/default/wifi_sta_iface.cpp
index e48978e..a00c5bc 100644
--- a/wifi/1.0/default/wifi_sta_iface.cpp
+++ b/wifi/1.0/default/wifi_sta_iface.cpp
@@ -212,6 +212,44 @@
                          state);
 }
 
+Return<void> WifiStaIface::enableNdOffload(bool enable,
+                                           enableNdOffload_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::enableNdOffloadInternal,
+                         hidl_status_cb,
+                         enable);
+}
+
+Return<void> WifiStaIface::startSendingKeepAlivePackets(
+    uint32_t cmd_id,
+    const hidl_vec<uint8_t>& ip_packet_data,
+    uint16_t ether_type,
+    const hidl_array<uint8_t, 6>& src_address,
+    const hidl_array<uint8_t, 6>& dst_address,
+    uint32_t period_in_ms,
+    startSendingKeepAlivePackets_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::startSendingKeepAlivePacketsInternal,
+                         hidl_status_cb,
+                         cmd_id,
+                         ip_packet_data,
+                         ether_type,
+                         src_address,
+                         dst_address,
+                         period_in_ms);
+}
+
+Return<void> WifiStaIface::stopSendingKeepAlivePackets(
+    uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::stopSendingKeepAlivePacketsInternal,
+                         hidl_status_cb,
+                         cmd_id);
+}
+
 Return<void> WifiStaIface::startDebugPacketFateMonitoring(
     startDebugPacketFateMonitoring_cb hidl_status_cb) {
   return validateAndCall(this,
@@ -498,6 +536,31 @@
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
+WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->configureNdOffload(enable);
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
+    uint32_t cmd_id,
+    const std::vector<uint8_t>& ip_packet_data,
+    uint16_t /* ether_type */,
+    const std::array<uint8_t, 6>& src_address,
+    const std::array<uint8_t, 6>& dst_address,
+    uint32_t period_in_ms) {
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->startSendingOffloadedPacket(
+          cmd_id, ip_packet_data, src_address, dst_address, period_in_ms);
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) {
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->stopSendingOffloadedPacket(cmd_id);
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
 WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
   legacy_hal::wifi_error legacy_status =
       legacy_hal_.lock()->startPktFateMonitoring();
diff --git a/wifi/1.0/default/wifi_sta_iface.h b/wifi/1.0/default/wifi_sta_iface.h
index 90126cd..311c991 100644
--- a/wifi/1.0/default/wifi_sta_iface.h
+++ b/wifi/1.0/default/wifi_sta_iface.h
@@ -83,6 +83,18 @@
                                 configureRoaming_cb hidl_status_cb) override;
   Return<void> setRoamingState(StaRoamingState state,
                                setRoamingState_cb hidl_status_cb) override;
+  Return<void> enableNdOffload(bool enable,
+                               enableNdOffload_cb hidl_status_cb) override;
+  Return<void> startSendingKeepAlivePackets(
+      uint32_t cmd_id,
+      const hidl_vec<uint8_t>& ip_packet_data,
+      uint16_t ether_type,
+      const hidl_array<uint8_t, 6>& src_address,
+      const hidl_array<uint8_t, 6>& dst_address,
+      uint32_t period_in_ms,
+      startSendingKeepAlivePackets_cb hidl_status_cb) override;
+  Return<void> stopSendingKeepAlivePackets(
+      uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override;
   Return<void> startDebugPacketFateMonitoring(
       startDebugPacketFateMonitoring_cb hidl_status_cb) override;
   Return<void> stopDebugPacketFateMonitoring(
@@ -121,6 +133,15 @@
   getRoamingCapabilitiesInternal();
   WifiStatus configureRoamingInternal(const StaRoamingConfig& config);
   WifiStatus setRoamingStateInternal(StaRoamingState state);
+  WifiStatus enableNdOffloadInternal(bool enable);
+  WifiStatus startSendingKeepAlivePacketsInternal(
+      uint32_t cmd_id,
+      const std::vector<uint8_t>& ip_packet_data,
+      uint16_t ether_type,
+      const std::array<uint8_t, 6>& src_address,
+      const std::array<uint8_t, 6>& dst_address,
+      uint32_t period_in_ms);
+  WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id);
   WifiStatus startDebugPacketFateMonitoringInternal();
   WifiStatus stopDebugPacketFateMonitoringInternal();
   std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>