diff --git a/wifi/1.0/default/wifi.cpp b/wifi/1.0/default/wifi.cpp
new file mode 100644
index 0000000..0e10bfb
--- /dev/null
+++ b/wifi/1.0/default/wifi.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "wifi.h"
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include "failure_reason_util.h"
+#include "wifi_chip.h"
+
+using ::android::hardware::wifi::V1_0::CommandFailureReason;
+using RunState = ::android::hardware::wifi::WifiHalState::RunState;
+
+namespace {
+std::string GetWlanInterfaceName() {
+  char buffer[PROPERTY_VALUE_MAX];
+  property_get("wifi.interface", buffer, "wlan0");
+  return buffer;
+}
+}
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+Wifi::Wifi(sp<Looper>& looper) : state_(looper) {
+  CHECK_EQ(init_wifi_vendor_hal_func_table(&state_.func_table_), WIFI_SUCCESS)
+      << "Failed to initialize hal func table";
+}
+
+Return<void> Wifi::registerEventCallback(
+    const sp<V1_0::IWifiEventCallback>& callback) {
+  // TODO(b/31632518): remove the callback when the client is destroyed
+  callbacks_.insert(callback);
+  return Void();
+}
+
+Return<bool> Wifi::isStarted() {
+  return state_.run_state_ != RunState::STOPPED;
+}
+
+Return<void> Wifi::start() {
+  if (state_.run_state_ == RunState::STARTED) {
+    for (auto& callback : callbacks_) {
+      callback->onStart();
+    }
+    return Void();
+  } else if (state_.run_state_ == RunState::STOPPING) {
+    for (auto& callback : callbacks_) {
+      callback->onStartFailure(CreateFailureReason(
+          CommandFailureReason::NOT_AVAILABLE, "HAL is stopping"));
+    }
+    return Void();
+  }
+
+  LOG(INFO) << "Initializing HAL";
+  wifi_error status = state_.func_table_.wifi_initialize(&state_.hal_handle_);
+  if (status != WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to initialize Wifi HAL";
+    for (auto& callback : callbacks_) {
+      callback->onStartFailure(CreateFailureReasonLegacyError(
+          status, "Failed to initialize HAL"));
+    }
+    return Void();
+  }
+
+  event_loop_thread_ = std::thread(&Wifi::DoHalEventLoop, this);
+
+  wifi_interface_handle iface_handle =
+      FindInterfaceHandle(GetWlanInterfaceName());
+  if (iface_handle != kInterfaceNotFoundHandle) {
+    chip_ = new WifiChip(&state_, iface_handle);
+  } else {
+    // TODO fail to init?
+  }
+
+  state_.run_state_ = RunState::STARTED;
+  for (auto& callback : callbacks_) {
+    callback->onStart();
+  }
+  return Void();
+}
+
+wifi_interface_handle Wifi::FindInterfaceHandle(
+    const std::string& ifname) {
+  int num_iface_handles = 0;
+  wifi_interface_handle* iface_handles = nullptr;
+  wifi_error ret = state_.func_table_.wifi_get_ifaces(
+      state_.hal_handle_, &num_iface_handles, &iface_handles);
+  if (ret != WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to enumerate interface handles: "
+               << LegacyErrorToString(ret);
+    return kInterfaceNotFoundHandle;
+  }
+
+  char buffer[IFNAMSIZ];
+  for (int i = 0; i < num_iface_handles; ++i) {
+    bzero(buffer, sizeof(buffer));
+    ret = state_.func_table_.wifi_get_iface_name(
+        iface_handles[i], buffer, sizeof(buffer));
+    if (ret != WIFI_SUCCESS) {
+      LOG(WARNING) << "Failed to get interface handle name: "
+                   << LegacyErrorToString(ret);
+      continue;
+    }
+    if (ifname == buffer) {
+      return iface_handles[i];
+    }
+  }
+  return kInterfaceNotFoundHandle;
+}
+
+
+void NoopHalCleanupHandler(wifi_handle) {}
+
+Return<void> Wifi::stop() {
+  if (state_.run_state_ == RunState::STOPPED) {
+    for (auto& callback : callbacks_) {
+      callback->onStop();
+    }
+    return Void();
+  } else if (state_.run_state_ == RunState::STOPPING) {
+    return Void();
+  }
+
+  LOG(INFO) << "Cleaning up HAL";
+  awaiting_hal_cleanup_command_ = true;
+  awaiting_hal_event_loop_termination_ = true;
+  state_.run_state_ = RunState::STOPPING;
+
+  if (chip_.get()) chip_->Invalidate();
+  chip_.clear();
+
+  state_.func_table_.wifi_cleanup(state_.hal_handle_, NoopHalCleanupHandler);
+  awaiting_hal_cleanup_command_ = false;
+  LOG(VERBOSE) << "HAL cleanup command complete";
+  FinishHalCleanup();
+  return Void();
+}
+
+void Wifi::DoHalEventLoop() {
+  LOG(VERBOSE) << "Starting HAL event loop";
+  state_.func_table_.wifi_event_loop(state_.hal_handle_);
+  if (state_.run_state_ != RunState::STOPPING) {
+    LOG(FATAL) << "HAL event loop terminated, but HAL was not stopping";
+  }
+  LOG(VERBOSE) << "HAL Event loop terminated";
+  event_loop_thread_.detach();
+  state_.PostTask([this](){
+      awaiting_hal_event_loop_termination_ = false;
+      FinishHalCleanup();
+    });
+}
+
+void Wifi::FinishHalCleanup() {
+  if (!awaiting_hal_cleanup_command_ && !awaiting_hal_event_loop_termination_) {
+    state_.run_state_ = RunState::STOPPED;
+    LOG(INFO) << "HAL cleanup complete";
+    for (auto& callback : callbacks_) {
+      callback->onStop();
+    }
+  }
+}
+
+
+Return<void> Wifi::getChip(getChip_cb cb) {
+  cb(chip_);
+  return Void();
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
