diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.0/default/wifi_chip.cpp
index 4f8545f..bc46eec 100644
--- a/wifi/1.0/default/wifi_chip.cpp
+++ b/wifi/1.0/default/wifi_chip.cpp
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include "wifi_chip.h"
-
 #include <android-base/logging.h>
 
+#include "hidl_return_util.h"
+#include "wifi_chip.h"
 #include "wifi_status_util.h"
 
 namespace {
@@ -25,14 +25,6 @@
 using android::hardware::hidl_vec;
 using android::hardware::hidl_string;
 
-std::vector<hidl_string> createHidlVecOfIfaceNames(const std::string& ifname) {
-  std::vector<hidl_string> ifnames;
-  if (!ifname.empty()) {
-    ifnames.emplace_back(ifname);
-  }
-  return ifnames;
-}
-
 template <typename Iface>
 void invalidateAndClear(sp<Iface>& iface) {
   if (iface.get()) {
@@ -47,6 +39,7 @@
 namespace wifi {
 namespace V1_0 {
 namespace implementation {
+using hidl_return_util::validateAndCall;
 
 WifiChip::WifiChip(ChipId chip_id,
                    const std::weak_ptr<WifiLegacyHal> legacy_hal)
@@ -59,363 +52,173 @@
   is_valid_ = false;
 }
 
+bool WifiChip::isValid() {
+  return is_valid_;
+}
+
 Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   UINT32_MAX);
-    return Void();
-  }
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), chip_id_);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getIdInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::registerEventCallback(
     const sp<IWifiChipEventCallback>& event_callback,
     registerEventCallback_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID));
-    return Void();
-  }
-  // TODO(b/31632518): remove the callback when the client is destroyed
-  event_callbacks_.emplace_back(event_callback);
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS));
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::registerEventCallbackInternal,
+                         hidl_status_cb,
+                         event_callback);
 }
 
 Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<ChipMode>());
-    return Void();
-  }
-  // TODO add implementation
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS),
-                 hidl_vec<ChipMode>());
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getAvailableModesInternal,
+                         hidl_status_cb);
 }
 
-Return<void> WifiChip::configureChip(uint32_t /*mode_id*/,
+Return<void> WifiChip::configureChip(uint32_t mode_id,
                                      configureChip_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID));
-    return Void();
-  }
-
-  invalidateAndRemoveAllIfaces();
-  // TODO add implementation
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS));
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::configureChipInternal,
+                         hidl_status_cb,
+                         mode_id);
 }
 
 Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   UINT32_MAX);
-    return Void();
-  }
-  // TODO add implementation
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), 0);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getModeInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::requestChipDebugInfo(
     requestChipDebugInfo_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   IWifiChip::ChipDebugInfo());
-    return Void();
-  }
-
-  IWifiChip::ChipDebugInfo result;
-
-  wifi_error legacy_status;
-  std::string driver_desc;
-  std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion();
-  if (legacy_status != WIFI_SUCCESS) {
-    LOG(ERROR) << "Failed to get driver version: "
-               << legacyErrorToString(legacy_status);
-    WifiStatus status = createWifiStatusFromLegacyError(
-        legacy_status, "failed to get driver version");
-    hidl_status_cb(status, result);
-    return Void();
-  }
-  result.driverDescription = driver_desc.c_str();
-
-  std::string firmware_desc;
-  std::tie(legacy_status, firmware_desc) =
-      legacy_hal_.lock()->getFirmwareVersion();
-  if (legacy_status != WIFI_SUCCESS) {
-    LOG(ERROR) << "Failed to get firmware version: "
-               << legacyErrorToString(legacy_status);
-    WifiStatus status = createWifiStatusFromLegacyError(
-        legacy_status, "failed to get firmware version");
-    hidl_status_cb(status, result);
-    return Void();
-  }
-  result.firmwareDescription = firmware_desc.c_str();
-
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), result);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::requestChipDebugInfoInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::requestDriverDebugDump(
     requestDriverDebugDump_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<uint8_t>());
