1 /* Copyright (C) 2013 BMW Group
2 * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3 * Author: Juergen Gehring (juergen.gehring@bmw.de)
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "DBusConnection.h"
10 #include "DBusFactory.h"
11 #include "DBusAddressTranslator.h"
12 #include "DBusServiceRegistry.h"
13 #include "DBusUtils.h"
14 #include "DBusServicePublisher.h"
19 #include <unordered_map>
26 std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_;
27 std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_;
30 void DBusFactory::registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryMethod) {
31 if(!registeredProxyFactoryFunctions_) {
32 registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction>();
34 registeredProxyFactoryFunctions_->insert({interfaceName, proxyFactoryMethod});
37 void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAdapterFactoryFunction adapterFactoryMethod) {
38 if(!registeredAdapterFactoryFunctions_) {
39 registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction>();
41 registeredAdapterFactoryFunctions_->insert({interfaceName, adapterFactoryMethod});
45 DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo, std::shared_ptr<MainLoopContext> mainLoopContext) :
46 CommonAPI::Factory(runtime, middlewareInfo),
47 dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()),
48 acquiredConnectionName_(""),
49 mainLoopContext_(mainLoopContext) {
50 bool startDispatchThread = !mainLoopContext_;
51 dbusConnection_->connect(startDispatchThread);
52 if(mainLoopContext_) {
53 dbusConnection_->attachMainLoopContext(mainLoopContext);
58 DBusFactory::~DBusFactory() {
62 std::vector<std::string> DBusFactory::getAvailableServiceInstances(const std::string& serviceName,
63 const std::string& domainName) {
64 return dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstances(serviceName, domainName);
68 void DBusFactory::getAvailableServiceInstancesAsync(Factory::GetAvailableServiceInstancesCallback callback, const std::string& serviceName, const std::string& serviceDomainName) {
69 dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstancesAsync(callback, serviceName, serviceDomainName);
73 bool DBusFactory::isServiceInstanceAlive(const std::string& serviceAddress) {
74 std::vector<std::string> parts = split(serviceAddress, ':');
75 assert(parts[0] == "local");
77 std::string interfaceName;
78 std::string connectionName;
79 std::string objectPath;
80 DBusAddressTranslator::getInstance().searchForDBusAddress(serviceAddress, interfaceName, connectionName, objectPath);
82 return dbusConnection_->getDBusServiceRegistry()->isServiceInstanceAlive(interfaceName, connectionName, objectPath);
86 bool DBusFactory::isServiceInstanceAlive(const std::string& participantId,
87 const std::string& serviceName,
88 const std::string& domainName) {
89 std::string serviceAddress = domainName + ":" + serviceName + ":" + participantId;
90 return isServiceInstanceAlive(serviceAddress);
94 SubscriptionStatus DBusFactory::isServiceInstanceAliveCallbackThunk(Factory::IsServiceInstanceAliveCallback callback, const AvailabilityStatus& status) {
95 callback(status == AvailabilityStatus::AVAILABLE);
96 return SubscriptionStatus::CANCEL;
99 void DBusFactory::isServiceInstanceAliveAsync(Factory::IsServiceInstanceAliveCallback callback, const std::string& serviceAddress) {
100 std::string interfaceName;
101 std::string connectionName;
102 std::string objectPath;
104 DBusAddressTranslator::getInstance().searchForDBusAddress(serviceAddress, interfaceName, connectionName, objectPath);
106 dbusConnection_->getDBusServiceRegistry()->subscribeAvailabilityListener(
108 std::bind(&DBusFactory::isServiceInstanceAliveCallbackThunk,
111 std::placeholders::_1)
115 void DBusFactory::isServiceInstanceAliveAsync(Factory::IsServiceInstanceAliveCallback callback, const std::string& serviceInstanceID, const std::string& serviceName, const std::string& serviceDomainName) {
116 std::string commonApiAddress = serviceDomainName + ":" + serviceName + ":" + serviceInstanceID;
117 isServiceInstanceAliveAsync(callback, commonApiAddress);
121 std::shared_ptr<Proxy> DBusFactory::createProxy(const char* interfaceId,
122 const std::string& participantId,
123 const std::string& serviceName,
124 const std::string& domain) {
125 std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
127 std::string interfaceName;
128 std::string connectionName;
129 std::string objectPath;
131 DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
133 if(!registeredProxyFactoryFunctions_) {
134 registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction> {};
137 for (auto it = registeredProxyFactoryFunctions_->begin(); it != registeredProxyFactoryFunctions_->end(); ++it) {
138 if(it->first == interfaceId) {
139 return (it->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_);
146 bool DBusFactory::registerAdapter(std::shared_ptr<StubBase> stubBase,
147 const char* interfaceId,
148 const std::string& participantId,
149 const std::string& serviceName,
150 const std::string& domain) {
151 assert(dbusConnection_->isConnected());
153 std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
155 std::string interfaceName;
156 std::string connectionName;
157 std::string objectPath;
159 DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
161 if(acquiredConnectionName_ == "") {
162 bool isServiceNameAcquired = dbusConnection_->requestServiceNameAndBlock(connectionName);
163 if(!isServiceNameAcquired) {
166 acquiredConnectionName_ = connectionName;
167 } else if (acquiredConnectionName_ != connectionName) {
171 if(!registeredAdapterFactoryFunctions_) {
172 registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction> {};
175 auto foundFunction = registeredAdapterFactoryFunctions_->find(interfaceId);
176 if(foundFunction != registeredAdapterFactoryFunctions_->end()) {
177 std::shared_ptr<DBusStubAdapter> dbusStubAdapter = (foundFunction->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_, stubBase);
178 if(!dbusStubAdapter) {
181 if(DBusServicePublisher::getInstance()->registerService(commonApiAddress, dbusStubAdapter)) {
182 dbusStubAdapter->init();
190 bool DBusFactory::unregisterService(const std::string& participantId, const std::string& serviceName, const std::string& domain) {
191 std::string serviceAddress(domain + ":" + serviceName + ":" + participantId);
192 return DBusServicePublisher::getInstance()->unregisterService(serviceAddress);
197 } // namespace CommonAPI