wifi: Move legacy HAL implementation
Changes in the CL:
1. Move the legacy HAL implementation from
"frameworks/opt/net/wifi/wifi_hal_legacy" to
"hardware/interfaces/wifi/1.0/default".
2. Renamed the .rc file and the module name in makefile to
conform to the HIDL style guide.
Files renamed from:
wifi_hal_service.cpp/h -> wifi.cpp/h
wifi_chip_service.cpp/h -> wifi_chip.cpp/h
main.cpp -> service
Bug: 31821133
Test: mmma -j32 hardware/interfaces/wifi/1.0/default
Change-Id: I5e65e2fdb5596346bde6963588031dcea42d633a
diff --git a/wifi/1.0/default/Android.mk b/wifi/1.0/default/Android.mk
new file mode 100644
index 0000000..6180efd
--- /dev/null
+++ b/wifi/1.0/default/Android.mk
@@ -0,0 +1,55 @@
+# 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.
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_CPPFLAGS := -std=c++11 -Wall -Wno-unused-parameter -Werror -Wextra
+LOCAL_SRC_FILES := \
+ failure_reason_util.cpp \
+ wifi_chip.cpp \
+ wifi.cpp \
+ wifi_hal_state.cpp
+LOCAL_SHARED_LIBRARIES := \
+ android.hardware.wifi@1.0 \
+ libbase \
+ libcutils \
+ libhidl \
+ libhwbinder \
+ liblog \
+ libnl \
+ libutils
+LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL)
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi@1.0-service
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_CPPFLAGS := -std=c++11 -Wall -Wno-unused-parameter -Werror -Wextra
+LOCAL_SRC_FILES := \
+ service.cpp
+LOCAL_SHARED_LIBRARIES := \
+ android.hardware.wifi@1.0 \
+ android.hardware.wifi@1.0-impl \
+ libbase \
+ libcutils \
+ libhidl \
+ libhwbinder \
+ liblog \
+ libnl \
+ libutils
+LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL)
+LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
+include $(BUILD_EXECUTABLE)
diff --git a/wifi/1.0/default/android.hardware.wifi@1.0-service.rc b/wifi/1.0/default/android.hardware.wifi@1.0-service.rc
new file mode 100644
index 0000000..9d09347
--- /dev/null
+++ b/wifi/1.0/default/android.hardware.wifi@1.0-service.rc
@@ -0,0 +1,4 @@
+service wifi_hal_legacy /system/bin/hw/android.hardware.wifi@1.0-service
+ class hal
+ user wifi
+ group wifi
diff --git a/wifi/1.0/default/failure_reason_util.cpp b/wifi/1.0/default/failure_reason_util.cpp
new file mode 100644
index 0000000..7fd2269
--- /dev/null
+++ b/wifi/1.0/default/failure_reason_util.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "failure_reason_util.h"
+
+using ::android::hardware::wifi::V1_0::CommandFailureReason;
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+std::string LegacyErrorToString(wifi_error error) {
+ switch(error) {
+ case WIFI_SUCCESS:
+ return "SUCCESS";
+ case WIFI_ERROR_UNINITIALIZED:
+ return "UNINITIALIZED";
+ case WIFI_ERROR_NOT_AVAILABLE:
+ return "NOT_AVAILABLE";
+ case WIFI_ERROR_NOT_SUPPORTED:
+ return "NOT_SUPPORTED";
+ case WIFI_ERROR_INVALID_ARGS:
+ return "INVALID_ARGS";
+ case WIFI_ERROR_INVALID_REQUEST_ID:
+ return "INVALID_REQUEST_ID";
+ case WIFI_ERROR_TIMED_OUT:
+ return "TIMED_OUT";
+ case WIFI_ERROR_TOO_MANY_REQUESTS:
+ return "TOO_MANY_REQUESTS";
+ case WIFI_ERROR_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case WIFI_ERROR_UNKNOWN:
+ default:
+ return "UNKNOWN";
+ }
+}
+
+V1_0::FailureReason CreateFailureReason(
+ CommandFailureReason reason, const std::string& description) {
+ V1_0::FailureReason result;
+ result.reason = reason;
+ result.description = description.data();
+ return result;
+}
+
+V1_0::FailureReason CreateFailureReasonLegacyError(
+ wifi_error error, const std::string& desc) {
+ switch(error) {
+ case WIFI_ERROR_UNINITIALIZED:
+ case WIFI_ERROR_NOT_AVAILABLE:
+ return CreateFailureReason(CommandFailureReason::NOT_AVAILABLE, desc);
+
+ case WIFI_ERROR_NOT_SUPPORTED:
+ return CreateFailureReason(CommandFailureReason::NOT_SUPPORTED, desc);
+
+ case WIFI_ERROR_INVALID_ARGS:
+ case WIFI_ERROR_INVALID_REQUEST_ID:
+ return CreateFailureReason(CommandFailureReason::INVALID_ARGS, desc);
+
+ case WIFI_ERROR_TIMED_OUT:
+ return CreateFailureReason(
+ CommandFailureReason::UNKNOWN, desc + ", timed out");
+
+ case WIFI_ERROR_TOO_MANY_REQUESTS:
+ return CreateFailureReason(
+ CommandFailureReason::UNKNOWN, desc + ", too many requests");
+
+ case WIFI_ERROR_OUT_OF_MEMORY:
+ return CreateFailureReason(
+ CommandFailureReason::UNKNOWN, desc + ", out of memory");
+
+ case WIFI_ERROR_NONE:
+ case WIFI_ERROR_UNKNOWN:
+ default:
+ return CreateFailureReason(CommandFailureReason::UNKNOWN, "unknown");
+ }
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/1.0/default/failure_reason_util.h b/wifi/1.0/default/failure_reason_util.h
new file mode 100644
index 0000000..d731700
--- /dev/null
+++ b/wifi/1.0/default/failure_reason_util.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef FAILURE_REASON_UTIL_H_
+#define FAILURE_REASON_UTIL_H_
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <hardware_legacy/wifi_hal.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+std::string LegacyErrorToString(wifi_error error);
+
+V1_0::FailureReason CreateFailureReason(
+ V1_0::CommandFailureReason reason, const std::string& description);
+V1_0::FailureReason CreateFailureReasonLegacyError(
+ wifi_error error, const std::string& description);
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // FAILURE_REASON_UTIL_H_
diff --git a/wifi/1.0/default/service.cpp b/wifi/1.0/default/service.cpp
new file mode 100644
index 0000000..a96584b
--- /dev/null
+++ b/wifi/1.0/default/service.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 <android-base/logging.h>
+#include <hidl/IServiceManager.h>
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+#include "wifi.h"
+
+using android::hardware::hidl_version;
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
+using android::Looper;
+
+namespace {
+int OnBinderReadReady(int /*fd*/, int /*events*/, void* /*data*/) {
+ IPCThreadState::self()->handlePolledCommands();
+ return 1; // continue receiving events
+}
+}
+
+int main(int /*argc*/, char** argv) {
+ android::base::InitLogging(
+ argv, android::base::LogdLogger(android::base::SYSTEM));
+ LOG(INFO) << "wifi_hal_legacy is starting up...";
+
+ // Setup binder
+ int binder_fd = -1;
+ ProcessState::self()->setThreadPoolMaxThreadCount(0);
+ CHECK_EQ(IPCThreadState::self()->setupPolling(&binder_fd),
+ android::NO_ERROR) << "Failed to initialize binder polling";
+ CHECK_GE(binder_fd, 0) << "Invalid binder FD: " << binder_fd;
+
+ // Setup looper
+ android::sp<Looper> looper = Looper::prepare(0 /* no options */);
+ CHECK(looper->addFd(
+ binder_fd, 0, Looper::EVENT_INPUT, OnBinderReadReady, nullptr))
+ << "Failed to watch binder FD";
+
+ // Setup hwbinder service
+ android::sp<android::hardware::wifi::Wifi> service =
+ new android::hardware::wifi::Wifi(looper);
+ CHECK_EQ(service->registerAsService("wifi"),
+ android::NO_ERROR) << "Failed to register wifi HAL";
+
+ // Loop
+ while (looper->pollAll(-1) != Looper::POLL_ERROR);
+
+ LOG(INFO) << "wifi_hal_legacy is terminating...";
+ return 0;
+}
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
diff --git a/wifi/1.0/default/wifi.h b/wifi/1.0/default/wifi.h
new file mode 100644
index 0000000..92712fd
--- /dev/null
+++ b/wifi/1.0/default/wifi.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_H_
+#define WIFI_H_
+
+#include <functional>
+#include <set>
+#include <thread>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android-base/macros.h>
+#include <hardware_legacy/wifi_hal.h>
+#include <utils/Looper.h>
+
+#include "wifi_hal_state.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class WifiChip;
+
+class Wifi : public V1_0::IWifi {
+ public:
+ Wifi(sp<Looper>& looper);
+
+ Return<void> registerEventCallback(
+ const sp<V1_0::IWifiEventCallback>& callback) override;
+
+ Return<bool> isStarted() override;
+ Return<void> start() override;
+ Return<void> stop() override;
+
+ Return<void> getChip(getChip_cb cb) override;
+
+ private:
+ const wifi_interface_handle kInterfaceNotFoundHandle = nullptr;
+ /** Get a HAL interface handle by name */
+ wifi_interface_handle FindInterfaceHandle(const std::string& ifname);
+
+ /**
+ * Called to indicate that the HAL implementation cleanup may be complete and
+ * the rest of HAL cleanup should be performed.
+ */
+ void FinishHalCleanup();
+
+ /**
+ * Entry point for HAL event loop thread. Handles cleanup when terminating.
+ */
+ void DoHalEventLoop();
+
+ std::set<sp<V1_0::IWifiEventCallback>> callbacks_;
+ sp<WifiChip> chip_;
+
+ WifiHalState state_;
+ std::thread event_loop_thread_;
+
+ // Variables to hold state while stopping the HAL
+ bool awaiting_hal_cleanup_command_;
+ bool awaiting_hal_event_loop_termination_;
+
+ DISALLOW_COPY_AND_ASSIGN(Wifi);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_H_
diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.0/default/wifi_chip.cpp
new file mode 100644
index 0000000..e794f53
--- /dev/null
+++ b/wifi/1.0/default/wifi_chip.cpp
@@ -0,0 +1,116 @@
+/*
+ * 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_chip.h"
+
+#include <android-base/logging.h>
+
+#include "failure_reason_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+WifiChip::WifiChip(
+ WifiHalState* hal_state, wifi_interface_handle interface_handle)
+ : hal_state_(hal_state), interface_handle_(interface_handle) {}
+
+void WifiChip::Invalidate() {
+ hal_state_ = nullptr;
+ callbacks_.clear();
+}
+
+Return<void> WifiChip::registerEventCallback(
+ const sp<V1_0::IWifiChipEventCallback>& callback) {
+ if (!hal_state_) return Void();
+ // TODO(b/31632518): remove the callback when the client is destroyed
+ callbacks_.insert(callback);
+ return Void();
+}
+
+Return<void> WifiChip::getAvailableModes(getAvailableModes_cb cb) {
+ if (!hal_state_) {
+ cb(hidl_vec<ChipMode>());
+ return Void();
+ } else {
+ // TODO add implementation
+ return Void();
+ }
+}
+
+Return<void> WifiChip::configureChip(uint32_t /*mode_id*/) {
+ if (!hal_state_) return Void();
+ // TODO add implementation
+ return Void();
+}
+
+Return<uint32_t> WifiChip::getMode() {
+ if (!hal_state_) return 0;
+ // TODO add implementation
+ return 0;
+}
+
+Return<void> WifiChip::requestChipDebugInfo() {
+ if (!hal_state_) return Void();
+
+ V1_0::IWifiChipEventCallback::ChipDebugInfo result;
+ result.driverDescription = "<unknown>";
+ result.firmwareDescription = "<unknown>";
+ char buffer[256];
+
+ // get driver version
+ bzero(buffer, sizeof(buffer));
+ wifi_error ret = hal_state_->func_table_.wifi_get_driver_version(
+ interface_handle_, buffer, sizeof(buffer));
+ if (ret == WIFI_SUCCESS) {
+ result.driverDescription = buffer;
+ } else {
+ LOG(WARNING) << "Failed to get driver version: "
+ << LegacyErrorToString(ret);
+ }
+
+ // get firmware version
+ bzero(buffer, sizeof(buffer));
+ ret = hal_state_->func_table_.wifi_get_firmware_version(
+ interface_handle_, buffer, sizeof(buffer));
+ if (ret == WIFI_SUCCESS) {
+ result.firmwareDescription = buffer;
+ } else {
+ LOG(WARNING) << "Failed to get firmware version: "
+ << LegacyErrorToString(ret);
+ }
+
+ // send callback
+ for (auto& callback : callbacks_) {
+ callback->onChipDebugInfoAvailable(result);
+ }
+ return Void();
+}
+
+Return<void> WifiChip::requestDriverDebugDump() {
+ // TODO implement
+ return Void();
+}
+
+Return<void> WifiChip::requestFirmwareDebugDump() {
+ // TODO implement
+ return Void();
+}
+
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/1.0/default/wifi_chip.h b/wifi/1.0/default/wifi_chip.h
new file mode 100644
index 0000000..583c151
--- /dev/null
+++ b/wifi/1.0/default/wifi_chip.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_CHIP_H_
+#define WIFI_CHIP_H_
+
+#include <set>
+
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android-base/macros.h>
+#include <hardware_legacy/wifi_hal.h>
+
+#include "wifi_hal_state.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class WifiChip : public V1_0::IWifiChip {
+ public:
+ WifiChip(
+ WifiHalState* hal_state, wifi_interface_handle interface_handle);
+
+ void Invalidate();
+
+ Return<void> registerEventCallback(
+ const sp<V1_0::IWifiChipEventCallback>& callback) override;
+
+ Return<void> getAvailableModes(getAvailableModes_cb cb) override;
+
+ Return<void> configureChip(uint32_t mode_id) override;
+
+ Return<uint32_t> getMode() override;
+
+ Return<void> requestChipDebugInfo() override;
+
+ Return<void> requestDriverDebugDump() override;
+
+ Return<void> requestFirmwareDebugDump() override;
+
+ private:
+ WifiHalState* hal_state_;
+ wifi_interface_handle interface_handle_;
+ std::set<sp<V1_0::IWifiChipEventCallback>> callbacks_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiChip);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_CHIP_H_
diff --git a/wifi/1.0/default/wifi_hal_state.cpp b/wifi/1.0/default/wifi_hal_state.cpp
new file mode 100644
index 0000000..11387d8
--- /dev/null
+++ b/wifi/1.0/default/wifi_hal_state.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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_hal_state.h"
+
+#include <android-base/logging.h>
+#include <hardware_legacy/wifi_hal.h>
+#include <utils/Looper.h>
+
+namespace {
+class FunctionMessageHandler : public android::MessageHandler {
+ public:
+ explicit FunctionMessageHandler(const std::function<void()>& callback)
+ : callback_(callback) {
+ }
+
+ ~FunctionMessageHandler() override = default;
+
+ virtual void handleMessage(const android::Message& /*message*/) {
+ callback_();
+ }
+
+ private:
+ const std::function<void()> callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(FunctionMessageHandler);
+};
+}
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+WifiHalState::WifiHalState(sp<Looper>& looper)
+ : run_state_(RunState::STOPPED), looper_(looper) {}
+
+void WifiHalState::PostTask(const std::function<void()>& callback) {
+ sp<MessageHandler> message_handler =
+ new FunctionMessageHandler(callback);
+ looper_->sendMessage(message_handler, NULL);
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/1.0/default/wifi_hal_state.h b/wifi/1.0/default/wifi_hal_state.h
new file mode 100644
index 0000000..6b9fc53
--- /dev/null
+++ b/wifi/1.0/default/wifi_hal_state.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_HAL_LEGACY_WIFI_HAL_STATE_H_
+#define WIFI_HAL_LEGACY_WIFI_HAL_STATE_H_
+
+#include <functional>
+
+#include <android-base/macros.h>
+#include <hardware_legacy/wifi_hal.h>
+#include <utils/Looper.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * Class that stores common state and functionality shared between HAL services.
+ */
+class WifiHalState {
+ public:
+ WifiHalState(sp<Looper>& looper);
+
+ /** Post a task to be executed on the main thread */
+ void PostTask(const std::function<void()>& callback);
+
+ wifi_hal_fn func_table_;
+ /** opaque handle from vendor for use while HAL is running */
+ wifi_handle hal_handle_;
+
+ enum class RunState {
+ STOPPED,
+ STARTED,
+ STOPPING
+ };
+
+ RunState run_state_;
+
+ private:
+ sp<Looper> looper_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiHalState);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_HAL_LEGACY_WIFI_HAL_STATE_H_