/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include "supplicant_hidl_call_util.h" #include "supplicant_hidl_test_utils.h" using ::android::sp; using ::android::hardware::hidl_array; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::wifi::supplicant::V1_0::IfaceType; using ::android::hardware::wifi::supplicant::V1_0::ISupplicant; using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface; using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIfaceCallback; using ::android::hardware::wifi::supplicant::V1_0::SupplicantNetworkId; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::V1_0::IWifi; namespace { constexpr uint8_t kTestSsidPostfix[] = {'t', 'e', 's', 't'}; constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92}; constexpr uint8_t kTestPeerMacAddr[] = {0x56, 0x67, 0x55, 0xf4, 0x56, 0x92}; constexpr uint8_t kTestBonjourServiceQuery[] = {'t', 'e', 's', 't', 'q', 'u', 'e', 'r', 'y'}; constexpr uint8_t kTestBonjourServiceResponse[] = { 't', 'e', 's', 't', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e'}; constexpr uint8_t kTestWfdDeviceInfo[] = {[0 ... 5] = 0x01}; constexpr char kTestConnectPin[] = "34556665"; constexpr char kTestGroupIfName[] = "TestGroup"; constexpr char kTestWpsDeviceName[] = "TestWpsDeviceName"; constexpr char kTestWpsManufacturer[] = "TestManufacturer"; constexpr char kTestWpsModelName[] = "TestModelName"; constexpr char kTestWpsModelNumber[] = "TestModelNumber"; constexpr char kTestWpsSerialNumber[] = "TestSerialNumber"; constexpr char kTestUpnpServiceName[] = "TestServiceName"; constexpr uint8_t kTestWpsDeviceType[] = {[0 ... 7] = 0x01}; constexpr uint16_t kTestWpsConfigMethods = 0xffff; constexpr uint32_t kTestConnectGoIntent = 6; constexpr uint32_t kTestFindTimeout = 5; constexpr uint32_t kTestSetGroupIdleTimeout = 6; constexpr uint32_t kTestChannel = 1; constexpr uint32_t kTestOperatingClass = 81; constexpr uint32_t kTestFreqRange[] = {2412, 2432}; constexpr uint32_t kTestExtListenPeriod = 400; constexpr uint32_t kTestExtListenInterval = 400; constexpr SupplicantNetworkId kTestNetworkId = 5; } // namespace class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_0 { public: virtual void SetUp() override { SupplicantHidlTestBaseV1_0::SetUp(); if (!isP2pOn_) { GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test."; } p2p_iface_ = getSupplicantP2pIface(supplicant_); ASSERT_NE(p2p_iface_.get(), nullptr); memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size()); memcpy(peer_mac_addr_.data(), kTestPeerMacAddr, peer_mac_addr_.size()); } protected: sp p2p_iface_; // MAC address to use for various tests. std::array mac_addr_; std::array peer_mac_addr_; }; class IfaceCallback : public ISupplicantP2pIfaceCallback { Return onNetworkAdded(uint32_t /* id */) override { return Void(); } Return onNetworkRemoved(uint32_t /* id */) override { return Void(); } Return onDeviceFound( const hidl_array& /* srcAddress */, const hidl_array& /* p2pDeviceAddress */, const hidl_array& /* primaryDeviceType */, const hidl_string& /* deviceName */, uint16_t /* configMethods */, uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */, const hidl_array& /* wfdDeviceInfo */) override { return Void(); } Return onDeviceLost( const hidl_array& /* p2pDeviceAddress */) override { return Void(); } Return onFindStopped() override { return Void(); } Return onGoNegotiationRequest( const hidl_array& /* srcAddress */, ISupplicantP2pIfaceCallback::WpsDevPasswordId /* passwordId */) override { return Void(); } Return onGoNegotiationCompleted( ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override { return Void(); } Return onGroupFormationSuccess() override { return Void(); } Return onGroupFormationFailure( const hidl_string& /* failureReason */) override { return Void(); } Return onGroupStarted( const hidl_string& /* groupIfname */, bool /* isGo */, const hidl_vec& /* ssid */, uint32_t /* frequency */, const hidl_array& /* psk */, const hidl_string& /* passphrase */, const hidl_array& /* goDeviceAddress */, bool /* isPersistent */) override { return Void(); } Return onGroupRemoved(const hidl_string& /* groupIfname */, bool /* isGo */) override { return Void(); } Return onInvitationReceived( const hidl_array& /* srcAddress */, const hidl_array& /* goDeviceAddress */, const hidl_array& /* bssid */, uint32_t /* persistentNetworkId */, uint32_t /* operatingFrequency */) override { return Void(); } Return onInvitationResult( const hidl_array& /* bssid */, ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override { return Void(); } Return onProvisionDiscoveryCompleted( const hidl_array& /* p2pDeviceAddress */, bool /* isRequest */, ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode /* status */, uint16_t /* configMethods */, const hidl_string& /* generatedPin */) override { return Void(); } Return onServiceDiscoveryResponse( const hidl_array& /* srcAddress */, uint16_t /* updateIndicator */, const hidl_vec& /* tlvs */) override { return Void(); } Return onStaAuthorized( const hidl_array& /* srcAddress */, const hidl_array& /* p2pDeviceAddress */) override { return Void(); } Return onStaDeauthorized( const hidl_array& /* srcAddress */, const hidl_array& /* p2pDeviceAddress */) override { return Void(); } }; /* * Create: * Ensures that an instance of the ISupplicantP2pIface proxy object is * successfully created. */ TEST_P(SupplicantP2pIfaceHidlTest, Create) { stopSupplicant(wifi_v1_0_instance_name_); startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, supplicant_instance_name_); sp p2p_iface = getSupplicantP2pIface( getSupplicant(supplicant_instance_name_, isP2pOn_)); EXPECT_NE(nullptr, p2p_iface.get()); } /* * RegisterCallback */ TEST_P(SupplicantP2pIfaceHidlTest, RegisterCallback) { p2p_iface_->registerCallback( new IfaceCallback(), [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * GetName */ TEST_P(SupplicantP2pIfaceHidlTest, GetName) { const auto& status_and_interface_name = HIDL_INVOKE(p2p_iface_, getName); EXPECT_EQ(SupplicantStatusCode::SUCCESS, status_and_interface_name.first.code); EXPECT_FALSE(std::string(status_and_interface_name.second).empty()); } /* * GetType */ TEST_P(SupplicantP2pIfaceHidlTest, GetType) { const auto& status_and_interface_type = HIDL_INVOKE(p2p_iface_, getType); EXPECT_EQ(SupplicantStatusCode::SUCCESS, status_and_interface_type.first.code); EXPECT_EQ(status_and_interface_type.second, IfaceType::P2P); } /* * GetDeviceAddress */ TEST_P(SupplicantP2pIfaceHidlTest, GetDeviceAddress) { p2p_iface_->getDeviceAddress( [](const SupplicantStatus& status, const hidl_array& /* mac_addr */) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * SetSsidPostfix */ TEST_P(SupplicantP2pIfaceHidlTest, SetSsidPostfix) { std::vector ssid(kTestSsidPostfix, kTestSsidPostfix + sizeof(kTestSsidPostfix)); p2p_iface_->setSsidPostfix(ssid, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * Find */ TEST_P(SupplicantP2pIfaceHidlTest, Find) { p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * StopFind */ TEST_P(SupplicantP2pIfaceHidlTest, StopFind) { p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); p2p_iface_->stopFind([](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * Flush */ TEST_P(SupplicantP2pIfaceHidlTest, Flush) { p2p_iface_->flush([](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * Connect */ TEST_P(SupplicantP2pIfaceHidlTest, Connect) { p2p_iface_->connect( mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, kTestConnectPin, false, false, kTestConnectGoIntent, [](const SupplicantStatus& status, const hidl_string& /* pin */) { /* * Before R, auto-join is not enabled and it is not going to work * with fake values. After enabling auto-join, it will succeed * always. */ LOG(INFO) << "ISupplicantP2pIface::connect() ret: " << toString(status); if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code && SupplicantStatusCode::SUCCESS != status.code) { FAIL(); } }); } /* * CancelConnect */ TEST_P(SupplicantP2pIfaceHidlTest, CancelConnect) { p2p_iface_->connect( mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, kTestConnectPin, false, false, kTestConnectGoIntent, [](const SupplicantStatus& status, const hidl_string& /* pin */) { /* * Before R, auto-join is not enabled and it is not going to work * with fake values. After enabling auto-join, it will succeed * always. */ LOG(INFO) << "ISupplicantP2pIface::connect() ret: " << toString(status); if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code && SupplicantStatusCode::SUCCESS != status.code) { FAIL(); } }); p2p_iface_->cancelConnect([](const SupplicantStatus& status) { LOG(INFO) << "ISupplicantP2pIface::cancelConnect() ret: " << toString(status); if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code && SupplicantStatusCode::SUCCESS != status.code) { FAIL(); } }); } /* * ProvisionDiscovery */ TEST_P(SupplicantP2pIfaceHidlTest, ProvisionDiscovery) { p2p_iface_->provisionDiscovery( mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, [](const SupplicantStatus& status) { // This is not going to work with fake values. EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); }); } /* * AddGroup */ TEST_P(SupplicantP2pIfaceHidlTest, AddGroup) { p2p_iface_->addGroup(false, kTestNetworkId, [](const SupplicantStatus& /* status */) { // TODO: Figure out the initialization sequence for // this to work. // EXPECT_EQ(SupplicantStatusCode::SUCCESS, // status.code); }); } /* * RemoveGroup */ TEST_P(SupplicantP2pIfaceHidlTest, RemoveGroup) { // This is not going to work with fake values. EXPECT_NE(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, removeGroup, kTestGroupIfName).code); } /* * Reject */ TEST_P(SupplicantP2pIfaceHidlTest, Reject) { p2p_iface_->reject(mac_addr_, [](const SupplicantStatus& status) { // This is not going to work with fake values. EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); }); } /* * Invite */ TEST_P(SupplicantP2pIfaceHidlTest, Invite) { p2p_iface_->invite(kTestGroupIfName, mac_addr_, peer_mac_addr_, [](const SupplicantStatus& status) { // This is not going to work with fake values. EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); }); } /* * Reinvoke */ TEST_P(SupplicantP2pIfaceHidlTest, Reinvoke) { p2p_iface_->reinvoke( kTestNetworkId, mac_addr_, [](const SupplicantStatus& status) { // This is not going to work with fake values. EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, status.code); }); } /* * ConfigureExtListen */ TEST_P(SupplicantP2pIfaceHidlTest, ConfigureExtListen) { p2p_iface_->configureExtListen(kTestExtListenPeriod, kTestExtListenInterval, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * SetListenChannel */ TEST_P(SupplicantP2pIfaceHidlTest, SetListenChannel) { p2p_iface_->setListenChannel( kTestChannel, kTestOperatingClass, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * SetDisallowedFrequencies */ TEST_P(SupplicantP2pIfaceHidlTest, SetDisallowedFrequencies) { std::vector ranges = { {kTestFreqRange[0], kTestFreqRange[1]}}; p2p_iface_->setDisallowedFrequencies( ranges, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * GetSsid */ TEST_P(SupplicantP2pIfaceHidlTest, GetSsid) { std::array mac_addr; memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size()); p2p_iface_->getSsid(mac_addr, [](const SupplicantStatus& status, const hidl_vec& /* ssid */) { // This is not going to work with fake values. EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); }); } /* * GetGroupCapability */ TEST_P(SupplicantP2pIfaceHidlTest, GetGroupCapability) { std::array mac_addr; memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size()); p2p_iface_->getGroupCapability( mac_addr, [](const SupplicantStatus& status, uint32_t /* caps */) { // This is not going to work with fake values. EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); }); } /* * FlushServices */ TEST_P(SupplicantP2pIfaceHidlTest, FlushServices) { p2p_iface_->flushServices([](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * SetMiracastMode */ TEST_P(SupplicantP2pIfaceHidlTest, SetMiracastMode) { p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::DISABLED, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::SOURCE, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::SINK, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } /* * SetGroupIdle */ TEST_P(SupplicantP2pIfaceHidlTest, SetGroupIdle) { // This is not going to work with fake values. EXPECT_NE(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setGroupIdle, kTestGroupIfName, kTestSetGroupIdleTimeout) .code); } /* * SetPowerSave */ TEST_P(SupplicantP2pIfaceHidlTest, SetPowerSave) { // This is not going to work with fake values. EXPECT_NE( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setPowerSave, kTestGroupIfName, true).code); // This is not going to work with fake values. EXPECT_NE( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setPowerSave, kTestGroupIfName, false).code); } /* * SetWpsDeviceName */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsDeviceName) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsDeviceName, kTestWpsDeviceName).code); } /* * SetWpsDeviceType */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsDeviceType) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsDeviceType, kTestWpsDeviceType).code); } /* * SetWpsManufacturer */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsManufacturer) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsManufacturer, kTestWpsManufacturer).code); } /* * SetWpsModelName */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsModelName) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsModelName, kTestWpsModelName).code); } /* * SetWpsModelNumber */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsModelNumber) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsModelNumber, kTestWpsModelNumber).code); } /* * SetWpsSerialNumber */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsSerialNumber) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsSerialNumber, kTestWpsSerialNumber).code); } /* * SetWpsConfigMethods */ TEST_P(SupplicantP2pIfaceHidlTest, SetWpsConfigMethods) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWpsConfigMethods, kTestWpsConfigMethods) .code); } /* * AddAndRemoveBonjourService * This tests that we are able to add a bonjour service, and we can remove it * by using the same query data. * This also tests that removeBonjourSerive() returns error when there is no * existing bonjour service with the same query data. */ TEST_P(SupplicantP2pIfaceHidlTest, AddAndRemoveBonjourService) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, HIDL_INVOKE( p2p_iface_, addBonjourService, std::vector(kTestBonjourServiceQuery, kTestBonjourServiceQuery + sizeof(kTestBonjourServiceQuery)), std::vector(kTestBonjourServiceResponse, kTestBonjourServiceResponse + sizeof(kTestBonjourServiceResponse))) .code); EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, removeBonjourService, std::vector(kTestBonjourServiceQuery, kTestBonjourServiceQuery + sizeof(kTestBonjourServiceQuery))) .code); // This will fail because boujour service with kTestBonjourServiceQuery was // already removed. EXPECT_NE( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, removeBonjourService, std::vector(kTestBonjourServiceQuery, kTestBonjourServiceQuery + sizeof(kTestBonjourServiceQuery))) .code); } /* * AddAndRemoveUpnpService * This tests that we are able to add a upnp service, and we can remove it * by using the same service name. * This also tests that removeUpnpService() returns error when there is no * exsiting upnp service with the same service name. */ TEST_P(SupplicantP2pIfaceHidlTest, AddAndRemoveUpnpService) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, addUpnpService, 0 /* version */, kTestUpnpServiceName) .code); EXPECT_EQ(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, removeUpnpService, 0 /* version */, kTestUpnpServiceName) .code); // This will fail because Upnp service with kTestUpnpServiceName was // already removed. EXPECT_NE(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, removeUpnpService, 0 /* version */, kTestUpnpServiceName) .code); } /* * EnableWfd */ TEST_P(SupplicantP2pIfaceHidlTest, EnableWfd) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, enableWfd, true).code); EXPECT_EQ(SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, enableWfd, false).code); } /* * SetWfdDeviceInfo */ TEST_P(SupplicantP2pIfaceHidlTest, SetWfdDeviceInfo) { EXPECT_EQ( SupplicantStatusCode::SUCCESS, HIDL_INVOKE(p2p_iface_, setWfdDeviceInfo, kTestWfdDeviceInfo).code); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantP2pIfaceHidlTest, testing::Combine( testing::ValuesIn( android::hardware::getAllHalInstanceNames(IWifi::descriptor)), testing::ValuesIn(android::hardware::getAllHalInstanceNames( ISupplicant::descriptor))), android::hardware::PrintInstanceTupleNameToString<>);