Loading wifi/1.3/default/tests/wifi_chip_unit_tests.cpp +67 −0 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 { Loading wifi/1.3/default/wifi_chip.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -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_}; } Loading Loading @@ -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()) { Loading @@ -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()) { Loading Loading @@ -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()) { Loading wifi/1.3/default/wifi_chip.h +3 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading wifi/1.3/default/wifi_iface_util.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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; } Loading @@ -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; Loading wifi/1.3/default/wifi_iface_util.h +13 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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 Loading Loading
wifi/1.3/default/tests/wifi_chip_unit_tests.cpp +67 −0 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 { Loading
wifi/1.3/default/wifi_chip.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -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_}; } Loading Loading @@ -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()) { Loading @@ -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()) { Loading Loading @@ -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()) { Loading
wifi/1.3/default/wifi_chip.h +3 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading
wifi/1.3/default/wifi_iface_util.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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; } Loading @@ -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; Loading
wifi/1.3/default/wifi_iface_util.h +13 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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 Loading