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 inline void readValue(std::string& readLine, DBusServiceAddress& dbusServiceAddress) {
35 std::stringstream readStream(readLine);
37 std::string paramName;
38 std::string paramValue;
40 getline(readStream, paramName, '=');
42 auto typeEntry = allowedValueTypes.find(paramName);
43 if(typeEntry != allowedValueTypes.end()) {
44 getline(readStream, paramValue);
45 switch(typeEntry->second) {
46 case TypeEnum::DBUS_CONNECTION:
47 std::get<0>(dbusServiceAddress) = paramValue;
49 case TypeEnum::DBUS_OBJECT:
50 std::get<1>(dbusServiceAddress) = paramValue;
52 case TypeEnum::DBUS_INTERFACE:
53 std::get<2>(dbusServiceAddress) = paramValue;
60 inline void reset(DBusServiceAddress& dbusServiceAddress) {
61 std::get<0>(dbusServiceAddress) = "";
62 std::get<1>(dbusServiceAddress) = "";
63 std::get<2>(dbusServiceAddress) = "";
67 void DBusAddressTranslator::fillUndefinedValues(DBusServiceAddress& dbusServiceAddress, const std::string& commonApiAddress) const {
68 std::string connectionName;
69 std::string objectPath;
70 std::string interfaceName;
72 findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
74 std::get<0>(dbusServiceAddress) = std::get<0>(dbusServiceAddress) == "" ? connectionName : std::get<0>(dbusServiceAddress);
75 std::get<1>(dbusServiceAddress) = std::get<1>(dbusServiceAddress) == "" ? objectPath : std::get<1>(dbusServiceAddress);
76 std::get<2>(dbusServiceAddress) = std::get<2>(dbusServiceAddress) == "" ? interfaceName : std::get<2>(dbusServiceAddress);
80 DBusAddressTranslator::DBusAddressTranslator() {}
83 void DBusAddressTranslator::init() {
84 std::string fqnOfConfigFile = getCurrentBinaryFileFQN();
85 fqnOfConfigFile += DBUS_CONFIG_SUFFIX;
87 std::ifstream addressConfigFile;
88 addressConfigFile.open(fqnOfConfigFile.c_str());
90 if(addressConfigFile.is_open()) {
91 readConfigFile(addressConfigFile);
92 addressConfigFile.close();
95 addressConfigFile.clear();
96 std::vector<std::string> splittedConfigFQN = split(fqnOfConfigFile, '/');
97 std::string globalConfigFQN = DBUS_GLOBAL_CONFIG_ROOT + splittedConfigFQN.at(splittedConfigFQN.size() - 1);
98 addressConfigFile.open(globalConfigFQN);
99 if(addressConfigFile.is_open()) {
100 readConfigFile(addressConfigFile);
101 addressConfigFile.close();
104 addressConfigFile.clear();
105 addressConfigFile.open(DBUS_GLOBAL_CONFIG_FQN);
106 if(addressConfigFile.is_open()) {
107 readConfigFile(addressConfigFile);
108 addressConfigFile.close();
113 void DBusAddressTranslator::readConfigFile(std::ifstream& addressConfigFile) {
114 std::string currentlyParsedCommonApiAddress;
115 DBusServiceAddress dbusServiceAddress;
116 reset(dbusServiceAddress);
118 bool currentAddressNotYetContained = false;
119 bool atLeastOneAddressFound = false;
121 while (addressConfigFile.good()) {
122 std::string readLine;
123 getline(addressConfigFile, readLine);
124 const size_t readLineLength = readLine.length();
126 if (readLine[0] == '[' && readLine[readLineLength - 1] == ']') {
127 if (atLeastOneAddressFound) {
128 fillUndefinedValues(dbusServiceAddress, currentlyParsedCommonApiAddress);
129 knownDBusAddresses.insert( {currentlyParsedCommonApiAddress, dbusServiceAddress});
130 knownCommonAddresses.insert( {dbusServiceAddress, currentlyParsedCommonApiAddress});
132 reset(dbusServiceAddress);
133 currentlyParsedCommonApiAddress = readLine.substr(1, readLineLength - 2);
134 currentAddressNotYetContained =
135 knownDBusAddresses.find(currentlyParsedCommonApiAddress) == knownDBusAddresses.end() &&
136 knownCommonAddresses.find(dbusServiceAddress) == knownCommonAddresses.end();
137 atLeastOneAddressFound = true;
139 } else if (currentAddressNotYetContained) {
140 readValue(readLine, dbusServiceAddress);
143 if(atLeastOneAddressFound) {
144 fillUndefinedValues(dbusServiceAddress, currentlyParsedCommonApiAddress);
145 knownDBusAddresses.insert( {currentlyParsedCommonApiAddress, dbusServiceAddress});
146 knownCommonAddresses.insert( {dbusServiceAddress, currentlyParsedCommonApiAddress});
151 DBusAddressTranslator& DBusAddressTranslator::getInstance() {
152 static DBusAddressTranslator* dbusNameService_;
153 if(!dbusNameService_) {
154 dbusNameService_ = new DBusAddressTranslator();
155 dbusNameService_->init();
157 return *dbusNameService_;
161 void DBusAddressTranslator::searchForDBusAddress(const std::string& commonApiAddress,
162 std::string& interfaceName,
163 std::string& connectionName,
164 std::string& objectPath) {
166 const auto& foundAddressMapping = knownDBusAddresses.find(commonApiAddress);
168 if(foundAddressMapping != knownDBusAddresses.end()) {
169 connectionName = std::get<0>(foundAddressMapping->second);
170 objectPath = std::get<1>(foundAddressMapping->second);
171 interfaceName = std::get<2>(foundAddressMapping->second);
173 findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
174 knownDBusAddresses.insert( {commonApiAddress, std::make_tuple(connectionName, objectPath, interfaceName) } );
178 void DBusAddressTranslator::searchForCommonAddress(const std::string& interfaceName,
179 const std::string& connectionName,
180 const std::string& objectPath,
181 std::string& commonApiAddress) {
183 DBusServiceAddress dbusAddress(connectionName, objectPath, interfaceName);
185 const auto& foundAddressMapping = knownCommonAddresses.find(dbusAddress);
186 if (foundAddressMapping != knownCommonAddresses.end()) {
187 commonApiAddress = foundAddressMapping->second;
189 findFallbackCommonAddress(commonApiAddress, interfaceName, connectionName, objectPath);
190 knownCommonAddresses.insert( {std::move(dbusAddress), commonApiAddress} );
195 void DBusAddressTranslator::findFallbackDBusAddress(const std::string& commonApiAddress,
196 std::string& interfaceName,
197 std::string& connectionName,
198 std::string& objectPath) const {
199 std::vector<std::string> parts = split(commonApiAddress, ':');
200 interfaceName = parts[1];
201 connectionName = parts[2];
202 objectPath = '/' + parts[2];
203 std::replace(objectPath.begin(), objectPath.end(), '.', '/');
206 void DBusAddressTranslator::findFallbackCommonAddress(std::string& commonApiAddress,
207 const std::string& interfaceName,
208 const std::string& connectionName,
209 const std::string& objectPath) const {
210 commonApiAddress = "local:" + interfaceName + ":" + connectionName;
215 }// namespace CommonAPI