diff options
Diffstat (limited to 'src/CommonAPI')
-rw-r--r-- | src/CommonAPI/DBus/DBusAddressTranslator.cpp | 68 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusConnection.cpp | 380 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusDaemonProxy.cpp | 2 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFactory.cpp | 8 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusMainLoopContext.cpp | 14 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusProxy.cpp | 237 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusProxyBase.cpp | 35 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusServiceRegistry.cpp | 18 |
8 files changed, 526 insertions, 236 deletions
diff --git a/src/CommonAPI/DBus/DBusAddressTranslator.cpp b/src/CommonAPI/DBus/DBusAddressTranslator.cpp index 57101b4..0c653dc 100644 --- a/src/CommonAPI/DBus/DBusAddressTranslator.cpp +++ b/src/CommonAPI/DBus/DBusAddressTranslator.cpp @@ -31,8 +31,7 @@ std::shared_ptr<DBusAddressTranslator> DBusAddressTranslator::get() { } DBusAddressTranslator::DBusAddressTranslator() - : defaultDomain_("local"), - dBusBusType_(DBusType_t::SESSION) { + : defaultDomain_("local"), orgFreedesktopDBusPeerMapped_(false) { init(); isDefault_ = ("dbus" == Runtime::get()->getDefaultBinding()); @@ -133,13 +132,13 @@ DBusAddressTranslator::translate(const DBusAddress &_key, CommonAPI::Address &_v void DBusAddressTranslator::insert( const std::string &_address, - const std::string &_service, const std::string &_path, const std::string &_interface) { + const std::string &_service, const std::string &_path, const std::string &_interface, const bool _objPathStartWithDigits) { if (isValid(_service, '.', (_service.length() > 0 && _service[0] == ':'), (_service.length() > 0 && _service[0] == ':'), true) - && isValid(_path, '/', true) + && isValid(_path, '/', true, _objPathStartWithDigits) && isValid(_interface, '.')) { CommonAPI::Address address(_address); DBusAddress dbusAddress(_service, _path, _interface); @@ -152,6 +151,12 @@ DBusAddressTranslator::insert( backwards_[dbusAddress] = address; COMMONAPI_DEBUG( "Added address mapping: ", address, " <--> ", dbusAddress); + if (!orgFreedesktopDBusPeerMapped_) { + orgFreedesktopDBusPeerMapped_ = (_interface == "org.freedesktop.DBus.Peer"); + if (orgFreedesktopDBusPeerMapped_) { + COMMONAPI_DEBUG("org.freedesktop.DBus.Peer mapped"); + } + } } else if(bw != backwards_.end() && bw->second != address) { COMMONAPI_ERROR("Trying to overwrite existing DBus address " "which is already mapped to a CommonAPI address: ", @@ -189,21 +194,28 @@ DBusAddressTranslator::readConfiguration() { return false; for (auto itsMapping : reader.getSections()) { - if(itsMapping.first == "dbus") { - // TODO this is kind of misplaced in the AddressTranslator... - std::string bus_type_str_ = itsMapping.second->getValue("dbus_bus_type"); - if(bus_type_str_ == "SESSION") { - dBusBusType_ = DBusType_t::SESSION; - } else if (bus_type_str_ == "SYSTEM") { - dBusBusType_ = DBusType_t::SYSTEM; - } else { - COMMONAPI_FATAL("Invalid dbus_bus_type specified in .ini file, " - "choose one of {SYSTEM, SESSION}"); - continue; - } - COMMONAPI_INFO("D-Bus bus type set to: " + bus_type_str_ + " via ini file"); - continue; + if(itsMapping.first == "segments") { + std::map<std::string, std::string> mappings = itsMapping.second->getMappings(); + ConnectionId_t connectionId; + std::string busType; + for(auto const &it : mappings) { + connectionId = it.first; + busType = it.second; + if(busType == "SESSION") { + dbusTypes_.insert({ connectionId, DBusType_t::SESSION }); + } else if (busType == "SYSTEM") { + dbusTypes_.insert({ connectionId, DBusType_t::SYSTEM }); + } else { + COMMONAPI_FATAL("Invalid bus type specified in .ini file, " + "choose one of {SYSTEM, SESSION}"); + continue; + } + COMMONAPI_INFO("D-Bus bus type for connection: " + connectionId + + " is set to: " + busType + " via ini file"); + } + continue; } + CommonAPI::Address itsAddress(itsMapping.first); std::string service = itsMapping.second->getValue("service"); @@ -234,8 +246,13 @@ DBusAddressTranslator::isValid( if (_ignoreFirst) { start = 1; - if (separatorPos == 0) + if (separatorPos == 0) { + // accept "root-only" i.e. '/' object path + if (1 == _name.length()) { + return true; + } separatorPos = _name.find(_separator, separatorPos+1); + } } while (start != std::string::npos) { @@ -306,8 +323,17 @@ DBusAddressTranslator::isValid( } DBusType_t -DBusAddressTranslator::getDBusBusType() const { - return dBusBusType_; +DBusAddressTranslator::getDBusBusType(const ConnectionId_t &_connectionId) const { + auto itsDbusTypesIterator = dbusTypes_.find(_connectionId); + if(itsDbusTypesIterator != dbusTypes_.end()) { + return itsDbusTypesIterator->second; + } else { + return DBusType_t::SESSION; + } +} + +bool DBusAddressTranslator::isOrgFreedesktopDBusPeerMapped() const { + return orgFreedesktopDBusPeerMapped_; } } // namespace DBus diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp index cb4f8aa..e3fb4a4 100644 --- a/src/CommonAPI/DBus/DBusConnection.cpp +++ b/src/CommonAPI/DBus/DBusConnection.cpp @@ -16,6 +16,7 @@ #include <CommonAPI/DBus/DBusProxy.hpp> #include <CommonAPI/DBus/DBusAddressTranslator.hpp> + namespace CommonAPI { namespace DBus { @@ -23,7 +24,7 @@ DBusConnectionStatusEvent::DBusConnectionStatusEvent(DBusConnection* dbusConnect dbusConnection_(dbusConnection) { } -void DBusConnectionStatusEvent::onListenerAdded(const Listener& listener) { +void DBusConnectionStatusEvent::onListenerAdded(const Listener& listener, const Subscription subscription) { if (dbusConnection_->isConnected()) listener(AvailabilityStatus::AVAILABLE); } @@ -43,18 +44,18 @@ const DBusObjectPathVTable* DBusConnection::getDBusObjectPathVTable() { const int32_t ownUseCount = 2; void DBusConnection::dispatch() { - std::shared_ptr<DBusConnection> selfReference = this->shared_from_this(); - while (!stopDispatching_ && readWriteDispatch(10) && selfReference.use_count() > ownUseCount) { - if (pauseDispatching_) { - dispatchSuspendLock_.lock(); - dispatchSuspendLock_.unlock(); - } - } + std::shared_ptr<DBusConnection> selfReference = this->shared_from_this(); + while (!stopDispatching_ && readWriteDispatch(10) && selfReference.use_count() > ownUseCount) { + if (pauseDispatching_) { + dispatchSuspendLock_.lock(); + dispatchSuspendLock_.unlock(); + } + } } bool DBusConnection::readWriteDispatch(int _timeout) { if(isConnected()) { - return 0 != dbus_connection_read_write_dispatch(connection_, _timeout); + return 0 != dbus_connection_read_write_dispatch(connection_, _timeout); } return false; } @@ -76,13 +77,13 @@ DBusConnection::DBusConnection(DBusType_t busType) : watchContext_(NULL), pauseDispatching_(false), connection_(NULL), - busType_(DBusAddressTranslator::get()->getDBusBusType()), + busType_(busType), dbusConnectionStatusEvent_(this), libdbusSignalMatchRulesCount_(0), dbusObjectMessageHandler_(), connectionNameCount_(), enforcerThread_(NULL), - enforcerThreadCancelled_(false) { + enforcerThreadCancelled_(false) { dbus_threads_init_default(); } @@ -99,8 +100,8 @@ DBusConnection::DBusConnection(::DBusConnection *_connection) : libdbusSignalMatchRulesCount_(0), dbusObjectMessageHandler_(), connectionNameCount_(), - enforcerThread_(NULL), - enforcerThreadCancelled_(false) { + enforcerThread_(NULL), + enforcerThreadCancelled_(false) { dbus_threads_init_default(); } @@ -124,27 +125,27 @@ DBusConnection::~DBusConnection() { } // ensure, the registry survives until disconnecting is done... - //std::shared_ptr<DBusServiceRegistry> itsRegistry = DBusServiceRegistry::get(shared_from_this()); - disconnect(); + //std::shared_ptr<DBusServiceRegistry> itsRegistry = DBusServiceRegistry::get(shared_from_this()); + disconnect(); //Assert that the enforcerThread_ is in a position to finish itself correctly even after destruction //of the DBusConnection. Also assert all resources are cleaned up. - auto it = timeoutMap_.begin(); - while (it != timeoutMap_.end()) { - DBusPendingCall* libdbusPendingCall = it->first; + auto it = timeoutMap_.begin(); + while (it != timeoutMap_.end()) { + DBusPendingCall* libdbusPendingCall = it->first; - if (!dbus_pending_call_get_completed(libdbusPendingCall)) { - dbus_pending_call_cancel(libdbusPendingCall); - DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); - DBusMessage& dbusMessageCall = std::get<2>(it->second); + if (!dbus_pending_call_get_completed(libdbusPendingCall)) { + dbus_pending_call_cancel(libdbusPendingCall); + DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); + DBusMessage& dbusMessageCall = std::get<2>(it->second); - asyncHandler->onDBusMessageReply(CallStatus::REMOTE_ERROR, dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT)); - delete asyncHandler; + asyncHandler->onDBusMessageReply(CallStatus::REMOTE_ERROR, dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT)); + delete asyncHandler; - } - it = timeoutMap_.erase(it); - dbus_pending_call_unref(libdbusPendingCall); - } + } + it = timeoutMap_.erase(it); + dbus_pending_call_unref(libdbusPendingCall); + } } @@ -162,7 +163,7 @@ bool DBusConnection::attachMainLoopContext(std::weak_ptr<MainLoopContext> mainLo &mainLoopContext_, NULL); - bool success = 0 != dbus_connection_set_watch_functions( + bool success = 0 != dbus_connection_set_watch_functions( connection_, &DBusConnection::onAddWatch, &DBusConnection::onRemoveWatch, @@ -174,7 +175,7 @@ bool DBusConnection::attachMainLoopContext(std::weak_ptr<MainLoopContext> mainLo return false; } - success = 0 != dbus_connection_set_timeout_functions( + success = 0 != dbus_connection_set_timeout_functions( connection_, &DBusConnection::onAddTimeout, &DBusConnection::onRemoveTimeout, @@ -289,15 +290,15 @@ bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) { connection_ = dbus_bus_get_private(libdbusType, &dbusError.libdbusError_); if (dbusError) { - #ifdef _MSC_VER - COMMONAPI_ERROR(std::string(__FUNCTION__) + - ": Name: " + dbusError.getName() + - " Message: " + dbusError.getMessage()) - #else - COMMONAPI_ERROR(std::string(__PRETTY_FUNCTION__) + - ": Name: " + dbusError.getName() + - " Message: " + dbusError.getMessage()) - #endif + #ifdef _MSC_VER + COMMONAPI_ERROR(std::string(__FUNCTION__) + + ": Name: " + dbusError.getName() + + " Message: " + dbusError.getMessage()) + #else + COMMONAPI_ERROR(std::string(__PRETTY_FUNCTION__) + + ": Name: " + dbusError.getName() + + " Message: " + dbusError.getMessage()) + #endif return false; } @@ -310,11 +311,11 @@ bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) { stopDispatching_ = !startDispatchThread; if (startDispatchThread) { - dispatchThread_ = new std::thread(std::bind(&DBusConnection::dispatch, this->shared_from_this())); + dispatchThread_ = new std::thread(std::bind(&DBusConnection::dispatch, this->shared_from_this())); } - enforcerThread_ = std::make_shared<std::thread>( - std::bind(&DBusConnection::enforceAsynchronousTimeouts, shared_from_this())); + enforcerThread_ = std::make_shared<std::thread>( + std::bind(&DBusConnection::enforceAsynchronousTimeouts, shared_from_this())); dbusConnectionStatusEvent_.notifyListeners(AvailabilityStatus::AVAILABLE); @@ -352,7 +353,7 @@ void DBusConnection::disconnect() { enforcerThreadCancelled_ = true; enforceTimeoutCondition_.notify_one(); if (enforcerThread_->joinable()) { - enforcerThread_->join(); + enforcerThread_->join(); } enforcerThreadCancelled_ = false; @@ -388,7 +389,7 @@ bool DBusConnection::requestServiceNameAndBlock(const std::string& serviceName) std::lock_guard<std::mutex> dbusConnectionLock(connectionGuard_); auto conIter = connectionNameCount_.find(serviceName); if (conIter == connectionNameCount_.end()) { - suspendDispatching(); + suspendDispatching(); const int libdbusStatus = dbus_bus_request_name(connection_, serviceName.c_str(), @@ -400,17 +401,17 @@ bool DBusConnection::requestServiceNameAndBlock(const std::string& serviceName) isServiceNameAcquired = (libdbusStatus == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER); if (isServiceNameAcquired) { connectionNameCount_.insert( { serviceName, (uint16_t)1 } ); - } - else { - #ifdef _MSC_VER // Visual Studio - COMMONAPI_ERROR(std::string(__FUNCTION__) + - ": Name: " + dbusError.getName() + - " Message: " + dbusError.getMessage()) - #else + } + else { + #ifdef _MSC_VER // Visual Studio + COMMONAPI_ERROR(std::string(__FUNCTION__) + + ": Name: " + dbusError.getName() + + " Message: " + dbusError.getMessage()) + #else COMMONAPI_ERROR(std::string(__PRETTY_FUNCTION__) + ": Name: " + dbusError.getName() + " Message: " + dbusError.getMessage()) - #endif + #endif } } else { conIter->second = conIter->second + 1; @@ -427,7 +428,7 @@ bool DBusConnection::releaseServiceName(const std::string& serviceName) const { auto conIter = connectionNameCount_.find(serviceName); if (conIter != connectionNameCount_.end()) { if (conIter->second == 1) { - suspendDispatching(); + suspendDispatching(); const int libdbusStatus = dbus_bus_release_name(connection_, serviceName.c_str(), &dbusError.libdbusError_); @@ -449,29 +450,40 @@ bool DBusConnection::sendDBusMessage(const DBusMessage &_message) const { assert(isConnected()); dbus_uint32_t dbusSerial; - bool result = 0 != dbus_connection_send(connection_, _message.message_, &dbusSerial); + bool result = 0 != dbus_connection_send(connection_, _message.message_, &dbusSerial); return result; } -void DBusConnection::onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void *userData) { - assert(userData); - assert(libdbusPendingCall); +DBusMessage DBusConnection::convertToDBusMessage(::DBusPendingCall* _libdbusPendingCall, + CallStatus& _callStatus) { + assert(_libdbusPendingCall); - auto dbusMessageReplyAsyncHandler = reinterpret_cast<DBusMessageReplyAsyncHandler*>(userData); + ::DBusMessage* libdbusMessage = dbus_pending_call_steal_reply(_libdbusPendingCall); + const bool increaseLibdbusMessageReferenceCount = false; + DBusMessage dbusMessage(libdbusMessage, increaseLibdbusMessageReferenceCount); + _callStatus = CallStatus::SUCCESS; - ::DBusMessage* libdbusMessage = dbus_pending_call_steal_reply(libdbusPendingCall); - const bool increaseLibdbusMessageReferenceCount = false; - DBusMessage dbusMessage(libdbusMessage, increaseLibdbusMessageReferenceCount); - CallStatus callStatus = CallStatus::SUCCESS; + if (!dbusMessage.isMethodReturnType()) { + _callStatus = CallStatus::REMOTE_ERROR; + } - if (!dbusMessage.isMethodReturnType()) { - callStatus = CallStatus::REMOTE_ERROR; - } + return dbusMessage; +} + +void DBusConnection::onLibdbusPendingCallNotifyThunk(::DBusPendingCall* _libdbusPendingCall, void *_userData) { + assert(_userData); + assert(_libdbusPendingCall); + + auto dbusMessageReplyAsyncHandler = reinterpret_cast<DBusMessageReplyAsyncHandler*>(_userData); + + DBusMessage dbusMessage; + CallStatus callStatus; + dbusMessage = DBusConnection::convertToDBusMessage(_libdbusPendingCall, callStatus); dbusMessageReplyAsyncHandler->onDBusMessageReply(callStatus, dbusMessage); // libdbus calls the cleanup method below - dbus_pending_call_unref(libdbusPendingCall); + dbus_pending_call_unref(_libdbusPendingCall); } void DBusConnection::onLibdbusDataCleanup(void* userData) { @@ -479,74 +491,77 @@ void DBusConnection::onLibdbusDataCleanup(void* userData) { delete dbusMessageReplyAsyncHandler; } - //Would not be needed if libdbus would actually handle its timeouts for pending calls. void DBusConnection::enforceAsynchronousTimeouts() const { - std::unique_lock<std::mutex> itsLock(enforcerThreadMutex_); + std::unique_lock<std::mutex> itsLock(enforcerThreadMutex_); - while (!enforcerThreadCancelled_) { + while (!enforcerThreadCancelled_) { enforceTimeoutMutex_.lock(); int timeout = std::numeric_limits<int>::max(); // not really, but nearly "forever" if (timeoutMap_.size() > 0) { - auto minTimeoutElement = std::min_element(timeoutMap_.begin(), timeoutMap_.end(), - [] (const TimeoutMapElement& lhs, const TimeoutMapElement& rhs) { - return std::get<0>(lhs.second) < std::get<0>(rhs.second); - }); + auto minTimeoutElement = std::min_element(timeoutMap_.begin(), timeoutMap_.end(), + [] (const TimeoutMapElement& lhs, const TimeoutMapElement& rhs) { + return std::get<0>(lhs.second) < std::get<0>(rhs.second); + }); - auto minTimeout = std::get<0>(minTimeoutElement->second); + auto minTimeout = std::get<0>(minTimeoutElement->second); - std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); - timeout = (int)std::chrono::duration_cast<std::chrono::milliseconds>(minTimeout - now).count(); + timeout = (int)std::chrono::duration_cast<std::chrono::milliseconds>(minTimeout - now).count(); } enforceTimeoutMutex_.unlock(); if (std::cv_status::timeout == - enforceTimeoutCondition_.wait_for(itsLock, std::chrono::milliseconds(timeout))) { - - //Do not access members if the DBusConnection was destroyed during the unlocked phase. - enforceTimeoutMutex_.lock(); - auto it = timeoutMap_.begin(); - while (it != timeoutMap_.end()) { - std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); - - if (now > std::get<0>(it->second)) { - DBusPendingCall* libdbusPendingCall = it->first; - - if (!dbus_pending_call_get_completed(libdbusPendingCall)) { - dbus_pending_call_cancel(libdbusPendingCall); - DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); - DBusMessage& dbusMessageCall = std::get<2>(it->second); - - if (mainLoopContext_.lock()) { - mainloopTimeouts_.push_back(std::make_pair(asyncHandler, dbusMessageCall)); - } else { - enforceTimeoutMutex_.unlock(); // unlock before making callbacks to application to avoid deadlocks - asyncHandler->onDBusMessageReply(CallStatus::REMOTE_ERROR, dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT)); - enforceTimeoutMutex_.lock(); - delete asyncHandler; - } - } - it = timeoutMap_.erase(it); - - //This unref MIGHT cause the destruction of the last callback object that references the DBusConnection. - //So after this unref has been called, it has to be ensured that continuation of the loop is an option. - dbus_pending_call_unref(libdbusPendingCall); - } else { - ++it; - } - } - enforceTimeoutMutex_.unlock(); - } + enforceTimeoutCondition_.wait_for(itsLock, std::chrono::milliseconds(timeout))) { + + //Do not access members if the DBusConnection was destroyed during the unlocked phase. + enforceTimeoutMutex_.lock(); + auto it = timeoutMap_.begin(); + while (it != timeoutMap_.end()) { + std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); + + if (now > std::get<0>(it->second)) { + DBusPendingCall* libdbusPendingCall = it->first; + + if (!dbus_pending_call_get_completed(libdbusPendingCall)) { + dbus_pending_call_cancel(libdbusPendingCall); + DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); + DBusMessage& dbusMessageCall = std::get<2>(it->second); + + if (mainLoopContext_.lock()) { + mainloopTimeouts_.push_back(std::make_tuple(asyncHandler, + dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT), + CallStatus::REMOTE_ERROR, + nullptr)); + mainLoopContext_.lock()->wakeup(); + } else { + enforceTimeoutMutex_.unlock(); // unlock before making callbacks to application to avoid deadlocks + asyncHandler->onDBusMessageReply(CallStatus::REMOTE_ERROR, dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT)); + enforceTimeoutMutex_.lock(); + delete asyncHandler; + } + } + it = timeoutMap_.erase(it); + + //This unref MIGHT cause the destruction of the last callback object that references the DBusConnection. + //So after this unref has been called, it has to be ensured that continuation of the loop is an option. + dbus_pending_call_unref(libdbusPendingCall); + } else { + ++it; + } + } + enforceTimeoutMutex_.unlock(); + } } } std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( const DBusMessage& dbusMessage, std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler, - const CommonAPI::CallInfo *_info) const { + const CommonAPI::CallInfo *_info) const { assert(dbusMessage); assert(isConnected()); @@ -555,56 +570,47 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( dbus_bool_t libdbusSuccess; suspendDispatching(); - libdbusSuccess = dbus_connection_send_with_reply(connection_, - dbusMessage.message_, - &libdbusPendingCall, - _info->timeout_); + libdbusSuccess = dbus_connection_send_with_reply_set_notify(connection_, + dbusMessage.message_, + &libdbusPendingCall, + onLibdbusPendingCallNotifyThunk, + dbusMessageReplyAsyncHandler.get(), + onLibdbusDataCleanup, + _info->timeout_); if (_info->sender_ != 0) { - COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial()); + COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial()); } if (!libdbusSuccess || !libdbusPendingCall) { - dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::CONNECTION_FAILED, dbusMessage.createMethodError(DBUS_ERROR_DISCONNECTED)); - resumeDispatching(); - return dbusMessageReplyAsyncHandler->getFuture(); + #ifdef _MSC_VER // Visual Studio + COMMONAPI_ERROR(std::string(__FUNCTION__) + + ": (!libdbusSuccess || !libdbusPendingCall) == true") + #else + COMMONAPI_ERROR(std::string(__PRETTY_FUNCTION__) + + ": (!libdbusSuccess || !libdbusPendingCall) == true") + #endif + if (libdbusPendingCall) { + dbus_pending_call_unref(libdbusPendingCall); + } + dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::CONNECTION_FAILED, dbusMessage.createMethodError(DBUS_ERROR_DISCONNECTED)); + resumeDispatching(); + return dbusMessageReplyAsyncHandler->getFuture(); } - sendLock_.lock(); - if (dbus_pending_call_get_completed (libdbusPendingCall)) { - onLibdbusPendingCallNotifyThunk(libdbusPendingCall, dbusMessageReplyAsyncHandler.get()); - onLibdbusDataCleanup(dbusMessageReplyAsyncHandler.get()); - - } else { - libdbusSuccess = dbus_pending_call_set_notify( - libdbusPendingCall, - onLibdbusPendingCallNotifyThunk, - dbusMessageReplyAsyncHandler.get(), - onLibdbusDataCleanup); - - if (!libdbusSuccess) { - dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::OUT_OF_MEMORY, dbusMessage); - dbus_pending_call_unref(libdbusPendingCall); - resumeDispatching(); - sendLock_.unlock(); - return dbusMessageReplyAsyncHandler->getFuture(); - } - } - sendLock_.unlock(); - DBusMessageReplyAsyncHandler* replyAsyncHandler = dbusMessageReplyAsyncHandler.release(); if (_info->timeout_ != DBUS_TIMEOUT_INFINITE) { dbus_pending_call_ref(libdbusPendingCall); auto timeoutPoint = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(_info->timeout_); std::tuple< - std::chrono::time_point<std::chrono::high_resolution_clock>, - DBusMessageReplyAsyncHandler*, - DBusMessage> toInsert { - timeoutPoint, - replyAsyncHandler, - dbusMessage - }; + std::chrono::time_point<std::chrono::high_resolution_clock>, + DBusMessageReplyAsyncHandler*, + DBusMessage> toInsert { + timeoutPoint, + replyAsyncHandler, + dbusMessage + }; enforceTimeoutMutex_.lock(); timeoutMap_.insert( { libdbusPendingCall, toInsert } ); @@ -622,7 +628,7 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage, DBusError& dbusError, - const CommonAPI::CallInfo *_info) const { + const CommonAPI::CallInfo *_info) const { assert(dbusMessage); assert(!dbusError); assert(isConnected()); @@ -635,7 +641,7 @@ DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage& &dbusError.libdbusError_); if (_info->sender_ != 0) { - COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial()); + COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial()); } resumeDispatching(); @@ -650,18 +656,25 @@ DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage& bool DBusConnection::singleDispatch() { - for (auto t : mainloopTimeouts_) { - t.first->onDBusMessageReply(CallStatus::REMOTE_ERROR, t.second.createMethodError(DBUS_ERROR_TIMEOUT)); - delete t.first; - } - mainloopTimeouts_.clear(); + for (auto t : mainloopTimeouts_) { + std::get<0>(t)->onDBusMessageReply(std::get<2>(t), std::get<1>(t)); + if (std::get<3>(t) != nullptr) { + dbus_pending_call_unref(std::get<3>(t)); + } + delete std::get<0>(t); + } + mainloopTimeouts_.clear(); return (dbus_connection_dispatch(connection_) == DBUS_DISPATCH_DATA_REMAINS); } bool DBusConnection::isDispatchReady() { return (dbus_connection_get_dispatch_status(connection_) == DBUS_DISPATCH_DATA_REMAINS || - !mainloopTimeouts_.empty()); + !mainloopTimeouts_.empty()); +} + +bool DBusConnection::hasDispatchThread() { + return (dispatchThread_ != NULL); } DBusProxyConnection::DBusSignalHandlerToken DBusConnection::subscribeForSelectiveBroadcast( @@ -685,13 +698,13 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::subscribeForSelectiv DBusProxyConnection::DBusSignalHandlerToken subscriptionToken; if (callStatus == CommonAPI::CallStatus::SUCCESS && subscriptionAccepted) { subscriptionToken = addSignalMemberHandler( - objectPath, - interfaceName, - interfaceMemberName, - interfaceMemberSignature, - dbusSignalHandler, - true - ); + objectPath, + interfaceName, + interfaceMemberName, + interfaceMemberSignature, + dbusSignalHandler, + true + ); subscriptionAccepted = true; } @@ -735,7 +748,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl handlerList.insert(dbusSignalHandler); dbusSignalHandlerTable_.insert( { - dbusSignalHandlerPath, + dbusSignalHandlerPath, std::make_pair(std::make_shared<std::recursive_mutex>(), std::move(handlerList)) } ); } else { @@ -763,6 +776,14 @@ bool DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken &dbu } signalEntry->second.first->unlock(); } + + if (lastHandlerRemoved) { + dbusSignalHandlerTable_.erase(signalEntry); + removeLibdbusSignalMatchRule(std::get<0>(dbusSignalHandlerToken), + std::get<1>(dbusSignalHandlerToken), + std::get<2>(dbusSignalHandlerToken)); + } + return lastHandlerRemoved; } @@ -874,12 +895,12 @@ bool DBusConnection::addLibdbusSignalMatchRule(const std::string& dbusMatchRule) // add the libdbus message signal filter if (!libdbusSignalMatchRulesCount_) { - libdbusSuccess = 0 != dbus_connection_add_filter( - connection_, + libdbusSuccess = 0 != dbus_connection_add_filter( + connection_, &onLibdbusSignalFilterThunk, this, NULL - ); + ); } // finally add the match rule @@ -912,10 +933,10 @@ bool DBusConnection::removeLibdbusSignalMatchRule(const std::string& dbusMatchRu dbus_bus_remove_match(connection_, dbusMatchRule.c_str(), NULL); - libdbusSignalMatchRulesCount_--; - if (libdbusSignalMatchRulesCount_ == 0) { - dbus_connection_remove_filter(connection_, &onLibdbusSignalFilterThunk, this); - } + libdbusSignalMatchRulesCount_--; + if (libdbusSignalMatchRulesCount_ == 0) { + dbus_connection_remove_filter(connection_, &onLibdbusSignalFilterThunk, this); + } resumeDispatching(); @@ -968,7 +989,7 @@ void DBusConnection::unregisterObjectPath(const std::string& objectPath) { if (isConnected()) { dbus_bool_t libdbusSuccess - = dbus_connection_unregister_object_path(connection_, objectPath.c_str()); + = dbus_connection_unregister_object_path(connection_, objectPath.c_str()); assert(libdbusSuccess); } } @@ -1007,14 +1028,15 @@ void DBusConnection::addLibdbusSignalMatchRule(const std::string& objectPath, if (isConnected()) { bool libdbusSuccess = true; suspendDispatching(); + // add the libdbus message signal filter if (isFirstMatchRule) { - libdbusSuccess = 0 != dbus_connection_add_filter( - connection_, - &onLibdbusSignalFilterThunk, - this, - NULL); + libdbusSuccess = 0 != dbus_connection_add_filter( + connection_, + &onLibdbusSignalFilterThunk, + this, + NULL); assert(libdbusSuccess); } diff --git a/src/CommonAPI/DBus/DBusDaemonProxy.cpp b/src/CommonAPI/DBus/DBusDaemonProxy.cpp index 489f06b..fe87335 100644 --- a/src/CommonAPI/DBus/DBusDaemonProxy.cpp +++ b/src/CommonAPI/DBus/DBusDaemonProxy.cpp @@ -36,7 +36,7 @@ static const char *DAEMON_DBUS_INTERFACE = DBusDaemonProxy::getInterfaceId(); static const char *DAEMON_DBUS_OBJECT_PATH = "/org/freedesktop/DBus"; static const char *DAEMON_DBUS_BUS = "org.freedesktop.DBus"; static DBusAddress dbusProxyAddress(DAEMON_DBUS_INTERFACE, DAEMON_DBUS_OBJECT_PATH, DAEMON_DBUS_BUS); -static CommonAPI::CallInfo daemonProxyInfo(2000); +static CommonAPI::CallInfo daemonProxyInfo(30000); DBusDaemonProxy::DBusDaemonProxy(const std::shared_ptr<DBusProxyConnection>& dbusConnection): DBusProxyBase(dbusProxyAddress, dbusConnection), diff --git a/src/CommonAPI/DBus/DBusFactory.cpp b/src/CommonAPI/DBus/DBusFactory.cpp index f75619c..afe5ad7 100644 --- a/src/CommonAPI/DBus/DBusFactory.cpp +++ b/src/CommonAPI/DBus/DBusFactory.cpp @@ -27,8 +27,7 @@ Factory::get() { return theFactory; } -Factory::Factory() - : dBusBusType_(DBusAddressTranslator::get()->getDBusBusType()) { +Factory::Factory() { } Factory::~Factory() { @@ -224,8 +223,9 @@ Factory::getConnection(const ConnectionId_t &_connectionId) { } // No connection found, lets create and initialize one + DBusType_t dbusType = DBusAddressTranslator::get()->getDBusBusType(_connectionId); std::shared_ptr<DBusConnection> itsConnection - = std::make_shared<DBusConnection>(dBusBusType_); + = std::make_shared<DBusConnection>(dbusType); connections_.insert({ _connectionId, itsConnection }); itsConnection->connect(true); @@ -244,7 +244,7 @@ Factory::getConnection(std::shared_ptr<MainLoopContext> _context) { // No connection found, lets create and initialize one std::shared_ptr<DBusConnection> itsConnection - = std::make_shared<DBusConnection>(dBusBusType_); + = std::make_shared<DBusConnection>(DBusType_t::SESSION); contextConnections_.insert({ _context.get(), itsConnection } ); itsConnection->connect(false); diff --git a/src/CommonAPI/DBus/DBusMainLoopContext.cpp b/src/CommonAPI/DBus/DBusMainLoopContext.cpp index beaee2c..c20beb9 100644 --- a/src/CommonAPI/DBus/DBusMainLoopContext.cpp +++ b/src/CommonAPI/DBus/DBusMainLoopContext.cpp @@ -65,6 +65,8 @@ void DBusWatch::startWatching() { #ifdef WIN32 pollFileDescriptor_.fd = dbus_watch_get_socket(libdbusWatch_); + wsaEvent_ = WSACreateEvent(); + WSAEventSelect(pollFileDescriptor_.fd, wsaEvent_, FD_READ); #else pollFileDescriptor_.fd = dbus_watch_get_unix_fd(libdbusWatch_); #endif @@ -88,6 +90,12 @@ const pollfd& DBusWatch::getAssociatedFileDescriptor() { return pollFileDescriptor_; } +#ifdef WIN32 +const HANDLE& DBusWatch::getAssociatedEvent() { + return wsaEvent_; +} +#endif + void DBusWatch::dispatch(unsigned int eventFlags) { #ifdef WIN32 unsigned int dbusWatchFlags = 0; @@ -111,7 +119,11 @@ void DBusWatch::dispatch(unsigned int eventFlags) { ((eventFlags & POLLERR) >> 1) | ((eventFlags & POLLHUP) >> 1); #endif - dbus_watch_handle(libdbusWatch_, dbusWatchFlags); + dbus_bool_t response = dbus_watch_handle(libdbusWatch_, dbusWatchFlags); + + if (!response) { + printf("dbus_watch_handle returned FALSE!"); + } } const std::vector<DispatchSource*>& DBusWatch::getDependentDispatchSources() { diff --git a/src/CommonAPI/DBus/DBusProxy.cpp b/src/CommonAPI/DBus/DBusProxy.cpp index 47336f7..1de88fc 100644 --- a/src/CommonAPI/DBus/DBusProxy.cpp +++ b/src/CommonAPI/DBus/DBusProxy.cpp @@ -9,6 +9,8 @@ #include <CommonAPI/Utils.hpp> #include <CommonAPI/DBus/DBusProxy.hpp> #include <CommonAPI/DBus/DBusUtils.hpp> +#include <CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp> +#include <CommonAPI/Logger.hpp> namespace CommonAPI { namespace DBus { @@ -17,7 +19,7 @@ DBusProxyStatusEvent::DBusProxyStatusEvent(DBusProxy *_dbusProxy) : dbusProxy_(_dbusProxy) { } -void DBusProxyStatusEvent::onListenerAdded(const Listener& listener) { +void DBusProxyStatusEvent::onListenerAdded(const Listener& listener, const Subscription subscription) { if (dbusProxy_->isAvailable()) listener(AvailabilityStatus::AVAILABLE); } @@ -28,7 +30,8 @@ DBusProxy::DBusProxy(const DBusAddress &_dbusAddress, dbusProxyStatusEvent_(this), availabilityStatus_(AvailabilityStatus::UNKNOWN), interfaceVersionAttribute_(*this, "uu", "getInterfaceVersion"), - dbusServiceRegistry_(DBusServiceRegistry::get(_connection)) + dbusServiceRegistry_(DBusServiceRegistry::get(_connection)), + signalMemberHandlerInfo_(3000) { } @@ -49,11 +52,15 @@ bool DBusProxy::isAvailable() const { } bool DBusProxy::isAvailableBlocking() const { - std::unique_lock<std::mutex> lock(availabilityMutex_); + std::unique_lock<std::mutex> lock(availabilityMutex_); + + if(!getDBusConnection()->hasDispatchThread()) { + return isAvailable(); + } while (availabilityStatus_ != AvailabilityStatus::AVAILABLE) { - availabilityCondition_.wait(lock); - } + availabilityCondition_.wait(lock); + } return true; } @@ -66,9 +73,79 @@ InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() { return interfaceVersionAttribute_; } +void DBusProxy::signalMemberCallback(const CallStatus dbusMessageCallStatus, + const DBusMessage& dbusMessage, + DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, + const uint32_t tag) { + dbusSignalHandler->onSignalDBusMessage(dbusMessage); +} + +void DBusProxy::signalInitialValueCallback(const CallStatus dbusMessageCallStatus, + const DBusMessage& dbusMessage, + DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, + const uint32_t tag) { + dbusSignalHandler->onInitialValueSignalDBusMessage(dbusMessage, tag); +} + void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus) { - availabilityStatus_ = availabilityStatus; - dbusProxyStatusEvent_.notifyListeners(availabilityStatus); + if (availabilityStatus != availabilityStatus_) { + availabilityStatusMutex_.lock(); + availabilityStatus_ = availabilityStatus; + availabilityStatusMutex_.unlock(); + + dbusProxyStatusEvent_.notifyListeners(availabilityStatus); + + if (availabilityStatus == AvailabilityStatus::AVAILABLE) { + std::lock_guard < std::mutex > queueLock(signalMemberHandlerQueueMutex_); + + for(auto signalMemberHandlerIterator = signalMemberHandlerQueue_.begin(); + signalMemberHandlerIterator != signalMemberHandlerQueue_.end(); + signalMemberHandlerIterator++) { + + if (!std::get<7>(*signalMemberHandlerIterator)) { + connection_->addSignalMemberHandler( + std::get<0>(*signalMemberHandlerIterator), + std::get<1>(*signalMemberHandlerIterator), + std::get<2>(*signalMemberHandlerIterator), + std::get<3>(*signalMemberHandlerIterator), + std::get<5>(*signalMemberHandlerIterator), + std::get<6>(*signalMemberHandlerIterator)); + std::get<7>(*signalMemberHandlerIterator) = true; + + DBusMessage message = createMethodCall(std::get<4>(*signalMemberHandlerIterator), ""); + + DBusProxyAsyncSignalMemberCallbackHandler::FunctionType myFunc = std::bind( + &DBusProxy::signalMemberCallback, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4); + connection_->sendDBusMessageWithReplyAsync( + message, + DBusProxyAsyncSignalMemberCallbackHandler::create(myFunc, std::get<5>(*signalMemberHandlerIterator), 0), + &signalMemberHandlerInfo_); + } + } + } else { + std::lock_guard < std::mutex > queueLock(signalMemberHandlerQueueMutex_); + + for(auto signalMemberHandlerIterator = signalMemberHandlerQueue_.begin(); + signalMemberHandlerIterator != signalMemberHandlerQueue_.end(); + signalMemberHandlerIterator++) { + + if (std::get<7>(*signalMemberHandlerIterator)) { + DBusProxyConnection::DBusSignalHandlerToken signalHandlerToken ( + std::get<0>(*signalMemberHandlerIterator), + std::get<1>(*signalMemberHandlerIterator), + std::get<2>(*signalMemberHandlerIterator), + std::get<3>(*signalMemberHandlerIterator)); + connection_->removeSignalMemberHandler(signalHandlerToken, std::get<5>(*signalMemberHandlerIterator)); + std::get<7>(*signalMemberHandlerIterator) = false; + } + } + } + } availabilityCondition_.notify_one(); } @@ -96,5 +173,151 @@ void DBusProxy::unsubscribeFromSelectiveBroadcast(const std::string& eventName, getDBusConnection()->unsubscribeFromSelectiveBroadcast(eventName, subscription, this, dbusSignalHandler); } +DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler( + const std::string& objectPath, + const std::string& interfaceName, + const std::string& signalName, + const std::string& signalSignature, + DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, + const bool justAddFilter) { + return DBusProxyBase::addSignalMemberHandler( + objectPath, + interfaceName, + signalName, + signalSignature, + dbusSignalHandler, + justAddFilter); +} + +DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler( + const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName, + const std::string &signalSignature, + const std::string &getMethodName, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const bool justAddFilter) { + + DBusProxyConnection::DBusSignalHandlerToken signalHandlerToken ( + objectPath, + interfaceName, + signalName, + signalSignature); + + if (getMethodName != "") { + + SignalMemberHandlerTuple signalMemberHandler( + objectPath, + interfaceName, + signalName, + signalSignature, + getMethodName, + dbusSignalHandler, + justAddFilter, + false); + + availabilityStatusMutex_.lock(); + if (availabilityStatus_ == AvailabilityStatus::AVAILABLE) { + availabilityStatusMutex_.unlock(); + signalHandlerToken = connection_->addSignalMemberHandler( + objectPath, + interfaceName, + signalName, + signalSignature, + dbusSignalHandler, + justAddFilter); + std::get<7>(signalMemberHandler) = true; + } else { + availabilityStatusMutex_.unlock(); + } + addSignalMemberHandlerToQueue(signalMemberHandler); + } else { + signalHandlerToken = connection_->addSignalMemberHandler( + objectPath, + interfaceName, + signalName, + signalSignature, + dbusSignalHandler, + justAddFilter); + } + + return signalHandlerToken; +} + +void DBusProxy::addSignalMemberHandlerToQueue(SignalMemberHandlerTuple& _signalMemberHandler) { + + std::lock_guard < std::mutex > queueLock(signalMemberHandlerQueueMutex_); + bool found = false; + + for(auto signalMemberHandlerIterator = signalMemberHandlerQueue_.begin(); + signalMemberHandlerIterator != signalMemberHandlerQueue_.end(); + signalMemberHandlerIterator++) { + + if ( (std::get<0>(*signalMemberHandlerIterator) == std::get<0>(_signalMemberHandler)) && + (std::get<1>(*signalMemberHandlerIterator) == std::get<1>(_signalMemberHandler)) && + (std::get<2>(*signalMemberHandlerIterator) == std::get<2>(_signalMemberHandler)) && + (std::get<3>(*signalMemberHandlerIterator) == std::get<3>(_signalMemberHandler))) { + + found = true; + break; + } + } + if (!found) { + signalMemberHandlerQueue_.push_back(_signalMemberHandler); + } +} + +bool DBusProxy::removeSignalMemberHandler( + const DBusProxyConnection::DBusSignalHandlerToken &_dbusSignalHandlerToken, + const DBusProxyConnection::DBusSignalHandler *_dbusSignalHandler) { + + { + std::lock_guard < std::mutex > queueLock(signalMemberHandlerQueueMutex_); + for(auto signalMemberHandlerIterator = signalMemberHandlerQueue_.begin(); + signalMemberHandlerIterator != signalMemberHandlerQueue_.end(); + signalMemberHandlerIterator++) { + + if ( (std::get<0>(*signalMemberHandlerIterator) == std::get<0>(_dbusSignalHandlerToken)) && + (std::get<1>(*signalMemberHandlerIterator) == std::get<1>(_dbusSignalHandlerToken)) && + (std::get<2>(*signalMemberHandlerIterator) == std::get<2>(_dbusSignalHandlerToken)) && + (std::get<3>(*signalMemberHandlerIterator) == std::get<3>(_dbusSignalHandlerToken))) { + signalMemberHandlerIterator = signalMemberHandlerQueue_.erase(signalMemberHandlerIterator); + + if (signalMemberHandlerIterator == signalMemberHandlerQueue_.end()) { + break; + } + } + } + } + + return connection_->removeSignalMemberHandler(_dbusSignalHandlerToken, _dbusSignalHandler); +} + +void DBusProxy::getCurrentValueForSignalListener( + const std::string &getMethodName, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const uint32_t subscription) { + + availabilityStatusMutex_.lock(); + if (availabilityStatus_ == AvailabilityStatus::AVAILABLE) { + availabilityStatusMutex_.unlock(); + + DBusMessage message = createMethodCall(getMethodName, ""); + + DBusProxyAsyncSignalMemberCallbackHandler::FunctionType myFunc = std::bind(&DBusProxy::signalInitialValueCallback, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4); + connection_->sendDBusMessageWithReplyAsync( + message, + DBusProxyAsyncSignalMemberCallbackHandler::create(myFunc, dbusSignalHandler, subscription), + &signalMemberHandlerInfo_); + } else { + availabilityStatusMutex_.unlock(); + } +} + } // namespace DBus } // namespace CommonAPI diff --git a/src/CommonAPI/DBus/DBusProxyBase.cpp b/src/CommonAPI/DBus/DBusProxyBase.cpp index 56d5717..ae8faac 100644 --- a/src/CommonAPI/DBus/DBusProxyBase.cpp +++ b/src/CommonAPI/DBus/DBusProxyBase.cpp @@ -36,20 +36,6 @@ DBusProxyBase::getDBusConnection() const { } DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandler( - const std::string& signalName, - const std::string& signalSignature, - DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, - const bool justAddFilter) { - return addSignalMemberHandler( - getDBusAddress().getObjectPath(), - getDBusAddress().getInterface(), - signalName, - signalSignature, - dbusSignalHandler, - justAddFilter); -} - -DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandler( const std::string& objectPath, const std::string& interfaceName, const std::string& signalName, @@ -65,8 +51,25 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandle justAddFilter); } -bool DBusProxyBase::removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& dbusSignalHandlerToken, const DBusProxyConnection::DBusSignalHandler* dbusSignalHandler) { - return connection_->removeSignalMemberHandler(dbusSignalHandlerToken, dbusSignalHandler); +DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandler( + const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName, + const std::string &signalSignature, + const std::string &getMethodName, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const bool justAddFilter) { + return addSignalMemberHandler( + objectPath, + interfaceName, + signalName, + signalSignature, + dbusSignalHandler, + justAddFilter); +} + +bool DBusProxyBase::removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& _dbusSignalHandlerToken, const DBusProxyConnection::DBusSignalHandler* _dbusSignalHandler) { + return connection_->removeSignalMemberHandler(_dbusSignalHandlerToken, _dbusSignalHandler); } } // namespace DBus diff --git a/src/CommonAPI/DBus/DBusServiceRegistry.cpp b/src/CommonAPI/DBus/DBusServiceRegistry.cpp index 7d12878..f18ff44 100644 --- a/src/CommonAPI/DBus/DBusServiceRegistry.cpp +++ b/src/CommonAPI/DBus/DBusServiceRegistry.cpp @@ -453,15 +453,18 @@ void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) { dbusInputStream >> dbusObjectPath; if (_dbusMessage.hasMemberName("InterfacesAdded")) { + std::string dbusInterfaceName; dbusInterfaceNameState = DBusRecordState::AVAILABLE; - DBusObjectPathAndInterfacesDict dbusObjectPathAndInterfacesDict; - dbusInputStream >> dbusObjectPathAndInterfacesDict; - - for (auto& dbusInterfaceIterator : dbusObjectPathAndInterfacesDict) { - const auto& dbusInterfaceName = dbusInterfaceIterator.first; + dbusInputStream.beginReadMapOfSerializableStructs(); + while (!dbusInputStream.readMapCompleted()) { + dbusInputStream.align(8); + dbusInputStream >> dbusInterfaceName; + dbusInputStream.skipMap(); + assert(!dbusInputStream.hasError()); dbusInterfaceNames.insert(dbusInterfaceName); } + dbusInputStream.endReadMapOfSerializableStructs(); } else { std::vector<std::string> removedDBusInterfaceNames; @@ -748,7 +751,7 @@ void DBusServiceRegistry::onIntrospectCallback(const CallStatus& callStatus, dbusObjectPathRecord.state = DBusRecordState::RESOLVED; dbusObjectPathRecord.promiseOnResolve.set_value(dbusObjectPathRecord.state); mutexObjectPathsResolveCount.lock(); - objectPathsToResolve++; + objectPathsToResolve--; mutexObjectPathsResolveCount.unlock(); monitorResolveAllObjectPaths_.notify_all(); @@ -801,12 +804,13 @@ void DBusServiceRegistry::processIntrospectionObjectPath(const pugi::xml_node& n void DBusServiceRegistry::processIntrospectionInterface(const pugi::xml_node& node, const std::string& rootObjectPath, const std::string& fullObjectPath, const std::string& dbusServiceUniqueName) { std::string interfaceName = node.attribute("name").as_string(); - DBusUniqueNameRecord& dbusUniqueNameRecord = dbusUniqueNamesMap_[dbusServiceUniqueName]; DBusObjectPathCache& dbusObjectPathCache = dbusUniqueNameRecord.dbusObjectPathsCache[fullObjectPath]; if(!isOrgFreedesktopDBusInterface(interfaceName)) { dbusObjectPathCache.dbusInterfaceNamesCache.insert(interfaceName); + } else if (translator_->isOrgFreedesktopDBusPeerMapped() && (interfaceName == "org.freedesktop.DBus.Peer")) { + dbusObjectPathCache.dbusInterfaceNamesCache.insert(interfaceName); } for(pugi::xml_node subNode : node.children()) { |