Added a return of "false" if the dbus connection name could not be
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusFactory.cpp
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/. */
7 #include "DBusProxy.h"
8 #include "DBusConnection.h"
9 #include "DBusFactory.h"
10 #include "DBusAddressTranslator.h"
11 #include "DBusServiceRegistry.h"
12 #include "DBusUtils.h"
13
14 #include <algorithm>
15 #include <cassert>
16 #include <sstream>
17 #include <unordered_map>
18 #include <vector>
19
20 namespace CommonAPI {
21 namespace DBus {
22
23 std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_;
24 std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_;
25
26
27 void DBusFactory::registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryMethod) {
28     if(!registeredProxyFactoryFunctions_) {
29         registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction>();
30     }
31     registeredProxyFactoryFunctions_->insert({interfaceName, proxyFactoryMethod});
32 }
33
34 void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAdapterFactoryFunction adapterFactoryMethod) {
35     if(!registeredAdapterFactoryFunctions_) {
36         registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction>();
37     }
38     registeredAdapterFactoryFunctions_->insert({interfaceName, adapterFactoryMethod});
39 }
40
41
42
43 DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo) :
44                 CommonAPI::Factory(runtime, middlewareInfo),
45                 dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()),
46                 acquiredConnectionName_("") {
47     dbusConnection_->connect();
48 }
49
50
51 DBusFactory::~DBusFactory() {
52 }
53
54
55 std::vector<std::string> DBusFactory::getAvailableServiceInstances(const std::string& serviceName,
56                                                                    const std::string& domainName) {
57     return dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstances(serviceName, domainName);
58 }
59
60
61 bool DBusFactory::isServiceInstanceAlive(const std::string& serviceAddress) {
62     std::vector<std::string> parts = split(serviceAddress, ':');
63     assert(parts[0] == "local");
64
65     std::string interfaceName;
66     std::string connectionName;
67     std::string objectPath;
68     DBusAddressTranslator::getInstance().searchForDBusAddress(serviceAddress, interfaceName, connectionName, objectPath);
69
70     return dbusConnection_->getDBusServiceRegistry()->isServiceInstanceAlive(interfaceName, connectionName, objectPath);
71 }
72
73
74 bool DBusFactory::isServiceInstanceAlive(const std::string& participantId,
75                                          const std::string& serviceName,
76                                          const std::string& domainName) {
77     std::string serviceAddress = domainName + ":" + serviceName + ":" + participantId;
78     return isServiceInstanceAlive(serviceAddress);
79 }
80
81
82 std::shared_ptr<Proxy> DBusFactory::createProxy(const char* interfaceId,
83                                                 const std::string& participantId,
84                                                 const std::string& serviceName,
85                                                 const std::string& domain) {
86     std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
87
88     std::string interfaceName;
89     std::string connectionName;
90     std::string objectPath;
91
92     DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
93
94     if(!registeredProxyFactoryFunctions_) {
95         registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction> {};
96     }
97
98     for (auto it = registeredProxyFactoryFunctions_->begin(); it != registeredProxyFactoryFunctions_->end(); ++it) {
99         if(it->first == interfaceId) {
100             return (it->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_);
101         }
102     }
103
104     return NULL;
105 }
106
107 bool DBusFactory::registerAdapter(std::shared_ptr<StubBase> stubBase,
108                                                                   const char* interfaceId,
109                                                                   const std::string& participantId,
110                                                                   const std::string& serviceName,
111                                                                   const std::string& domain) {
112     assert(dbusConnection_->isConnected());
113
114     std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
115
116     std::string interfaceName;
117     std::string connectionName;
118     std::string objectPath;
119
120     DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
121
122     if(acquiredConnectionName_ == "") {
123         bool isServiceNameAcquired = dbusConnection_->requestServiceNameAndBlock(connectionName);
124         if(!isServiceNameAcquired) {
125             return false;
126         }
127         acquiredConnectionName_ = connectionName;
128     } else if (acquiredConnectionName_ != connectionName) {
129         return false;
130     }
131
132     if(!registeredAdapterFactoryFunctions_) {
133         registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction> {};
134     }
135
136     auto foundFunction = registeredAdapterFactoryFunctions_->find(interfaceId);
137     if(foundFunction != registeredAdapterFactoryFunctions_->end()) {
138         std::shared_ptr<DBusStubAdapter> dbusStubAdapter =  (foundFunction->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_, stubBase);
139         if(!dbusStubAdapter) {
140             return false;
141         }
142         std::string address = domain + ":" + serviceName + ":" + participantId;
143         if(registeredServices_.insert( {std::move(address), dbusStubAdapter} ).second) {
144             dbusStubAdapter->init();
145             return true;
146         }
147     }
148
149         return false;
150 }
151
152 bool DBusFactory::unregisterService(const std::string& participantId, const std::string& serviceName, const std::string& domain) {
153     std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
154         auto foundStubAdapter = registeredServices_.find(commonApiAddress);
155         if(foundStubAdapter != registeredServices_.end()) {
156                 std::shared_ptr<DBusStubAdapter> stubAdapter = foundStubAdapter->second;
157                 stubAdapter->deinit();
158                 return registeredServices_.erase(commonApiAddress);
159         }
160         return false;
161 }
162
163
164 } // namespace DBus
165 } // namespace CommonAPI