int main(void) { auto dbusConnection = CommonAPI::DBus::DBusConnection::getBus(CommonAPI::DBus::DBusType_t::SESSION); if (!dbusConnection->isConnected()) dbusConnection->connect(); assert(dbusConnection->isConnected()); const bool serviceNameAcquired = dbusConnection->requestServiceNameAndBlock( "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter"); assert(serviceNameAcquired); auto testStub = std::make_shared<TestStub>(); auto testStubAdapter = std::make_shared<TestDBusStubAdapter>( "my:common.api:address.for.dbus", "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter", "/common/api/dbus/TestDBusInterfaceAdapter", dbusConnection, testStub); testStubAdapter->init(testStubAdapter); auto dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(CommonAPI::DBus::DBusAddress("org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter", testStubAdapter->getDBusAddress().getObjectPath().c_str(), testStubAdapter->getDBusAddress().getService().c_str()), "GetEmptyResponse"); const bool messageSent = dbusConnection->sendDBusMessage(dbusMessageCall); assert(messageSent); for (int i = 0; i < 10; i++) { dbusConnection->readWriteDispatch(100); } assert(dispatchedMessageCount > 0); testStubAdapter->deinit(); return 0; }
bool DBusObjectManagerStub::onInterfaceDBusMessage(const DBusMessage& dbusMessage) { auto dbusConnection = dbusConnection_.lock(); if (!dbusConnection || !dbusConnection->isConnected()) { return false; } if (!dbusMessage.isMethodCallType() || !dbusMessage.hasMemberName("GetManagedObjects")) { return false; } std::lock_guard<std::mutex> dbusObjectManagerStubLock(dbusObjectManagerStubLock_); DBusObjectPathAndInterfacesDict dbusObjectPathAndInterfacesDict; for (const auto& registeredDBusObjectPathIterator : registeredDBusObjectPathsMap_) { const std::string& registeredDBusObjectPath = registeredDBusObjectPathIterator.first; const auto& registeredDBusInterfacesMap = registeredDBusObjectPathIterator.second; DBusInterfacesAndPropertiesDict dbusInterfacesAndPropertiesDict; assert(registeredDBusObjectPath.length() > 0); assert(registeredDBusInterfacesMap.size() > 0); for (const auto& registeredDBusInterfaceIterator : registeredDBusInterfacesMap) { const std::string& registeredDBusInterfaceName = registeredDBusInterfaceIterator.first; const auto& registeredDBusStubAdapter = registeredDBusInterfaceIterator.second; assert(registeredDBusInterfaceName.length() > 0); dbusInterfacesAndPropertiesDict.insert({ registeredDBusInterfaceName, DBusPropertiesChangedDict() }); if (registeredDBusStubAdapter->isManagingInterface()) { dbusInterfacesAndPropertiesDict.insert({ getInterfaceName(), DBusPropertiesChangedDict() }); } } dbusObjectPathAndInterfacesDict.insert({ registeredDBusObjectPath, std::move(dbusInterfacesAndPropertiesDict) }); } DBusMessage dbusMessageReply = dbusMessage.createMethodReturn("a{oa{sa{sv}}}"); DBusOutputStream dbusOutputStream(dbusMessageReply); dbusOutputStream << dbusObjectPathAndInterfacesDict; dbusOutputStream.flush(); const bool dbusMessageReplySent = dbusConnection->sendDBusMessage(dbusMessageReply); return dbusMessageReplySent; }
TEST_F(DBusConnectionTest, SendingAsyncDBusMessagesWorks) { const char busName[] = "commonapi.dbus.test.TestInterfaceHandler"; const char objectPath[] = "/common/api/dbus/test/TestObject"; const char interfaceName[] = "commonapi.dbus.test.TestInterface"; const char methodName[] = "TestMethod"; auto interfaceHandlerDBusConnection = CommonAPI::DBus::DBusConnection::getSessionBus(); ASSERT_TRUE(interfaceHandlerDBusConnection->connect()); ASSERT_TRUE(interfaceHandlerDBusConnection->requestServiceNameAndBlock(busName)); uint32_t serviceHandlerDBusMessageCount = 0; uint32_t clientReplyHandlerDBusMessageCount = 0; interfaceHandlerDBusConnection->setObjectPathMessageHandler( [&serviceHandlerDBusMessageCount, &interfaceHandlerDBusConnection] (CommonAPI::DBus::DBusMessage dbusMessage) -> bool { ++serviceHandlerDBusMessageCount; CommonAPI::DBus::DBusMessage dbusMessageReply = dbusMessage.createMethodReturn(""); interfaceHandlerDBusConnection->sendDBusMessage(dbusMessageReply); return true; } ); interfaceHandlerDBusConnection->registerObjectPath(objectPath); ASSERT_TRUE(dbusConnection_->connect()); CommonAPI::DBus::DBusMessage dbusReplyMessage; for (uint32_t expectedDBusMessageCount = 1; expectedDBusMessageCount <= 10; expectedDBusMessageCount++) { CommonAPI::DBus::DBusMessage dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall( busName, objectPath, interfaceName, methodName, ""); CommonAPI::DBus::DBusOutputStream dbusOutputStream(dbusMessageCall); interfaceHandlerDBusConnection->sendDBusMessageWithReplyAsync( dbusMessageCall, CommonAPI::DBus::DBusProxyAsyncCallbackHandler<>::create( [&clientReplyHandlerDBusMessageCount](CommonAPI::CallStatus status) { ASSERT_EQ(CommonAPI::CallStatus::SUCCESS, status); ++clientReplyHandlerDBusMessageCount; }) ); for (int i = 0; i < 10 && serviceHandlerDBusMessageCount < expectedDBusMessageCount; i++) { interfaceHandlerDBusConnection->readWriteDispatch(100); } ASSERT_EQ(serviceHandlerDBusMessageCount, expectedDBusMessageCount); for (int i = 0; i < 10 && clientReplyHandlerDBusMessageCount < expectedDBusMessageCount; i++) { dbusConnection_->readWriteDispatch(100); } ASSERT_EQ(clientReplyHandlerDBusMessageCount, expectedDBusMessageCount); } dbusConnection_->disconnect(); interfaceHandlerDBusConnection->unregisterObjectPath(objectPath); ASSERT_TRUE(interfaceHandlerDBusConnection->releaseServiceName(busName)); interfaceHandlerDBusConnection->disconnect(); }