wifi(implementation): Send NAN disabled on wlan0 down & up

When the iface state is toggled for MAC address change on the underlying
interface for NAN operations, send NAN disabled event up to the
framework. The iface down/up toggle resets all NAN operations in the
firmware. So, this callback should trigger a cleanup of any
operations initiated by the framework.

Bug: 132943959
Test: Unit tests in the follow-up CL.
Test: Will send for regression tests.
Change-Id: I760dc5ca3b9276956f5edd40a97c3c13811f442c
This commit is contained in:
Roshan Pius 2019-05-17 15:07:34 -07:00
parent 8236850bc0
commit 356d5a6ed2
5 changed files with 65 additions and 6 deletions

View file

@ -861,7 +861,7 @@ std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
}
// These are still assumed to be based on wlan0.
std::string ifname = getFirstActiveWlanIfaceName();
sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_, iface_util_);
nan_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {

View file

@ -39,7 +39,8 @@ namespace V1_3 {
namespace implementation {
namespace iface_util {
WifiIfaceUtil::WifiIfaceUtil() : random_mac_address_(nullptr) {}
WifiIfaceUtil::WifiIfaceUtil()
: random_mac_address_(nullptr), event_handlers_map_() {}
std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
const std::string& iface_name) {
@ -60,6 +61,14 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
LOG(ERROR) << "SetUpState(true) failed.";
return false;
}
IfaceEventHandlers event_handlers = {};
const auto it = event_handlers_map_.find(iface_name);
if (it != event_handlers_map_.end()) {
event_handlers = it->second;
}
if (event_handlers.on_state_toggle_off_on != nullptr) {
event_handlers.on_state_toggle_off_on(iface_name);
}
LOG(DEBUG) << "Successfully SetMacAddress.";
return true;
}
@ -73,6 +82,16 @@ std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
return *random_mac_address_.get();
}
void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
IfaceEventHandlers handlers) {
event_handlers_map_[iface_name] = handlers;
}
void WifiIfaceUtil::unregisterIfaceEventHandlers(
const std::string& iface_name) {
event_handlers_map_.erase(iface_name);
}
std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
std::array<uint8_t, 6> address = {};
std::random_device rd;

View file

@ -28,6 +28,13 @@ namespace V1_3 {
namespace implementation {
namespace iface_util {
// Iface event handlers.
struct IfaceEventHandlers {
// Callback to be invoked when the iface is set down & up for MAC address
// change.
std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
};
/**
* Util class for common iface operations.
*/
@ -45,11 +52,17 @@ class WifiIfaceUtil {
// daemon. (So, changes on every reboot)
virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
// Register for any iface event callbacks for the provided interface.
virtual void registerIfaceEventHandlers(const std::string& iface_name,
IfaceEventHandlers handlers);
virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
private:
std::array<uint8_t, 6> createRandomMacAddress();
wifi_system::InterfaceTool iface_tool_;
std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
std::map<std::string, IfaceEventHandlers> event_handlers_map_;
};
} // namespace iface_util

View file

@ -30,8 +30,12 @@ using hidl_return_util::validateAndCall;
WifiNanIface::WifiNanIface(
const std::string& ifname,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
: ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
: ifname_(ifname),
legacy_hal_(legacy_hal),
iface_util_(iface_util),
is_valid_(true) {
// Register all the callbacks here. these should be valid for the lifetime
// of the object. Whenever the mode changes legacy HAL will remove
// all of these callbacks.
@ -498,6 +502,26 @@ WifiNanIface::WifiNanIface(
LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
invalidate();
}
// Register for iface state toggle events.
iface_util::IfaceEventHandlers event_handlers = {};
event_handlers.on_state_toggle_off_on =
[weak_ptr_this](const std::string& /* iface_name */) {
const auto shared_ptr_this = weak_ptr_this.promote();
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
LOG(ERROR) << "Callback invoked on an invalid object";
return;
}
// Tell framework that NAN has been disabled.
WifiNanStatus status = {
NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
if (!callback->eventDisabled(status).isOk()) {
LOG(ERROR) << "Failed to invoke the callback";
}
}
};
iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
}
void WifiNanIface::invalidate() {
@ -505,7 +529,7 @@ void WifiNanIface::invalidate() {
legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
legacy_hal_.reset();
event_cb_handler_.invalidate();
event_cb_handler_1_2_.invalidate();

View file

@ -22,6 +22,7 @@
#include <android/hardware/wifi/1.2/IWifiNanIface.h>
#include "hidl_callback_util.h"
#include "wifi_iface_util.h"
#include "wifi_legacy_hal.h"
namespace android {
@ -37,7 +38,8 @@ using namespace android::hardware::wifi::V1_0;
class WifiNanIface : public V1_2::IWifiNanIface {
public:
WifiNanIface(const std::string& ifname,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
// Refer to |WifiChip::invalidate()|.
void invalidate();
bool isValid();
@ -147,6 +149,7 @@ class WifiNanIface : public V1_2::IWifiNanIface {
std::string ifname_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
bool is_valid_;
hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback>
event_cb_handler_;