From 356d5a6ed2163a85173bd1d414b29f7634e68bd2 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 17 May 2019 15:07:34 -0700 Subject: [PATCH] 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 --- wifi/1.3/default/wifi_chip.cpp | 2 +- wifi/1.3/default/wifi_iface_util.cpp | 21 ++++++++++++++++++- wifi/1.3/default/wifi_iface_util.h | 13 ++++++++++++ wifi/1.3/default/wifi_nan_iface.cpp | 30 +++++++++++++++++++++++++--- wifi/1.3/default/wifi_nan_iface.h | 5 ++++- 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp index 27320c407b..6c2fd678da 100644 --- a/wifi/1.3/default/wifi_chip.cpp +++ b/wifi/1.3/default/wifi_chip.cpp @@ -861,7 +861,7 @@ std::pair> WifiChip::createNanIfaceInternal() { } // These are still assumed to be based on wlan0. std::string ifname = getFirstActiveWlanIfaceName(); - sp iface = new WifiNanIface(ifname, legacy_hal_); + sp 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()) { diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.3/default/wifi_iface_util.cpp index 5d61271410..7042af0b87 100644 --- a/wifi/1.3/default/wifi_iface_util.cpp +++ b/wifi/1.3/default/wifi_iface_util.cpp @@ -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 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 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 WifiIfaceUtil::createRandomMacAddress() { std::array address = {}; std::random_device rd; diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.3/default/wifi_iface_util.h index b2382344ed..325fbe8390 100644 --- a/wifi/1.3/default/wifi_iface_util.h +++ b/wifi/1.3/default/wifi_iface_util.h @@ -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 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 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 createRandomMacAddress(); wifi_system::InterfaceTool iface_tool_; std::unique_ptr> random_mac_address_; + std::map event_handlers_map_; }; } // namespace iface_util diff --git a/wifi/1.3/default/wifi_nan_iface.cpp b/wifi/1.3/default/wifi_nan_iface.cpp index 4325f44dad..ff9f4224df 100644 --- a/wifi/1.3/default/wifi_nan_iface.cpp +++ b/wifi/1.3/default/wifi_nan_iface.cpp @@ -30,8 +30,12 @@ using hidl_return_util::validateAndCall; WifiNanIface::WifiNanIface( const std::string& ifname, - const std::weak_ptr legacy_hal) - : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) { + const std::weak_ptr legacy_hal, + const std::weak_ptr 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(); diff --git a/wifi/1.3/default/wifi_nan_iface.h b/wifi/1.3/default/wifi_nan_iface.h index f735d61cf9..737be93217 100644 --- a/wifi/1.3/default/wifi_nan_iface.h +++ b/wifi/1.3/default/wifi_nan_iface.h @@ -22,6 +22,7 @@ #include #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); + const std::weak_ptr legacy_hal, + const std::weak_ptr 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_; + std::weak_ptr iface_util_; bool is_valid_; hidl_callback_util::HidlCallbackHandler event_cb_handler_;