-    return Void();
-  }
-
-  wifi_error legacy_status;
-  std::vector<char> driver_dump;
-  std::tie(legacy_status, driver_dump) =
-      legacy_hal_.lock()->requestDriverMemoryDump();
-  if (legacy_status != WIFI_SUCCESS) {
-    LOG(ERROR) << "Failed to get driver debug dump: "
-               << legacyErrorToString(legacy_status);
-    hidl_status_cb(createWifiStatusFromLegacyError(legacy_status),
-                   hidl_vec<uint8_t>());
-    return Void();
-  }
-
-  hidl_vec<uint8_t> hidl_data;
-  hidl_data.setToExternal(reinterpret_cast<uint8_t*>(driver_dump.data()),
-                          driver_dump.size());
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), hidl_data);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::requestDriverDebugDumpInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::requestFirmwareDebugDump(
     requestFirmwareDebugDump_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<uint8_t>());
-    return Void();
-  }
-
-  wifi_error legacy_status;
-  std::vector<char> firmware_dump;
-  std::tie(legacy_status, firmware_dump) =
-      legacy_hal_.lock()->requestFirmwareMemoryDump();
-  if (legacy_status != WIFI_SUCCESS) {
-    LOG(ERROR) << "Failed to get firmware debug dump: "
-               << legacyErrorToString(legacy_status);
-    hidl_status_cb(createWifiStatusFromLegacyError(legacy_status),
-                   hidl_vec<uint8_t>());
-    return Void();
-  }
-
-  hidl_vec<uint8_t> hidl_data;
-  hidl_data.setToExternal(reinterpret_cast<uint8_t*>(firmware_dump.data()),
-                          firmware_dump.size());
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), hidl_data);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::requestFirmwareDebugDumpInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  // TODO(b/31997422): Disallow this based on the chip combination.
-  std::string ifname = legacy_hal_.lock()->getApIfaceName();
-  ap_iface_ = new WifiApIface(ifname, legacy_hal_);
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::createApIfaceInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<hidl_string>());
-    return Void();
-  }
-
-  std::string ifname;
-  if (ap_iface_.get()) {
-    ifname = legacy_hal_.lock()->getApIfaceName().c_str();
-  }
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS),
-                 createHidlVecOfIfaceNames(ifname));
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getApIfaceNamesInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getApIface(const hidl_string& ifname,
                                   getApIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  if (ap_iface_.get() &&
-      (ifname.c_str() == legacy_hal_.lock()->getApIfaceName())) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_);
-  } else {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS),
-                   nullptr);
-  }
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getApIfaceInternal,
+                         hidl_status_cb,
+                         ifname);
 }
 
 Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  // TODO(b/31997422): Disallow this based on the chip combination.
-  std::string ifname = legacy_hal_.lock()->getNanIfaceName();
-  nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::createNanIfaceInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<hidl_string>());
-    return Void();
-  }
-
-  std::string ifname;
-  if (nan_iface_.get()) {
-    ifname = legacy_hal_.lock()->getNanIfaceName().c_str();
-  }
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS),
-                 createHidlVecOfIfaceNames(ifname));
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getNanIfaceNamesInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getNanIface(const hidl_string& ifname,
                                    getNanIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  if (nan_iface_.get() &&
-      (ifname.c_str() == legacy_hal_.lock()->getNanIfaceName())) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_);
-  } else {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS),
-                   nullptr);
-  }
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getNanIfaceInternal,
+                         hidl_status_cb,
+                         ifname);
 }
 
 Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  // TODO(b/31997422): Disallow this based on the chip combination.
-  std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
-  p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::createP2pIfaceInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<hidl_string>());
-    return Void();
-  }
-
-  std::string ifname;
-  if (p2p_iface_.get()) {
-    ifname = legacy_hal_.lock()->getP2pIfaceName().c_str();
-  }
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS),
-                 createHidlVecOfIfaceNames(ifname));
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getP2pIfaceNamesInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
                                    getP2pIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  if (p2p_iface_.get() &&
-      (ifname.c_str() == legacy_hal_.lock()->getP2pIfaceName())) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_);
-  } else {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS),
-                   nullptr);
-  }
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getP2pIfaceInternal,
+                         hidl_status_cb,
+                         ifname);
 }
 
 Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  // TODO(b/31997422): Disallow this based on the chip combination.
