diff --git a/include/connectionmanager.h b/include/connectionmanager.h index e11c27a46da2b78f8372f65042372651d4f43980..5a97280abb6c09954e683c8c9c3bde61a99fcb06 100644 --- a/include/connectionmanager.h +++ b/include/connectionmanager.h @@ -139,6 +139,13 @@ public: */ bool isConnecting(const DeviceId& deviceId, const std::string& name) const; + /** + * Check if we are already connected to a device + * @param deviceId Remote device + * @return if connected + */ + bool isConnected(const DeviceId& deviceId) const; + /** * Close all connections with a current device * @param peerUri Peer URI diff --git a/src/connectionmanager.cpp b/src/connectionmanager.cpp index 5474fa0022a2c99909fe7681588aaec20799570e..87704a8d702dae42e953ddf4e686c00ab1f45249 100644 --- a/src/connectionmanager.cpp +++ b/src/connectionmanager.cpp @@ -1883,6 +1883,16 @@ ConnectionManager::isConnecting(const DeviceId& deviceId, const std::string& nam return false; } +bool +ConnectionManager::isConnected(const DeviceId& deviceId) const +{ + if (auto dinfo = pimpl_->infos_.getDeviceInfo(deviceId)) { + std::unique_lock<std::mutex> lk {dinfo->mtx_}; + return dinfo->getConnectedInfo() != nullptr; + } + return false; +} + void ConnectionManager::closeConnectionsWith(const std::string& peerUri) { diff --git a/tests/connectionManager.cpp b/tests/connectionManager.cpp index 0bbe5bfd648ee6bff152e1c52bef32897d0a963f..9d0b1624207e929f93994394ba39b3518a5837c9 100644 --- a/tests/connectionManager.cpp +++ b/tests/connectionManager.cpp @@ -98,16 +98,19 @@ private: void testFloodSocket(); void testDestroyWhileSending(); void testIsConnecting(); + void testIsConnected(); void testCanSendBeacon(); void testCannotSendBeacon(); void testConnectivityChangeTriggerBeacon(); void testOnNoBeaconTriggersShutdown(); void testShutdownWhileNegotiating(); void testGetChannelList(); + CPPUNIT_TEST_SUITE(ConnectionManagerTest); CPPUNIT_TEST(testDeclineICERequest); CPPUNIT_TEST(testConnectDevice); CPPUNIT_TEST(testIsConnecting); + CPPUNIT_TEST(testIsConnected); CPPUNIT_TEST(testAcceptConnection); CPPUNIT_TEST(testDeclineConnection); CPPUNIT_TEST(testManyChannels); @@ -199,7 +202,7 @@ ConnectionManagerTest::setUp() }); bootstrap_node = std::make_shared<dht::DhtRunner>(); bootstrap_node->run(36432); - + factory = std::make_unique<IceTransportFactory>(/*logger*/); alice = setupHandler(aliceDevice1Id, "127.0.0.1:36432"); bob = setupHandler(bobDevice1Id, "127.0.0.1:36432"); @@ -994,7 +997,7 @@ ConnectionManagerTest::testShutdownCallbacks() rcv.notify_one(); } }); - + std::unique_lock<std::mutex> lk {mtx}; // Connect first channel. This will initiate a mx sock CPPUNIT_ASSERT(rcv.wait_for(lk, 30s, [&] { @@ -1265,6 +1268,36 @@ ConnectionManagerTest::testIsConnecting() CPPUNIT_ASSERT(!alice->connectionManager->isConnecting(bob->id.second->getLongId(), "sip")); } +void +ConnectionManagerTest::testIsConnected() +{ + bob->connectionManager->onICERequest([](const DeviceId&) { return true; }); + alice->connectionManager->onICERequest([](const DeviceId&) { return true; }); + + std::unique_lock<std::mutex> lk {mtx}; + std::condition_variable cv; + bool successfullyConnected = false, successfullyReceive = false; + + bob->connectionManager->onChannelRequest( + [&](const std::shared_ptr<dht::crypto::Certificate>&, const std::string&) { + return true; + }); + + alice->connectionManager->connectDevice(bob->id.second, + "sip", + [&](std::shared_ptr<ChannelSocket> socket, + const DeviceId&) { + if (socket) { + successfullyConnected = true; + } + cv.notify_one(); + }); + CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&] { return successfullyConnected; })); + std::this_thread::sleep_for( + std::chrono::milliseconds(100)); // Just to wait for the callback to finish + CPPUNIT_ASSERT(alice->connectionManager->isConnected(bob->id.second->getLongId())); +} + void ConnectionManagerTest::testCanSendBeacon() {