#include <string.h>
#include <iostream>
#include <fstream>
+#include <cassert>
namespace CommonAPI {
namespace DBus {
+enum class TypeEnum {
+ DBUS_CONNECTION, DBUS_OBJECT, DBUS_INTERFACE, DBUS_PREDEFINED
+};
+static const std::unordered_map<std::string, TypeEnum> allowedValueTypes = {
+ {"dbus_connection", TypeEnum::DBUS_CONNECTION},
+ {"dbus_object", TypeEnum::DBUS_OBJECT},
+ {"dbus_interface", TypeEnum::DBUS_INTERFACE},
+ {"dbus_predefined", TypeEnum::DBUS_PREDEFINED}
+};
-inline bool readSection(std::ifstream& addressConfigFile, std::string& section) {
- std::string readLine;
- getline(addressConfigFile, readLine);
+DBusAddressTranslator::DBusAddressTranslator() {}
- const size_t sectionLength = readLine.length();
- if(readLine[0] != '[' || readLine[sectionLength - 1] != ']') {
- return false;
- }
-
- section = readLine.substr(1, sectionLength - 2);
+void DBusAddressTranslator::init() {
+ std::string fqnOfConfigFile = getCurrentBinaryFileFQN();
+ std::ifstream addressConfigFile;
- return true;
+ if (fqnOfConfigFile != "") {
+ fqnOfConfigFile += DBUS_CONFIG_SUFFIX;
+
+ addressConfigFile.open(fqnOfConfigFile.c_str());
+
+ if (addressConfigFile.is_open()) {
+ readConfigFile(addressConfigFile);
+ addressConfigFile.close();
+ }
+
+ addressConfigFile.clear();
+ std::vector<std::string> splittedConfigFQN = split(fqnOfConfigFile, '/');
+ std::string globalConfigFQN = DBUS_GLOBAL_CONFIG_ROOT + splittedConfigFQN.at(splittedConfigFQN.size() - 1);
+ addressConfigFile.open(globalConfigFQN);
+ if (addressConfigFile.is_open()) {
+ readConfigFile(addressConfigFile);
+ addressConfigFile.close();
+ }
+ addressConfigFile.clear();
+ }
-// [domain:service:instance]
-// dbus_connection=connection.name
-// dbus_object=/path/to/object
-// dbus_interface=service.name
+ addressConfigFile.open(DBUS_GLOBAL_CONFIG_FQN);
+ if(addressConfigFile.is_open()) {
+ readConfigFile(addressConfigFile);
+ addressConfigFile.close();
+ }
}
-std::unordered_set<std::string> allowedValueTypes = {"dbus_connection", "dbus_object", "dbus_interface"};
-
-
-inline bool readValue(std::ifstream& addressConfigFile, std::string& paramName, std::string& paramValue) {
- getline(addressConfigFile, paramName, '=');
- if(allowedValueTypes.find(paramName) == allowedValueTypes.end()) {
- return false;
+inline void readValue(std::string& readLine, CommonApiServiceDetails& serviceDetails) {
+ std::stringstream readStream(readLine);
+
+ std::string paramName;
+ std::string paramValue;
+
+ getline(readStream, paramName, '=');
+
+ auto typeEntry = allowedValueTypes.find(paramName);
+ if(typeEntry != allowedValueTypes.end()) {
+ getline(readStream, paramValue);
+ switch(typeEntry->second) {
+ case TypeEnum::DBUS_CONNECTION:
+ std::get<0>(std::get<0>(serviceDetails)) = paramValue;
+ break;
+ case TypeEnum::DBUS_OBJECT:
+ std::get<1>(std::get<0>(serviceDetails)) = paramValue;
+ break;
+ case TypeEnum::DBUS_INTERFACE:
+ std::get<2>(std::get<0>(serviceDetails)) = paramValue;
+ break;
+ case TypeEnum::DBUS_PREDEFINED:
+ std::get<1>(serviceDetails) = paramValue == "true" ? true : false;
+ break;
+ }
}
- getline(addressConfigFile, paramValue);
-
- //TODO: Check whether its a valid bus name
-
- return true;
}
+inline void reset(DBusServiceAddress& dbusServiceAddress) {
+ std::get<0>(dbusServiceAddress) = "";
+ std::get<1>(dbusServiceAddress) = "";
+ std::get<2>(dbusServiceAddress) = "";
+}
+inline void reset(CommonApiServiceDetails& serviceDetails) {
+ reset(std::get<0>(serviceDetails));
+ std::get<1>(serviceDetails) = false;
+}
+void DBusAddressTranslator::readConfigFile(std::ifstream& addressConfigFile) {
+ std::string currentlyParsedCommonApiAddress;
+ CommonApiServiceDetails serviceDetails;
+ reset(serviceDetails);
-DBusAddressTranslator::DBusAddressTranslator()
-{
- std::string fqnOfConfigFile = getBinaryFileName();
- fqnOfConfigFile += "_dbus.ini";
-
- std::ifstream addressConfigFile;
-
- addressConfigFile.open(fqnOfConfigFile.c_str());
+ bool newAddressFound = false;
while (addressConfigFile.good()) {
- std::string section;
+ std::string readLine;
+ getline(addressConfigFile, readLine);
+ const size_t readLineLength = readLine.length();
+
+ if (readLine[0] == '[' && readLine[readLineLength - 1] == ']') {
+ if (newAddressFound) {
+ fillUndefinedValues(serviceDetails, currentlyParsedCommonApiAddress);
+ commonApiAddressDetails.insert( {currentlyParsedCommonApiAddress, serviceDetails});
+ dbusToCommonApiAddress.insert( {std::get<0>(serviceDetails), currentlyParsedCommonApiAddress});
+ }
+ reset(serviceDetails);
+ std::string newAddress = readLine.substr(1, readLineLength - 2);
+ if (isValidCommonApiAddress(newAddress)) {
+ currentlyParsedCommonApiAddress = std::move(newAddress);
+ newAddressFound = commonApiAddressDetails.find(currentlyParsedCommonApiAddress) == commonApiAddressDetails.end();
+ }
+
+ } else if (newAddressFound) {
+ readValue(readLine, serviceDetails);
+ }
+ }
+ if(newAddressFound) {
+ fillUndefinedValues(serviceDetails, currentlyParsedCommonApiAddress);
+ commonApiAddressDetails.insert( {currentlyParsedCommonApiAddress, serviceDetails});
+ dbusToCommonApiAddress.insert( {std::get<0>(serviceDetails), currentlyParsedCommonApiAddress});
+ }
+}
- readSection(addressConfigFile, section);
- std::cout << "---" << section<< "---" << std::endl;
- std::string paramName;
- std::string paramValue;
+void DBusAddressTranslator::fillUndefinedValues(CommonApiServiceDetails& serviceDetails, const std::string& commonApiAddress) const {
+ std::string connectionName;
+ std::string objectPath;
+ std::string interfaceName;
- readValue(addressConfigFile, paramName, paramValue);
- std::cout << paramName << "::" << paramValue << std::endl;
- readValue(addressConfigFile, paramName, paramValue);
- std::cout << paramName << "::" << paramValue << std::endl;
- readValue(addressConfigFile, paramName, paramValue);
- std::cout << paramName << "::" << paramValue << std::endl;
- }
+ findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
- addressConfigFile.close();
+ std::get<0>(std::get<0>(serviceDetails)) = std::get<0>(std::get<0>(serviceDetails)) == "" ? connectionName : std::get<0>(std::get<0>(serviceDetails));
+ std::get<1>(std::get<0>(serviceDetails)) = std::get<1>(std::get<0>(serviceDetails)) == "" ? objectPath : std::get<1>(std::get<0>(serviceDetails));
+ std::get<2>(std::get<0>(serviceDetails)) = std::get<2>(std::get<0>(serviceDetails)) == "" ? interfaceName : std::get<2>(std::get<0>(serviceDetails));
}
static DBusAddressTranslator* dbusNameService_;
if(!dbusNameService_) {
dbusNameService_ = new DBusAddressTranslator();
+ dbusNameService_->init();
}
return *dbusNameService_;
}
-void DBusAddressTranslator::searchForDBusInstanceId(const std::string& instanceId,
- std::string& connectionName,
- std::string& objectPath) const {
- if(!true) {
- findFallbackDBusInstanceId(instanceId, connectionName, objectPath);
+void DBusAddressTranslator::searchForDBusAddress(const std::string& commonApiAddress,
+ std::string& interfaceName,
+ std::string& connectionName,
+ std::string& objectPath) {
+
+ const auto& foundAddressMapping = commonApiAddressDetails.find(commonApiAddress);
+
+ if(foundAddressMapping != commonApiAddressDetails.end()) {
+ connectionName = std::get<0>(std::get<0>(foundAddressMapping->second));
+ objectPath = std::get<1>(std::get<0>(foundAddressMapping->second));
+ interfaceName = std::get<2>(std::get<0>(foundAddressMapping->second));
+ } else {
+ findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
+ commonApiAddressDetails.insert( {commonApiAddress, std::make_tuple(std::make_tuple(connectionName, objectPath, interfaceName), false) } );
}
}
-void DBusAddressTranslator::searchForCommonInstanceId(std::string& instanceId,
- const std::string& connectionName,
- const std::string& objectPath) const {
- if(!true) {
- findFallbackCommonInstanceId(instanceId, connectionName, objectPath);
+void DBusAddressTranslator::searchForCommonAddress(const std::string& interfaceName,
+ const std::string& connectionName,
+ const std::string& objectPath,
+ std::string& commonApiAddress) {
+
+ DBusServiceAddress dbusAddress(connectionName, objectPath, interfaceName);
+
+ const auto& foundAddressMapping = dbusToCommonApiAddress.find(dbusAddress);
+ if (foundAddressMapping != dbusToCommonApiAddress.end()) {
+ commonApiAddress = foundAddressMapping->second;
+ } else {
+ findFallbackCommonAddress(commonApiAddress, interfaceName, connectionName, objectPath);
+ dbusToCommonApiAddress.insert( {std::move(dbusAddress), commonApiAddress} );
}
}
-
-std::string DBusAddressTranslator::findCommonAPIAddressForDBusAddress(const std::string& conName,
- const std::string& objName,
- const std::string& intName) const {
- return "local:" + intName + ":" + conName;
+void DBusAddressTranslator::getPredefinedInstances(const std::string& connectionName,
+ std::vector<DBusServiceAddress>& instances) {
+ instances.clear();
+ auto dbusAddress = commonApiAddressDetails.begin();
+ while (dbusAddress != commonApiAddressDetails.end()) {
+ CommonApiServiceDetails serviceDetails = dbusAddress->second;
+ if (connectionName == std::get<0>(std::get<0>(serviceDetails))
+ && true == std::get<1>(serviceDetails)) {
+ instances.push_back(std::get<0>(serviceDetails));
+ }
+ dbusAddress++;
+ }
}
-void DBusAddressTranslator::findFallbackDBusInstanceId(const std::string& instanceId,
- std::string& connectionName,
- std::string& objectPath) const {
- connectionName = instanceId;
- objectPath = '/' + instanceId;
+void DBusAddressTranslator::findFallbackDBusAddress(const std::string& commonApiAddress,
+ std::string& interfaceName,
+ std::string& connectionName,
+ std::string& objectPath) const {
+ std::vector<std::string> parts = split(commonApiAddress, ':');
+ interfaceName = parts[1];
+ connectionName = parts[2];
+ objectPath = '/' + parts[2];
std::replace(objectPath.begin(), objectPath.end(), '.', '/');
}
-void DBusAddressTranslator::findFallbackCommonInstanceId(std::string& instanceId,
- const std::string& connectionName,
- const std::string& objectPath) const {
- instanceId = connectionName;
+void DBusAddressTranslator::findFallbackCommonAddress(std::string& commonApiAddress,
+ const std::string& interfaceName,
+ const std::string& connectionName,
+ const std::string& objectPath) const {
+ commonApiAddress = "local:" + interfaceName + ":" + connectionName;
}