wifi: Restructure wifi legacy HAL implementation
Restructured the existing code to create a new class called
|WifiLegacyHal|. This class will be used as a wrapper to invoke
all the legacy HAL functions and handle the "C" style callbacks.
Bug: 31936700
Test: mmma -j32 hardware/interfaces/wifi/1.0/default
Change-Id: I63e8543f49886f8446101320a97d1e96e30d1035
diff --git a/wifi/1.0/default/Android.mk b/wifi/1.0/default/Android.mk
index 6180efd..14923f5 100644
--- a/wifi/1.0/default/Android.mk
+++ b/wifi/1.0/default/Android.mk
@@ -21,7 +21,7 @@
failure_reason_util.cpp \
wifi_chip.cpp \
wifi.cpp \
- wifi_hal_state.cpp
+ wifi_legacy_hal.cpp
LOCAL_SHARED_LIBRARIES := \
android.hardware.wifi@1.0 \
libbase \
diff --git a/wifi/1.0/default/service.cpp b/wifi/1.0/default/service.cpp
index 07e6c81..10ce1db 100644
--- a/wifi/1.0/default/service.cpp
+++ b/wifi/1.0/default/service.cpp
@@ -55,13 +55,14 @@
// Setup hwbinder service
android::sp<android::hardware::wifi::V1_0::IWifi> service =
- new android::hardware::wifi::V1_0::implementation::Wifi(looper);
+ new android::hardware::wifi::V1_0::implementation::Wifi();
CHECK_EQ(service->registerAsService("wifi"), android::NO_ERROR)
<< "Failed to register wifi HAL";
// Loop
- while (looper->pollAll(-1) != Looper::POLL_ERROR)
- ;
+ while (looper->pollAll(-1) != Looper::POLL_ERROR) {
+ // Keep polling until failure.
+ }
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
index aa0fc5b..d5b69b8 100644
--- a/wifi/1.0/default/wifi.cpp
+++ b/wifi/1.0/default/wifi.cpp
@@ -17,31 +17,18 @@
#include "wifi.h"
#include <android-base/logging.h>
-#include <cutils/properties.h>
#include "failure_reason_util.h"
#include "wifi_chip.h"
-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 {
namespace V1_0 {
namespace implementation {
-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";
-}
+Wifi::Wifi()
+ : legacy_hal_(new WifiLegacyHal()), run_state_(RunState::STOPPED) {}
Return<void> Wifi::registerEventCallback(
const sp<IWifiEventCallback>& callback) {
@@ -51,131 +38,76 @@
}
Return<bool> Wifi::isStarted() {
- return state_.run_state_ != RunState::STOPPED;
+ return run_state_ != RunState::STOPPED;
}
Return<void> Wifi::start() {
- if (state_.run_state_ == RunState::STARTED) {
- for (auto& callback : callbacks_) {
+ if (run_state_ == RunState::STARTED) {
+ for (const auto& callback : callbacks_) {
callback->onStart();
}
return Void();
- } else if (state_.run_state_ == RunState::STOPPING) {
- for (auto& callback : callbacks_) {
+ } else if (run_state_ == RunState::STOPPING) {
+ for (const 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_);
+ LOG(INFO) << "Starting HAL";
+ wifi_error status = legacy_hal_->start();
if (status != WIFI_SUCCESS) {
- LOG(ERROR) << "Failed to initialize Wifi HAL";
+ LOG(ERROR) << "Failed to start Wifi HAL";
for (auto& callback : callbacks_) {
callback->onStartFailure(
- CreateFailureReasonLegacyError(status, "Failed to initialize HAL"));
+ CreateFailureReasonLegacyError(status, "Failed to start 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_) {
+ // Create the chip instance once the HAL is started.
+ chip_ = new WifiChip(legacy_hal_);
+ run_state_ = RunState::STARTED;
+ for (const 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_) {
+ if (run_state_ == RunState::STOPPED) {
+ for (const auto& callback : callbacks_) {
callback->onStop();
}
return Void();
- } else if (state_.run_state_ == RunState::STOPPING) {
+ } else if (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();
+ LOG(INFO) << "Stopping HAL";
+ run_state_ = RunState::STOPPING;
+ const auto on_complete_callback_ = [&]() {
+ if (chip_.get()) {
+ chip_->invalidate();
+ }
+ chip_.clear();
+ run_state_ = RunState::STOPPED;
+ for (const auto& callback : callbacks_) {
+ callback->onStop();
+ }
+ };
+ wifi_error status = legacy_hal_->stop(on_complete_callback_);
+ if (status != WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to stop Wifi HAL";
+ for (const auto& callback : callbacks_) {
+ callback->onFailure(
+ CreateFailureReasonLegacyError(status, "Failed to stop HAL"));
+ }
+ }
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();
diff --git a/wifi/1.0/default/wifi.h b/wifi/1.0/default/wifi.h
index 0122741..e6cf1ac 100644
--- a/wifi/1.0/default/wifi.h
+++ b/wifi/1.0/default/wifi.h
@@ -19,15 +19,13 @@
#include <functional>
#include <set>
-#include <thread>
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifi.h>
-#include <hardware_legacy/wifi_hal.h>
#include <utils/Looper.h>
-#include "wifi_hal_state.h"
#include "wifi_chip.h"
+#include "wifi_legacy_hal.h"
namespace android {
namespace hardware {
@@ -35,45 +33,31 @@
namespace V1_0 {
namespace implementation {
+/**
+ * Root HIDL interface object used to control the Wifi HAL.
+ */
class Wifi : public IWifi {
public:
- Wifi(sp<Looper>& looper);
+ Wifi();
+ // HIDL methods exposed.
Return<void> registerEventCallback(
const sp<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);
+ enum class RunState { STOPPED, STARTED, STOPPING };
- /**
- * 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();
-
+ // Instance is created in this root level |IWifi| HIDL interface object
+ // and shared with all the child HIDL interface objects.
+ std::shared_ptr<WifiLegacyHal> legacy_hal_;
+ RunState run_state_;
std::set<sp<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);
};
diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.0/default/wifi_chip.cpp
index 42118b7..91cf514 100644
--- a/wifi/1.0/default/wifi_chip.cpp
+++ b/wifi/1.0/default/wifi_chip.cpp
@@ -26,18 +26,17 @@
namespace V1_0 {
namespace implementation {
-WifiChip::WifiChip(WifiHalState* hal_state,
- wifi_interface_handle interface_handle)
- : hal_state_(hal_state), interface_handle_(interface_handle) {}
+WifiChip::WifiChip(std::weak_ptr<WifiLegacyHal> legacy_hal)
+ : legacy_hal_(legacy_hal) {}
-void WifiChip::Invalidate() {
- hal_state_ = nullptr;
+void WifiChip::invalidate() {
+ legacy_hal_.reset();
callbacks_.clear();
}
Return<void> WifiChip::registerEventCallback(
const sp<IWifiChipEventCallback>& callback) {
- if (!hal_state_)
+ if (!legacy_hal_.lock())
return Void();
// TODO(b/31632518): remove the callback when the client is destroyed
callbacks_.insert(callback);
@@ -45,7 +44,7 @@
}
Return<void> WifiChip::getAvailableModes(getAvailableModes_cb cb) {
- if (!hal_state_) {
+ if (!legacy_hal_.lock()) {
cb(hidl_vec<ChipMode>());
return Void();
} else {
@@ -55,54 +54,23 @@
}
Return<void> WifiChip::configureChip(uint32_t /*mode_id*/) {
- if (!hal_state_)
+ if (!legacy_hal_.lock())
return Void();
// TODO add implementation
return Void();
}
Return<uint32_t> WifiChip::getMode() {
- if (!hal_state_)
+ if (!legacy_hal_.lock())
return 0;
// TODO add implementation
return 0;
}
Return<void> WifiChip::requestChipDebugInfo() {
- if (!hal_state_)
+ if (!legacy_hal_.lock())
return Void();
-
- 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);
- }
+ // TODO add implementation
return Void();
}
diff --git a/wifi/1.0/default/wifi_chip.h b/wifi/1.0/default/wifi_chip.h
index d776644..95fabe4 100644
--- a/wifi/1.0/default/wifi_chip.h
+++ b/wifi/1.0/default/wifi_chip.h
@@ -21,9 +21,8 @@
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifiChip.h>
-#include <hardware_legacy/wifi_hal.h>
-#include "wifi_hal_state.h"
+#include "wifi_legacy_hal.h"
namespace android {
namespace hardware {
@@ -31,30 +30,29 @@
namespace V1_0 {
namespace implementation {
+/**
+ * HIDL interface object used to control a Wifi HAL chip instance.
+ * Since there is only a single chip instance used today, there is no
+ * identifying handle information stored here.
+ */
class WifiChip : public IWifiChip {
public:
- WifiChip(WifiHalState* hal_state, wifi_interface_handle interface_handle);
+ WifiChip(std::weak_ptr<WifiLegacyHal> legacy_hal);
+ // Invalidate this instance once the HAL is stopped.
+ void invalidate();
- void Invalidate();
-
+ // HIDL methods exposed.
Return<void> registerEventCallback(
const sp<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::weak_ptr<WifiLegacyHal> legacy_hal_;
std::set<sp<IWifiChipEventCallback>> callbacks_;
DISALLOW_COPY_AND_ASSIGN(WifiChip);
diff --git a/wifi/1.0/default/wifi_hal_state.cpp b/wifi/1.0/default/wifi_hal_state.cpp
deleted file mode 100644
index 1483689..0000000
--- a/wifi/1.0/default/wifi_hal_state.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 {
-namespace V1_0 {
-namespace implementation {
-
-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 implementation
-} // namespace V1_0
-} // 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
deleted file mode 100644
index 40e39ec..0000000
--- a/wifi/1.0/default/wifi_hal_state.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 {
-namespace V1_0 {
-namespace implementation {
-
-/**
- * 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 implementation
-} // namespace V1_0
-} // namespace wifi
-} // namespace hardware
-} // namespace android
-
-#endif // WIFI_HAL_LEGACY_WIFI_HAL_STATE_H_
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
new file mode 100644
index 0000000..a9ad0d1
--- /dev/null
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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 <array>
+
+#include "failure_reason_util.h"
+#include "wifi_legacy_hal.h"
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+namespace {
+std::string getWlanInterfaceName() {
+ char buffer[PROPERTY_VALUE_MAX];
+ property_get("wifi.interface", buffer, "wlan0");
+ return buffer;
+}
+
+// Legacy HAL functions accept "C" style function pointers, so use global
+// functions to pass to the legacy HAL function and store the corresponding
+// std::function methods to be invoked.
+// Callback to be invoked once |stop| is complete.
+std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
+void onStopComplete(wifi_handle handle) {
+ if (on_stop_complete_internal_callback) {
+ on_stop_complete_internal_callback(handle);
+ }
+}
+}
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_0 {
+namespace implementation {
+
+WifiLegacyHal::WifiLegacyHal()
+ : global_handle_(nullptr),
+ wlan_interface_handle_(nullptr),
+ awaiting_event_loop_termination_(false) {
+ CHECK_EQ(init_wifi_vendor_hal_func_table(&global_func_table_), WIFI_SUCCESS)
+ << "Failed to initialize legacy hal function table";
+}
+
+wifi_error WifiLegacyHal::start() {
+ // Ensure that we're starting in a good state.
+ CHECK(!global_handle_ && !wlan_interface_handle_ &&
+ !awaiting_event_loop_termination_);
+
+ LOG(INFO) << "Starting legacy HAL";
+ wifi_error status = global_func_table_.wifi_initialize(&global_handle_);
+ if (status != WIFI_SUCCESS || !global_handle_) {
+ LOG(ERROR) << "Failed to retrieve global handle";
+ return status;
+ }
+ event_loop_thread_ = std::thread(&WifiLegacyHal::runEventLoop, this);
+ status = retrieveWlanInterfaceHandle();
+ if (status != WIFI_SUCCESS || !wlan_interface_handle_) {
+ LOG(ERROR) << "Failed to retrieve wlan interface handle";
+ return status;
+ }
+ LOG(VERBOSE) << "Legacy HAL start complete";
+ return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::stop(
+ const std::function<void()>& on_stop_complete_user_callback) {
+ LOG(INFO) << "Stopping legacy HAL";
+ on_stop_complete_internal_callback = [&](wifi_handle handle) {
+ CHECK_EQ(global_handle_, handle) << "Handle mismatch";
+ on_stop_complete_user_callback();
+ global_handle_ = nullptr;
+ wlan_interface_handle_ = nullptr;
+ on_stop_complete_internal_callback = nullptr;
+ };
+ awaiting_event_loop_termination_ = true;
+ global_func_table_.wifi_cleanup(global_handle_, onStopComplete);
+ LOG(VERBOSE) << "Legacy HAL stop initiated";
+ return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::retrieveWlanInterfaceHandle() {
+ const std::string& ifname_to_find = getWlanInterfaceName();
+
+ wifi_interface_handle* iface_handles = nullptr;
+ int num_iface_handles = 0;
+ wifi_error status = global_func_table_.wifi_get_ifaces(
+ global_handle_, &num_iface_handles, &iface_handles);
+ if (status != WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to enumerate interface handles: "
+ << LegacyErrorToString(status);
+ return status;
+ }
+ for (int i = 0; i < num_iface_handles; ++i) {
+ std::array<char, IFNAMSIZ> current_ifname;
+ current_ifname.fill(0);
+ status = global_func_table_.wifi_get_iface_name(
+ iface_handles[i], current_ifname.data(), current_ifname.size());
+ if (status != WIFI_SUCCESS) {
+ LOG(WARNING) << "Failed to get interface handle name: "
+ << LegacyErrorToString(status);
+ continue;
+ }
+ if (ifname_to_find == current_ifname.data()) {
+ wlan_interface_handle_ = iface_handles[i];
+ return WIFI_SUCCESS;
+ }
+ }
+ return WIFI_ERROR_UNKNOWN;
+}
+
+void WifiLegacyHal::runEventLoop() {
+ LOG(VERBOSE) << "Starting legacy HAL event loop";
+ global_func_table_.wifi_event_loop(global_handle_);
+ if (!awaiting_event_loop_termination_) {
+ LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
+ }
+ LOG(VERBOSE) << "Legacy HAL event loop terminated";
+ awaiting_event_loop_termination_ = false;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
new file mode 100644
index 0000000..1af9f1a
--- /dev/null
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -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.
+ */
+
+#ifndef WIFI_LEGACY_WIFI_HAL_H_
+#define WIFI_LEGACY_WIFI_HAL_H_
+
+#include <functional>
+#include <thread>
+
+#include <hardware_legacy/wifi_hal.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_0 {
+namespace implementation {
+
+/**
+ * Class that encapsulates all legacy HAL interactions.
+ * This class manages the lifetime of the event loop thread used by legacy HAL.
+ */
+class WifiLegacyHal {
+ public:
+ WifiLegacyHal();
+ // Initialize the legacy HAL and start the event looper thread.
+ wifi_error start();
+ // Deinitialize the legacy HAL and stop the event looper thread.
+ wifi_error stop(const std::function<void()>& on_complete_callback);
+
+ private:
+ // Retrieve the interface handle to be used for the "wlan" interface.
+ wifi_error retrieveWlanInterfaceHandle();
+ // Run the legacy HAL event loop thread.
+ void runEventLoop();
+
+ // Event loop thread used by legacy HAL.
+ std::thread event_loop_thread_;
+ // Global function table of legacy HAL.
+ wifi_hal_fn global_func_table_;
+ // Opaque handle to be used for all global operations.
+ wifi_handle global_handle_;
+ // Opaque handle to be used for all wlan0 interface specific operations.
+ wifi_interface_handle wlan_interface_handle_;
+ // Flag to indicate if we have initiated the cleanup of legacy HAL.
+ bool awaiting_event_loop_termination_;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_LEGACY_WIFI_HAL_H_