-  std::string ifname = legacy_hal_.lock()->getStaIfaceName();
-  sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::createStaIfaceInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   hidl_vec<hidl_string>());
-    return Void();
-  }
-
-  std::string ifname;
-  if (sta_iface_.get()) {
-    ifname = legacy_hal_.lock()->getStaIfaceName().c_str();
-  }
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS),
-                 createHidlVecOfIfaceNames(ifname));
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getStaIfaceNamesInternal,
+                         hidl_status_cb);
 }
 
 Return<void> WifiChip::getStaIface(const hidl_string& ifname,
                                    getStaIface_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  if (sta_iface_.get() &&
-      (ifname.c_str() == legacy_hal_.lock()->getStaIfaceName())) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_);
-  } else {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS),
-                   nullptr);
-  }
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::getStaIfaceInternal,
+                         hidl_status_cb,
+                         ifname);
 }
 
 Return<void> WifiChip::createRttController(
     const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
-  if (!is_valid_) {
-    hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_WIFI_CHIP_INVALID),
-                   nullptr);
-    return Void();
-  }
-
-  sp<WifiRttController> rtt = new WifiRttController(bound_iface, legacy_hal_);
-  rtt_controllers_.emplace_back(rtt);
-  hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS), rtt);
-  return Void();
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::createRttControllerInternal,
+                         hidl_status_cb,
+                         bound_iface);
 }
 
 void WifiChip::invalidateAndRemoveAllIfaces() {
@@ -431,6 +234,201 @@
   rtt_controllers_.clear();
 }
 
