wifi: Restructure wifi legacy HAL implementation am: aabe575536
am: e9301b4c57
am: 79ddd9f48b
am: fcf91b089f
Change-Id: I1e372b2c5bd94ec02d31e281c92107729cf66981
This commit is contained in:
commit
289a0f0462
10 changed files with 281 additions and 314 deletions
|
@ -21,7 +21,7 @@ LOCAL_SRC_FILES := \
|
|||
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 \
|
||||
|
|
|
@ -55,13 +55,14 @@ int main(int /*argc*/, char** argv) {
|
|||
|
||||
// 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;
|
||||
|
|
|
@ -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<void> Wifi::registerEventCallback(
|
|||
}
|
||||
|
||||
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();
|
||||
|
|
|
@ -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 wifi {
|
|||
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);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
enum class RunState { STOPPED, STARTED, STOPPING };
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
|
|
@ -26,18 +26,17 @@ namespace wifi {
|
|||
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::registerEventCallback(
|
|||
}
|
||||
|
||||
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::getAvailableModes(getAvailableModes_cb cb) {
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 wifi {
|
|||
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);
|
||||
|
||||
void Invalidate();
|
||||
WifiChip(std::weak_ptr<WifiLegacyHal> legacy_hal);
|
||||
// Invalidate this instance once the HAL is stopped.
|
||||
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);
|
||||
|
|
|
@ -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
|
|
@ -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_
|
139
wifi/1.0/default/wifi_legacy_hal.cpp
Normal file
139
wifi/1.0/default/wifi_legacy_hal.cpp
Normal file
|
@ -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
|
67
wifi/1.0/default/wifi_legacy_hal.h
Normal file
67
wifi/1.0/default/wifi_legacy_hal.h
Normal file
|
@ -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_
|
Loading…
Reference in a new issue