Use additional interface for the WiFi Aware Discovery operations.
NAN operations are currently done on the STA interface.This resulted in the NAN sessions getting terminated in all the instances where the STA interface is restarted (IFF DOWN/UP), due to connected MAC randomization. Hence, remove the dependency of NAN over STA interface. This change expects the driver to create a dedicated interface for the NAN operations. The iface name needs to be set in "wifi.aware.interface" property. Bug: 1636219 Test: HAL unit tests Test: Device boots up and connects to wifi network. Change-Id: I1b6d64eb94334172a8cd621d0b15ed8c8dc87f91
This commit is contained in:
parent
432974a63e
commit
5ba0a90cac
11 changed files with 82 additions and 15 deletions
|
@ -156,6 +156,11 @@ LOCAL_SRC_FILES := \
|
|||
LOCAL_STATIC_LIBRARIES := \
|
||||
libgmock \
|
||||
libgtest \
|
||||
android.hardware.wifi@1.0 \
|
||||
android.hardware.wifi@1.1 \
|
||||
android.hardware.wifi@1.2 \
|
||||
android.hardware.wifi@1.3 \
|
||||
android.hardware.wifi@1.4 \
|
||||
android.hardware.wifi@1.0-service-lib
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbase \
|
||||
|
@ -165,10 +170,5 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
libnl \
|
||||
libutils \
|
||||
libwifi-hal \
|
||||
libwifi-system-iface \
|
||||
android.hardware.wifi@1.0 \
|
||||
android.hardware.wifi@1.1 \
|
||||
android.hardware.wifi@1.2 \
|
||||
android.hardware.wifi@1.3 \
|
||||
android.hardware.wifi@1.4
|
||||
libwifi-system-iface
|
||||
include $(BUILD_NATIVE_TEST)
|
||||
|
|
|
@ -40,6 +40,7 @@ class MockWifiIfaceUtil : public WifiIfaceUtil {
|
|||
MOCK_METHOD2(registerIfaceEventHandlers,
|
||||
void(const std::string&, IfaceEventHandlers));
|
||||
MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
|
||||
MOCK_METHOD2(setUpState, bool(const std::string&, bool));
|
||||
};
|
||||
} // namespace iface_util
|
||||
} // namespace implementation
|
||||
|
|
|
@ -57,6 +57,10 @@ class MockWifiLegacyHal : public WifiLegacyHal {
|
|||
MOCK_METHOD3(nanDataInterfaceDelete,
|
||||
wifi_error(const std::string&, transaction_id,
|
||||
const std::string&));
|
||||
MOCK_METHOD2(createVirtualInterface,
|
||||
wifi_error(const std::string& ifname,
|
||||
wifi_interface_type iftype));
|
||||
MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
|
||||
};
|
||||
} // namespace legacy_hal
|
||||
} // namespace implementation
|
||||
|
|
|
@ -292,6 +292,7 @@ class WifiChipTest : public Test {
|
|||
// mock).
|
||||
property_set("wifi.interface", "wlan0");
|
||||
property_set("wifi.concurrent.interface", "wlan1");
|
||||
property_set("wifi.aware.interface", nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -773,6 +774,28 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest,
|
|||
});
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
|
||||
property_set("wifi.aware.interface", nullptr);
|
||||
findModeAndConfigureForIfaceType(IfaceType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
|
||||
removeIface(IfaceType::NAN, "wlan0");
|
||||
EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0);
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) {
|
||||
property_set("wifi.aware.interface", "aware0");
|
||||
findModeAndConfigureForIfaceType(IfaceType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
EXPECT_CALL(*iface_util_, setUpState("aware0", true))
|
||||
.WillOnce(testing::Return(true));
|
||||
ASSERT_EQ(createIface(IfaceType::NAN), "aware0");
|
||||
|
||||
EXPECT_CALL(*iface_util_, setUpState("aware0", false))
|
||||
.WillOnce(testing::Return(true));
|
||||
removeIface(IfaceType::NAN, "aware0");
|
||||
}
|
||||
|
||||
////////// V1 Iface Combinations when AP creation is disabled //////////
|
||||
class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
|
|
|
@ -131,7 +131,7 @@ TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
|
|||
bind(CaptureIfaceEventHandlers, std::placeholders::_1,
|
||||
std::placeholders::_2, &captured_iface_event_handlers)));
|
||||
sp<WifiNanIface> nan_iface =
|
||||
new WifiNanIface(kIfaceName, legacy_hal_, iface_util_);
|
||||
new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_);
|
||||
|
||||
// Register a mock nan event callback.
|
||||
sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
|
||||
|
|
|
@ -107,6 +107,15 @@ std::string getP2pIfaceName() {
|
|||
return buffer.data();
|
||||
}
|
||||
|
||||
// Returns the dedicated iface name if one is defined.
|
||||
std::string getNanIfaceName() {
|
||||
std::array<char, PROPERTY_VALUE_MAX> buffer;
|
||||
if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
|
||||
return {};
|
||||
}
|
||||
return buffer.data();
|
||||
}
|
||||
|
||||
void setActiveWlanIfaceNameProperty(const std::string& ifname) {
|
||||
auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
|
||||
if (res != 0) {
|
||||
|
@ -864,9 +873,16 @@ std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
|
|||
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
|
||||
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
|
||||
}
|
||||
// These are still assumed to be based on wlan0.
|
||||
std::string ifname = getFirstActiveWlanIfaceName();
|
||||
sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_, iface_util_);
|
||||
bool is_dedicated_iface = true;
|
||||
std::string ifname = getNanIfaceName();
|
||||
if (ifname.empty()) {
|
||||
// Use the first shared STA iface (wlan0) if a dedicated aware iface is
|
||||
// not defined.
|
||||
ifname = getFirstActiveWlanIfaceName();
|
||||
is_dedicated_iface = false;
|
||||
}
|
||||
sp<WifiNanIface> iface =
|
||||
new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
|
||||
nan_ifaces_.push_back(iface);
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
|
||||
|
|
|
@ -110,6 +110,14 @@ std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
|
|||
address[0] &= ~kMacAddressMulticastMask;
|
||||
return address;
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
|
||||
if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
|
||||
LOG(ERROR) << "SetUpState to " << request_up << " failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace iface_util
|
||||
} // namespace implementation
|
||||
} // namespace V1_4
|
||||
|
|
|
@ -56,6 +56,7 @@ class WifiIfaceUtil {
|
|||
virtual void registerIfaceEventHandlers(const std::string& iface_name,
|
||||
IfaceEventHandlers handlers);
|
||||
virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
|
||||
virtual bool setUpState(const std::string& iface_name, bool request_up);
|
||||
|
||||
private:
|
||||
std::array<uint8_t, 6> createRandomMacAddress();
|
||||
|
|
|
@ -373,9 +373,9 @@ class WifiLegacyHal {
|
|||
std::array<int8_t, 2> code);
|
||||
|
||||
// interface functions.
|
||||
wifi_error createVirtualInterface(const std::string& ifname,
|
||||
wifi_interface_type iftype);
|
||||
wifi_error deleteVirtualInterface(const std::string& ifname);
|
||||
virtual wifi_error createVirtualInterface(const std::string& ifname,
|
||||
wifi_interface_type iftype);
|
||||
virtual wifi_error deleteVirtualInterface(const std::string& ifname);
|
||||
|
||||
private:
|
||||
// Retrieve interface handles for all the available interfaces.
|
||||
|
|
|
@ -29,13 +29,22 @@ namespace implementation {
|
|||
using hidl_return_util::validateAndCall;
|
||||
|
||||
WifiNanIface::WifiNanIface(
|
||||
const std::string& ifname,
|
||||
const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
|
||||
: ifname_(ifname),
|
||||
is_dedicated_iface_(is_dedicated_iface),
|
||||
legacy_hal_(legacy_hal),
|
||||
iface_util_(iface_util),
|
||||
is_valid_(true) {
|
||||
if (is_dedicated_iface_) {
|
||||
// If using a dedicated iface, set the iface up first.
|
||||
if (!iface_util_.lock()->setUpState(ifname_, true)) {
|
||||
// Fatal failure, invalidate the iface object.
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
|
@ -534,6 +543,10 @@ void WifiNanIface::invalidate() {
|
|||
event_cb_handler_.invalidate();
|
||||
event_cb_handler_1_2_.invalidate();
|
||||
is_valid_ = false;
|
||||
if (is_dedicated_iface_) {
|
||||
// If using a dedicated iface, set the iface down.
|
||||
iface_util_.lock()->setUpState(ifname_, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiNanIface::isValid() { return is_valid_; }
|
||||
|
|
|
@ -38,7 +38,7 @@ using namespace android::hardware::wifi::V1_2;
|
|||
*/
|
||||
class WifiNanIface : public V1_4::IWifiNanIface {
|
||||
public:
|
||||
WifiNanIface(const std::string& ifname,
|
||||
WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
|
||||
// Refer to |WifiChip::invalidate()|.
|
||||
|
@ -165,6 +165,7 @@ class WifiNanIface : public V1_4::IWifiNanIface {
|
|||
std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
|
||||
|
||||
std::string ifname_;
|
||||
bool is_dedicated_iface_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
|
||||
bool is_valid_;
|
||||
|
|
Loading…
Reference in a new issue