+std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
+  return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
+}
+
+WifiStatus WifiChip::registerEventCallbackInternal(
+    const sp<IWifiChipEventCallback>& event_callback) {
+  // TODO(b/31632518): remove the callback when the client is destroyed
+  event_callbacks_.emplace_back(event_callback);
+  return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
+WifiChip::getAvailableModesInternal() {
+  // TODO add implementation
+  return {createWifiStatus(WifiStatusCode::SUCCESS),
+          std::vector<IWifiChip::ChipMode>()};
+}
+
+WifiStatus WifiChip::configureChipInternal(uint32_t /* mode_id */) {
+  invalidateAndRemoveAllIfaces();
+  // TODO add implementation
+  return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
+  // TODO add implementation
+  return {createWifiStatus(WifiStatusCode::SUCCESS), 0};
+}
+
+std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
+WifiChip::requestChipDebugInfoInternal() {
+  IWifiChip::ChipDebugInfo result;
+  wifi_error legacy_status;
+  std::string driver_desc;
+  std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion();
+  if (legacy_status != WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to get driver version: "
+               << legacyErrorToString(legacy_status);
+    WifiStatus status = createWifiStatusFromLegacyError(
+        legacy_status, "failed to get driver version");
+    return {status, result};
+  }
+  result.driverDescription = driver_desc.c_str();
+
+  std::string firmware_desc;
+  std::tie(legacy_status, firmware_desc) =
+      legacy_hal_.lock()->getFirmwareVersion();
+  if (legacy_status != WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to get firmware version: "
+               << legacyErrorToString(legacy_status);
+    WifiStatus status = createWifiStatusFromLegacyError(
+        legacy_status, "failed to get firmware version");
+    return {status, result};
+  }
+  result.firmwareDescription = firmware_desc.c_str();
+
+  return {createWifiStatus(WifiStatusCode::SUCCESS), result};
+}
+
+std::pair<WifiStatus, std::vector<uint8_t>>
+WifiChip::requestDriverDebugDumpInternal() {
+  wifi_error legacy_status;
+  std::vector<uint8_t> driver_dump;
+  std::tie(legacy_status, driver_dump) =
+      legacy_hal_.lock()->requestDriverMemoryDump();
+  if (legacy_status != WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to get driver debug dump: "
+               << legacyErrorToString(legacy_status);
+    return {createWifiStatusFromLegacyError(legacy_status),
+            std::vector<uint8_t>()};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
+}
+
+std::pair<WifiStatus, std::vector<uint8_t>>
+WifiChip::requestFirmwareDebugDumpInternal() {
+  wifi_error legacy_status;
+  std::vector<uint8_t> firmware_dump;
+  std::tie(legacy_status, firmware_dump) =
+      legacy_hal_.lock()->requestFirmwareMemoryDump();
+  if (legacy_status != WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to get firmware debug dump: "
+               << legacyErrorToString(legacy_status);
+    return {createWifiStatusFromLegacyError(legacy_status),
+            std::vector<uint8_t>()};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
+}
+
+std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
+  // TODO(b/31997422): Disallow this based on the chip combination.
+  std::string ifname = legacy_hal_.lock()->getApIfaceName();
+  ap_iface_ = new WifiApIface(ifname, legacy_hal_);
+  return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>>
+WifiChip::getApIfaceNamesInternal() {
+  if (!ap_iface_.get()) {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS),
+          {legacy_hal_.lock()->getApIfaceName()}};
+}
+
+std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
+    const hidl_string& ifname) {
+  if (!ap_iface_.get() ||
+      (ifname.c_str() != legacy_hal_.lock()->getApIfaceName())) {
+    return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
+}
+
+std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
+  // TODO(b/31997422): Disallow this based on the chip combination.
+  std::string ifname = legacy_hal_.lock()->getNanIfaceName();
+  nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
+  return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>>
+WifiChip::getNanIfaceNamesInternal() {
+  if (!nan_iface_.get()) {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS),
+          {legacy_hal_.lock()->getNanIfaceName()}};
+}
+
+std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
+    const hidl_string& ifname) {
+  if (!nan_iface_.get() ||
+      (ifname.c_str() != legacy_hal_.lock()->getNanIfaceName())) {
+    return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
+}
+
+std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
+  // TODO(b/31997422): Disallow this based on the chip combination.
+  std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
+  p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
+  return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>>
+WifiChip::getP2pIfaceNamesInternal() {
+  if (!p2p_iface_.get()) {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS),
+          {legacy_hal_.lock()->getP2pIfaceName()}};
+}
+
+std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
+    const hidl_string& ifname) {
+  if (!p2p_iface_.get() ||
+      (ifname.c_str() != legacy_hal_.lock()->getP2pIfaceName())) {
+    return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
+}
+
+std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
+  // TODO(b/31997422): Disallow this based on the chip combination.
+  std::string ifname = legacy_hal_.lock()->getStaIfaceName();
+  sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
+  return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>>
+WifiChip::getStaIfaceNamesInternal() {
+  if (!sta_iface_.get()) {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS),
+          {legacy_hal_.lock()->getStaIfaceName()}};
+}
+
+std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
+    const hidl_string& ifname) {
+  if (!sta_iface_.get() ||
+      (ifname.c_str() != legacy_hal_.lock()->getStaIfaceName())) {
+    return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
+}
+
+std::pair<WifiStatus, sp<IWifiRttController>>
+WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
+  sp<WifiRttController> rtt = new WifiRttController(bound_iface, legacy_hal_);
+  rtt_controllers_.emplace_back(rtt);
+  return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
+}
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace wifi
diff --git a/wifi/1.0/default/wifi_chip.h b/wifi/1.0/default/wifi_chip.h
index dd9117e..47b4d7a 100644
--- a/wifi/1.0/default/wifi_chip.h
+++ b/wifi/1.0/default/wifi_chip.h
@@ -57,6 +57,7 @@
   // All HIDL method implementations should check if the object is still marked
   // valid before processing them.
   void invalidate();
+  bool isValid();
 
   // HIDL methods exposed.
   Return<void> getId(getId_cb hidl_status_cb) override;
@@ -96,6 +97,37 @@
  private:
   void invalidateAndRemoveAllIfaces();
 
