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 "DBusAddressTranslator.h"
10 #include "DBusUtils.h"
12 #include <unordered_set>
24 DBUS_CONNECTION, DBUS_OBJECT, DBUS_INTERFACE
27 static const std::unordered_map<std::string, TypeEnum> allowedValueTypes = {
28 {"dbus_connection", TypeEnum::DBUS_CONNECTION},
29 {"dbus_object", TypeEnum::DBUS_OBJECT},
30 {"dbus_interface", TypeEnum::DBUS_INTERFACE}
34 DBusAddressTranslator::DBusAddressTranslator() {}
37 void DBusAddressTranslator::init() {
38 std::string fqnOfConfigFile = getCurrentBinaryFileFQN();
39 fqnOfConfigFile += DBUS_CONFIG_SUFFIX;
41 std::ifstream addressConfigFile;
42 addressConfigFile.open(fqnOfConfigFile.c_str());
44 if(addressConfigFile.is_open()) {
45 readConfigFile(addressConfigFile);
46 addressConfigFile.close();
49 addressConfigFile.clear();
50 std::vector<std::string> splittedConfigFQN = split(fqnOfConfigFile, '/');
51 std::string globalConfigFQN = DBUS_GLOBAL_CONFIG_ROOT + splittedConfigFQN.at(splittedConfigFQN.size() - 1);
52 addressConfigFile.open(globalConfigFQN);
53 if(addressConfigFile.is_open()) {
54 readConfigFile(addressConfigFile);
55 addressConfigFile.close();
58 addressConfigFile.clear();
59 addressConfigFile.open(DBUS_GLOBAL_CONFIG_FQN);
60 if(addressConfigFile.is_open()) {
61 readConfigFile(addressConfigFile);
62 addressConfigFile.close();
67 inline void readValue(std::string& readLine, DBusServiceAddress& dbusServiceAddress) {
68 std::stringstream readStream(readLine);
70 std::string paramName;
71 std::string paramValue;
73 getline(readStream, paramName, '=');
75 auto typeEntry = allowedValueTypes.find(paramName);
76 if(typeEntry != allowedValueTypes.end()) {
77 getline(readStream, paramValue);
78 switch(typeEntry->second) {
79 case TypeEnum::DBUS_CONNECTION:
80 std::get<0>(dbusServiceAddress) = paramValue;
82 case TypeEnum::DBUS_OBJECT:
83 std::get<1>(dbusServiceAddress) = paramValue;
85 case TypeEnum::DBUS_INTERFACE:
86 std::get<2>(dbusServiceAddress) = paramValue;
93 inline void reset(DBusServiceAddress& dbusServiceAddress) {
94 std::get<0>(dbusServiceAddress) = "";
95 std::get<1>(dbusServiceAddress) = "";
96 std::get<2>(dbusServiceAddress) = "";
100 void DBusAddressTranslator::readConfigFile(std::ifstream& addressConfigFile) {
101 std::string currentlyParsedCommonApiAddress;
102 DBusServiceAddress dbusServiceAddress;
103 reset(dbusServiceAddress);
105 bool newAddressFound = false;
107 while (addressConfigFile.good()) {
108 std::string readLine;
109 getline(addressConfigFile, readLine);
110 const size_t readLineLength = readLine.length();
112 if (readLine[0] == '[' && readLine[readLineLength - 1] == ']') {
113 if (newAddressFound) {
114 fillUndefinedValues(dbusServiceAddress, currentlyParsedCommonApiAddress);
115 knownDBusAddresses.insert( {currentlyParsedCommonApiAddress, dbusServiceAddress});
116 knownCommonAddresses.insert( {dbusServiceAddress, currentlyParsedCommonApiAddress});
118 reset(dbusServiceAddress);
119 currentlyParsedCommonApiAddress = readLine.substr(1, readLineLength - 2);
120 newAddressFound = knownDBusAddresses.find(currentlyParsedCommonApiAddress) == knownDBusAddresses.end();
122 } else if (newAddressFound) {
123 readValue(readLine, dbusServiceAddress);
126 if(newAddressFound) {
127 fillUndefinedValues(dbusServiceAddress, currentlyParsedCommonApiAddress);
128 knownDBusAddresses.insert( {currentlyParsedCommonApiAddress, dbusServiceAddress});
129 knownCommonAddresses.insert( {dbusServiceAddress, currentlyParsedCommonApiAddress});
134 void DBusAddressTranslator::fillUndefinedValues(DBusServiceAddress& dbusServiceAddress, const std::string& commonApiAddress) const {
135 std::string connectionName;
136 std::string objectPath;
137 std::string interfaceName;
139 findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
141 std::get<0>(dbusServiceAddress) = std::get<0>(dbusServiceAddress) == "" ? connectionName : std::get<0>(dbusServiceAddress);
142 std::get<1>(dbusServiceAddress) = std::get<1>(dbusServiceAddress) == "" ? objectPath : std::get<1>(dbusServiceAddress);
143 std::get<2>(dbusServiceAddress) = std::get<2>(dbusServiceAddress) == "" ? interfaceName : std::get<2>(dbusServiceAddress);
147 DBusAddressTranslator& DBusAddressTranslator::getInstance() {
148 static DBusAddressTranslator* dbusNameService_;
149 if(!dbusNameService_) {
150 dbusNameService_ = new DBusAddressTranslator();
151 dbusNameService_->init();
153 return *dbusNameService_;
157 void DBusAddressTranslator::searchForDBusAddress(const std::string& commonApiAddress,
158 std::string& interfaceName,
159 std::string& connectionName,
160 std::string& objectPath) {
162 const auto& foundAddressMapping = knownDBusAddresses.find(commonApiAddress);
164 if(foundAddressMapping != knownDBusAddresses.end()) {
165 connectionName = std::get<0>(foundAddressMapping->second);
166 objectPath = std::get<1>(foundAddressMapping->second);
167 interfaceName = std::get<2>(foundAddressMapping->second);
169 findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
170 knownDBusAddresses.insert( {commonApiAddress, std::make_tuple(connectionName, objectPath, interfaceName) } );
174 void DBusAddressTranslator::searchForCommonAddress(const std::string& interfaceName,
175 const std::string& connectionName,
176 const std::string& objectPath,
177 std::string& commonApiAddress) {
179 DBusServiceAddress dbusAddress(connectionName, objectPath, interfaceName);
181 const auto& foundAddressMapping = knownCommonAddresses.find(dbusAddress);
182 if (foundAddressMapping != knownCommonAddresses.end()) {
183 commonApiAddress = foundAddressMapping->second;
185 findFallbackCommonAddress(commonApiAddress, interfaceName, connectionName, objectPath);
186 knownCommonAddresses.insert( {std::move(dbusAddress), commonApiAddress} );
191 void DBusAddressTranslator::findFallbackDBusAddress(const std::string& commonApiAddress,
192 std::string& interfaceName,
193 std::string& connectionName,
194 std::string& objectPath) const {
195 std::vector<std::string> parts = split(commonApiAddress, ':');
196 interfaceName = parts[1];
197 connectionName = parts[2];
198 objectPath = '/' + parts[2];
199 std::replace(objectPath.begin(), objectPath.end(), '.', '/');
202 void DBusAddressTranslator::findFallbackCommonAddress(std::string& commonApiAddress,
203 const std::string& interfaceName,
204 const std::string& connectionName,
205 const std::string& objectPath) const {
206 commonApiAddress = "local:" + interfaceName + ":" + connectionName;
211 }// namespace CommonAPI