We would like to reason about our interfaces as being up
when they are configured and ready for use, and down otherwise.
This helps when switching modes. For example, when setting up a SoftAP,
you can expect that the interface starts in a down state, and
transitions to up when hostapd is ready for business. Note that we
cannot do this after firmware reload, because this may cause driver
de-initialization (see c#6 in b/
31205821).
Bug:
31337216
Test: Integration tests pass
Change-Id: I03a71ea623e29ef9b023d97afc81cf836ebfb1ff
libbase \
libbinder \
libcutils \
libbase \
libbinder \
libcutils \
+ libutils \
+ libwifi-system
LOCAL_STATIC_LIBRARIES := \
libgmock \
libwificond_ipc \
LOCAL_STATIC_LIBRARIES := \
libgmock \
libwificond_ipc \
ApInterfaceImpl::~ApInterfaceImpl() {
binder_->NotifyImplDead();
ApInterfaceImpl::~ApInterfaceImpl() {
binder_->NotifyImplDead();
+ if_tool_->SetUpState(interface_name_.c_str(), false);
}
sp<IApInterface> ApInterfaceImpl::GetBinder() const {
}
sp<IApInterface> ApInterfaceImpl::GetBinder() const {
using android::net::wifi::IClientInterface;
using android::sp;
using android::net::wifi::IClientInterface;
using android::sp;
+using android::wifi_system::InterfaceTool;
using android::wifi_system::SupplicantManager;
using namespace std::placeholders;
using android::wifi_system::SupplicantManager;
using namespace std::placeholders;
const std::string& interface_name,
uint32_t interface_index,
const std::vector<uint8_t>& interface_mac_addr,
const std::string& interface_name,
uint32_t interface_index,
const std::vector<uint8_t>& interface_mac_addr,
+ InterfaceTool* if_tool,
SupplicantManager* supplicant_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
: interface_name_(interface_name),
interface_index_(interface_index),
interface_mac_addr_(interface_mac_addr),
SupplicantManager* supplicant_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
: interface_name_(interface_name),
interface_index_(interface_index),
interface_mac_addr_(interface_mac_addr),
supplicant_manager_(supplicant_manager),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils),
supplicant_manager_(supplicant_manager),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils),
binder_->NotifyImplDead();
DisableSupplicant();
scan_utils_->UnsubscribeScanResultNotification(interface_index_);
binder_->NotifyImplDead();
DisableSupplicant();
scan_utils_->UnsubscribeScanResultNotification(interface_index_);
+ if_tool_->SetUpState(interface_name_.c_str(), false);
}
sp<android::net::wifi::IClientInterface> ClientInterfaceImpl::GetBinder() const {
}
sp<android::net::wifi::IClientInterface> ClientInterfaceImpl::GetBinder() const {
#include <android-base/macros.h>
#include <utils/StrongPointer.h>
#include <android-base/macros.h>
#include <utils/StrongPointer.h>
+#include <wifi_system/interface_tool.h>
#include <wifi_system/supplicant_manager.h>
#include "android/net/wifi/IClientInterface.h"
#include <wifi_system/supplicant_manager.h>
#include "android/net/wifi/IClientInterface.h"
const std::string& interface_name,
uint32_t interface_index,
const std::vector<uint8_t>& interface_mac_addr,
const std::string& interface_name,
uint32_t interface_index,
const std::vector<uint8_t>& interface_mac_addr,
+ android::wifi_system::InterfaceTool* if_tool,
android::wifi_system::SupplicantManager* supplicant_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils);
android::wifi_system::SupplicantManager* supplicant_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils);
const std::string interface_name_;
const uint32_t interface_index_;
const std::vector<uint8_t> interface_mac_addr_;
const std::string interface_name_;
const uint32_t interface_index_;
const std::vector<uint8_t> interface_mac_addr_;
+ android::wifi_system::InterfaceTool* const if_tool_;
android::wifi_system::SupplicantManager* const supplicant_manager_;
NetlinkUtils* const netlink_utils_;
ScanUtils* const scan_utils_;
android::wifi_system::SupplicantManager* const supplicant_manager_;
NetlinkUtils* const netlink_utils_;
ScanUtils* const scan_utils_;
interface_name,
interface_index,
interface_mac_addr,
interface_name,
interface_index,
interface_mac_addr,
supplicant_manager_.get(),
netlink_utils_,
scan_utils_));
supplicant_manager_.get(),
netlink_utils_,
scan_utils_));
EXPECT_CALL(*if_tool_, SetUpState(StrEq(kTestInterfaceName), false))
.WillOnce(Return(true));
EXPECT_TRUE(ap_interface_.StopHostapd());
EXPECT_CALL(*if_tool_, SetUpState(StrEq(kTestInterfaceName), false))
.WillOnce(Return(true));
EXPECT_TRUE(ap_interface_.StopHostapd());
+ testing::Mock::VerifyAndClearExpectations(if_tool_.get());
}
TEST_F(ApInterfaceImplTest, ShouldRejectInvalidConfig) {
}
TEST_F(ApInterfaceImplTest, ShouldRejectInvalidConfig) {
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <wifi_system/supplicant_manager.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <wifi_system/supplicant_manager.h>
+#include <wifi_system_test/mock_interface_tool.h>
#include <wifi_system_test/mock_supplicant_manager.h>
#include "wificond/client_interface_impl.h"
#include <wifi_system_test/mock_supplicant_manager.h>
#include "wificond/client_interface_impl.h"
#include "wificond/tests/mock_netlink_utils.h"
#include "wificond/tests/mock_scan_utils.h"
#include "wificond/tests/mock_netlink_utils.h"
#include "wificond/tests/mock_scan_utils.h"
+using android::wifi_system::MockInterfaceTool;
using android::wifi_system::MockSupplicantManager;
using android::wifi_system::SupplicantManager;
using std::unique_ptr;
using android::wifi_system::MockSupplicantManager;
using android::wifi_system::SupplicantManager;
using std::unique_ptr;
kTestInterfaceName,
kTestInterfaceIndex,
vector<uint8_t>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
kTestInterfaceName,
kTestInterfaceIndex,
vector<uint8_t>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
supplicant_manager_.get(),
&netlink_utils_,
&scan_utils_});
supplicant_manager_.get(),
&netlink_utils_,
&scan_utils_});
UnsubscribeScanResultNotification(kTestInterfaceIndex));
}
UnsubscribeScanResultNotification(kTestInterfaceIndex));
}
+ unique_ptr<NiceMock<MockInterfaceTool>> if_tool_{
+ new NiceMock<MockInterfaceTool>};
unique_ptr<NiceMock<MockSupplicantManager>> supplicant_manager_{
new NiceMock<MockSupplicantManager>};
unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
unique_ptr<NiceMock<MockSupplicantManager>> supplicant_manager_{
new NiceMock<MockSupplicantManager>};
unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
+#include <wifi_system/interface_tool.h>
#include "android/net/wifi/IApInterface.h"
#include "android/net/wifi/IWificond.h"
#include "android/net/wifi/IApInterface.h"
#include "android/net/wifi/IWificond.h"
using android::net::wifi::IApInterface;
using android::net::wifi::IWificond;
using android::net::wifi::IApInterface;
using android::net::wifi::IWificond;
+using android::wifi_system::InterfaceTool;
using android::wificond::tests::integration::HostapdIsDead;
using android::wificond::tests::integration::HostapdIsRunning;
using android::wificond::tests::integration::ScopedDevModeWificond;
using android::wificond::tests::integration::WaitForTrue;
using android::wificond::tests::integration::HostapdIsDead;
using android::wificond::tests::integration::HostapdIsRunning;
using android::wificond::tests::integration::ScopedDevModeWificond;
using android::wificond::tests::integration::WaitForTrue;
using std::vector;
namespace android {
using std::vector;
namespace android {
EXPECT_TRUE(service->createApInterface(&ap_interface).isOk());
EXPECT_NE(nullptr, ap_interface.get());
EXPECT_TRUE(service->createApInterface(&ap_interface).isOk());
EXPECT_NE(nullptr, ap_interface.get());
+ // The interface should start out down.
+ string if_name;
+ EXPECT_TRUE(ap_interface->getInterfaceName(&if_name).isOk());
+ EXPECT_TRUE(!if_name.empty());
+ InterfaceTool if_tool;
+ EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
+
+ // Mark the interface as up, just to test that we mark it down on teardown.
+ EXPECT_TRUE(if_tool.SetUpState(if_name.c_str(), true));
+ EXPECT_TRUE(if_tool.GetUpState(if_name.c_str()));
+
// We should not be able to create two AP interfaces.
sp<IApInterface> ap_interface2;
EXPECT_TRUE(service->createApInterface(&ap_interface2).isOk());
// We should not be able to create two AP interfaces.
sp<IApInterface> ap_interface2;
EXPECT_TRUE(service->createApInterface(&ap_interface2).isOk());
// We can tear down the created interface.
EXPECT_TRUE(service->tearDownInterfaces().isOk());
// We can tear down the created interface.
EXPECT_TRUE(service->tearDownInterfaces().isOk());
+ EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
}
// TODO: b/30311493 this test fails because hostapd fails to set the driver
}
// TODO: b/30311493 this test fails because hostapd fails to set the driver
EXPECT_TRUE(service->createApInterface(&ap_interface).isOk());
ASSERT_NE(nullptr, ap_interface.get());
EXPECT_TRUE(service->createApInterface(&ap_interface).isOk());
ASSERT_NE(nullptr, ap_interface.get());
+ // Interface should start out down.
+ string if_name;
+ EXPECT_TRUE(ap_interface->getInterfaceName(&if_name).isOk());
+ EXPECT_TRUE(!if_name.empty());
+ InterfaceTool if_tool;
+ EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
+
bool wrote_config = false;
EXPECT_TRUE(ap_interface->writeHostapdConfig(
vector<uint8_t>(kValidSsid, kValidSsid + sizeof(kValidSsid) - 1),
bool wrote_config = false;
EXPECT_TRUE(ap_interface->writeHostapdConfig(
vector<uint8_t>(kValidSsid, kValidSsid + sizeof(kValidSsid) - 1),
// can leave the driver in a poor state.
// The latter points to an obvious race, where we cannot fully clean up the
// driver on quick transitions.
// can leave the driver in a poor state.
// The latter points to an obvious race, where we cannot fully clean up the
// driver on quick transitions.
+ auto InterfaceIsUp = [&if_tool, &if_name] () {
+ return if_tool.GetUpState(if_name.c_str());
+ };
+ EXPECT_TRUE(WaitForTrue(InterfaceIsUp, kHostapdStartupTimeoutSeconds))
+ << "Failed on iteration " << iteration;
EXPECT_TRUE(HostapdIsRunning()) << "Failed on iteration " << iteration;
bool hostapd_stopped = false;
EXPECT_TRUE(ap_interface->stopHostapd(&hostapd_stopped).isOk());
EXPECT_TRUE(hostapd_stopped);
EXPECT_TRUE(HostapdIsRunning()) << "Failed on iteration " << iteration;
bool hostapd_stopped = false;
EXPECT_TRUE(ap_interface->stopHostapd(&hostapd_stopped).isOk());
EXPECT_TRUE(hostapd_stopped);
+ EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
+
EXPECT_TRUE(WaitForTrue(HostapdIsDead, kHostapdDeathTimeoutSeconds))
<< "Failed on iteration " << iteration;
EXPECT_TRUE(WaitForTrue(HostapdIsDead, kHostapdDeathTimeoutSeconds))
<< "Failed on iteration " << iteration;
* limitations under the License.
*/
* limitations under the License.
*/
#include <vector>
#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
#include <vector>
#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
+#include <wifi_system/interface_tool.h>
#include "android/net/wifi/IClientInterface.h"
#include "android/net/wifi/IWificond.h"
#include "android/net/wifi/IClientInterface.h"
#include "android/net/wifi/IWificond.h"
using android::net::wifi::IClientInterface;
using android::net::wifi::IWificond;
using android::net::wifi::IClientInterface;
using android::net::wifi::IWificond;
+using android::wifi_system::InterfaceTool;
using android::wificond::tests::integration::ScopedDevModeWificond;
using android::wificond::tests::integration::SupplicantIsDead;
using android::wificond::tests::integration::SupplicantIsRunning;
using android::wificond::tests::integration::WaitForTrue;
using android::wificond::tests::integration::ScopedDevModeWificond;
using android::wificond::tests::integration::SupplicantIsDead;
using android::wificond::tests::integration::SupplicantIsRunning;
using android::wificond::tests::integration::WaitForTrue;
using std::vector;
namespace android {
using std::vector;
namespace android {
EXPECT_TRUE(service->createClientInterface(&client_interface).isOk());
EXPECT_NE(nullptr, client_interface.get());
EXPECT_TRUE(service->createClientInterface(&client_interface).isOk());
EXPECT_NE(nullptr, client_interface.get());
+ // The interface should start out down.
+ string if_name;
+ EXPECT_TRUE(client_interface->getInterfaceName(&if_name).isOk());
+ EXPECT_TRUE(!if_name.empty());
+ InterfaceTool if_tool;
+ EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
+
+ // Mark the interface as up, just to test that we mark it down on teardown.
+ EXPECT_TRUE(if_tool.SetUpState(if_name.c_str(), true));
+ EXPECT_TRUE(if_tool.GetUpState(if_name.c_str()));
+
// We should not be able to create two client interfaces.
sp<IClientInterface> client_interface2;
EXPECT_TRUE(service->createClientInterface(&client_interface2).isOk());
// We should not be able to create two client interfaces.
sp<IClientInterface> client_interface2;
EXPECT_TRUE(service->createClientInterface(&client_interface2).isOk());
// We can tear down the created interface.
EXPECT_TRUE(service->tearDownInterfaces().isOk());
// We can tear down the created interface.
EXPECT_TRUE(service->tearDownInterfaces().isOk());
+ EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
}
TEST(ClientInterfaceTest, CanStartStopSupplicant) {
}
TEST(ClientInterfaceTest, CanStartStopSupplicant) {