Merge changes I760dc5ca,Ia2da1dcf into qt-dev
* changes: wifi(implementation): Send NAN disabled on wlan0 down & up wifi(implementation): Invalidate NAN iface on STA iface removal
This commit is contained in:
commit
c733f3bbed
9 changed files with 166 additions and 6 deletions
|
@ -700,6 +700,72 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
|
|||
});
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest,
|
||||
InvalidateAndRemoveNanOnStaRemove) {
|
||||
findModeAndConfigureForIfaceType(IfaceType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
|
||||
// Create NAN iface
|
||||
ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
|
||||
|
||||
// We should have 1 nan iface.
|
||||
chip_->getNanIfaceNames(
|
||||
[](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
|
||||
ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
|
||||
ASSERT_EQ(iface_names.size(), 1u);
|
||||
ASSERT_EQ(iface_names[0], "wlan0");
|
||||
});
|
||||
// Retrieve the exact iface object.
|
||||
sp<IWifiNanIface> nan_iface;
|
||||
chip_->getNanIface("wlan0", [&nan_iface](const WifiStatus& status,
|
||||
const sp<IWifiNanIface>& iface) {
|
||||
ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
|
||||
ASSERT_NE(iface.get(), nullptr);
|
||||
nan_iface = iface;
|
||||
});
|
||||
|
||||
// Remove the STA iface.
|
||||
removeIface(IfaceType::STA, "wlan0");
|
||||
// We should have 0 nan iface now.
|
||||
chip_->getNanIfaceNames(
|
||||
[](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
|
||||
ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
|
||||
ASSERT_EQ(iface_names.size(), 0u);
|
||||
});
|
||||
// Any operation on the nan iface object should return error now.
|
||||
nan_iface->getName(
|
||||
[](const WifiStatus& status, const std::string& /* iface_name */) {
|
||||
ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest,
|
||||
InvalidateAndRemoveRttControllerOnStaRemove) {
|
||||
findModeAndConfigureForIfaceType(IfaceType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
|
||||
// Create RTT controller
|
||||
sp<IWifiRttController> rtt_controller;
|
||||
chip_->createRttController(
|
||||
NULL, [&rtt_controller](const WifiStatus& status,
|
||||
const sp<IWifiRttController>& rtt) {
|
||||
if (WifiStatusCode::SUCCESS == status.code) {
|
||||
ASSERT_NE(rtt.get(), nullptr);
|
||||
rtt_controller = rtt;
|
||||
}
|
||||
});
|
||||
|
||||
// Remove the STA iface.
|
||||
removeIface(IfaceType::STA, "wlan0");
|
||||
|
||||
// Any operation on the rtt controller object should return error now.
|
||||
rtt_controller->getBoundIface(
|
||||
[](const WifiStatus& status, const sp<IWifiIface>& /* iface */) {
|
||||
ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
status.code);
|
||||
});
|
||||
}
|
||||
|
||||
////////// V1 Iface Combinations when AP creation is disabled //////////
|
||||
class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
|
@ -732,6 +798,7 @@ TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest,
|
|||
ASSERT_TRUE(createIface(IfaceType::AP).empty());
|
||||
}
|
||||
|
||||
////////// Hypothetical Iface Combination with multiple ifaces //////////
|
||||
class WifiChip_MultiIfaceTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
|
|
|
@ -634,6 +634,27 @@ void WifiChip::invalidateAndRemoveAllIfaces() {
|
|||
rtt_controllers_.clear();
|
||||
}
|
||||
|
||||
void WifiChip::invalidateAndRemoveDependencies(
|
||||
const std::string& removed_iface_name) {
|
||||
for (const auto& nan_iface : nan_ifaces_) {
|
||||
if (nan_iface->getName() == removed_iface_name) {
|
||||
invalidateAndClear(nan_ifaces_, nan_iface);
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
if (!callback
|
||||
->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto& rtt : rtt_controllers_) {
|
||||
if (rtt->getIfaceName() == removed_iface_name) {
|
||||
invalidateAndClear(rtt_controllers_, rtt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
|
||||
return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
|
||||
}
|
||||
|
@ -819,6 +840,11 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
|
|||
if (!iface.get()) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
// Invalidate & remove any dependent objects first.
|
||||
// Note: This is probably not required because we never create
|
||||
// nan/rtt objects over AP iface. But, there is no harm to do it
|
||||
// here and not make that assumption all over the place.
|
||||
invalidateAndRemoveDependencies(ifname);
|
||||
invalidateAndClear(ap_ifaces_, iface);
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
|
||||
|
@ -835,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()) {
|
||||
|
@ -960,6 +986,8 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
|
|||
if (!iface.get()) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
// Invalidate & remove any dependent objects first.
|
||||
invalidateAndRemoveDependencies(ifname);
|
||||
invalidateAndClear(sta_ifaces_, iface);
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
|
||||
|
|
|
@ -155,6 +155,9 @@ class WifiChip : public V1_3::IWifiChip {
|
|||
|
||||
private:
|
||||
void invalidateAndRemoveAllIfaces();
|
||||
// When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
|
||||
// invalidated & removed.
|
||||
void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
|
||||
|
||||
// Corresponding worker functions for the HIDL methods.
|
||||
std::pair<WifiStatus, ChipId> getIdInternal();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -49,6 +49,8 @@ WifiRttController::getEventCallbacks() {
|
|||
return event_callbacks_;
|
||||
}
|
||||
|
||||
std::string WifiRttController::getIfaceName() { return ifname_; }
|
||||
|
||||
Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
|
||||
return validateAndCall(
|
||||
this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
|
|
|
@ -42,6 +42,7 @@ class WifiRttController : public V1_0::IWifiRttController {
|
|||
void invalidate();
|
||||
bool isValid();
|
||||
std::vector<sp<IWifiRttControllerEventCallback>> getEventCallbacks();
|
||||
std::string getIfaceName();
|
||||
|
||||
// HIDL methods exposed.
|
||||
Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;
|
||||
|
|
Loading…
Reference in a new issue