+  // Corresponding worker functions for the HIDL methods.
+  std::pair<WifiStatus, ChipId> getIdInternal();
+  WifiStatus registerEventCallbackInternal(
+      const sp<IWifiChipEventCallback>& event_callback);
+  std::pair<WifiStatus, std::vector<ChipMode>> getAvailableModesInternal();
+  WifiStatus configureChipInternal(uint32_t mode_id);
+  std::pair<WifiStatus, uint32_t> getModeInternal();
+  std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
+  requestChipDebugInfoInternal();
+  std::pair<WifiStatus, std::vector<uint8_t>> requestDriverDebugDumpInternal();
+  std::pair<WifiStatus, std::vector<uint8_t>>
+  requestFirmwareDebugDumpInternal();
+  std::pair<WifiStatus, sp<IWifiApIface>> createApIfaceInternal();
+  std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal();
+  std::pair<WifiStatus, sp<IWifiApIface>> getApIfaceInternal(
+      const hidl_string& ifname);
+  std::pair<WifiStatus, sp<IWifiNanIface>> createNanIfaceInternal();
+  std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal();
+  std::pair<WifiStatus, sp<IWifiNanIface>> getNanIfaceInternal(
+      const hidl_string& ifname);
+  std::pair<WifiStatus, sp<IWifiP2pIface>> createP2pIfaceInternal();
+  std::pair<WifiStatus, std::vector<hidl_string>> getP2pIfaceNamesInternal();
+  std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(
+      const hidl_string& ifname);
+  std::pair<WifiStatus, sp<IWifiStaIface>> createStaIfaceInternal();
+  std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
+  std::pair<WifiStatus, sp<IWifiStaIface>> getStaIfaceInternal(
+      const hidl_string& ifname);
+  std::pair<WifiStatus, sp<IWifiRttController>> createRttControllerInternal(
+      const sp<IWifiIface>& bound_iface);
+
   ChipId chip_id_;
   std::weak_ptr<WifiLegacyHal> legacy_hal_;
   std::vector<sp<IWifiChipEventCallback>> event_callbacks_;
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index 65c0782..5bd2454 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -154,12 +154,14 @@
   return std::make_pair(status, buffer.data());
 }
 
-std::pair<wifi_error, std::vector<char>>
+std::pair<wifi_error, std::vector<uint8_t>>
 WifiLegacyHal::requestDriverMemoryDump() {
-  std::vector<char> driver_dump;
+  std::vector<uint8_t> driver_dump;
   on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer,
                                                            int buffer_size) {
-    driver_dump.insert(driver_dump.end(), buffer, buffer + buffer_size);
+    driver_dump.insert(driver_dump.end(),
+                       reinterpret_cast<uint8_t*>(buffer),
+                       reinterpret_cast<uint8_t*>(buffer) + buffer_size);
   };
   wifi_error status = global_func_table_.wifi_get_driver_memory_dump(
       wlan_interface_handle_, {onDriverMemoryDump});
@@ -167,12 +169,14 @@
   return std::make_pair(status, std::move(driver_dump));
 }
 
-std::pair<wifi_error, std::vector<char>>
+std::pair<wifi_error, std::vector<uint8_t>>
 WifiLegacyHal::requestFirmwareMemoryDump() {
-  std::vector<char> firmware_dump;
+  std::vector<uint8_t> firmware_dump;
   on_firmware_memory_dump_internal_callback = [&firmware_dump](
       char* buffer, int buffer_size) {
-    firmware_dump.insert(firmware_dump.end(), buffer, buffer + buffer_size);
+    firmware_dump.insert(firmware_dump.end(),
+                         reinterpret_cast<uint8_t*>(buffer),
+                         reinterpret_cast<uint8_t*>(buffer) + buffer_size);
   };
   wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
       wlan_interface_handle_, {onFirmwareMemoryDump});
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
index 367ff15..21acb92 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -49,8 +49,8 @@
   // Wrappers for all the functions in the legacy HAL function table.
   std::pair<wifi_error, std::string> getDriverVersion();
   std::pair<wifi_error, std::string> getFirmwareVersion();
-  std::pair<wifi_error, std::vector<char>> requestDriverMemoryDump();
-  std::pair<wifi_error, std::vector<char>> requestFirmwareMemoryDump();
+  std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump();
+  std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump();
 
  private:
   static const uint32_t kMaxVersionStringLength;
