diff options
-rw-r--r-- | RELEASE.md | 2 | ||||
-rw-r--r-- | ambd/pluginloader.cpp | 439 | ||||
-rw-r--r-- | tools/ambctl.py | 12 |
3 files changed, 229 insertions, 224 deletions
@@ -4,6 +4,8 @@ Version: 0.14 ## New features: - [DBus] some classes for exporting custom interfaces moved to plugins-common - [Bluemonkey plugin] support for creating custom dbus interfaces: bluemonkey.exportInterface() +- [Bluemonkey plugin] dbus module supports creating dbus interfaces to system or session services and + creating/exporting dbus objects - [ambctl] support for enabling disabling plugins - [ambd] support plugins.d - now plugin segments can be stuck in there and amb will try to load all plugins that are enabled. See the example segments: /etc/ambd/plugins.d/dbus, examplesink, examplesource diff --git a/ambd/pluginloader.cpp b/ambd/pluginloader.cpp index 6727413f..a2ffedd0 100644 --- a/ambd/pluginloader.cpp +++ b/ambd/pluginloader.cpp @@ -31,257 +31,260 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA std::string get_file_contents(const char *filename) { - std::ifstream in(filename, std::ios::in); - if(in.fail()) - { - DebugOut(DebugOut::Error) << "Failed to open file '" << filename << "':' " << strerror(errno) << endl; - return ""; - } - - std::string output; - std::string line; - while(in.good()) - { - getline(in,line); - output.append(line); - } - return output; + std::ifstream in(filename, std::ios::in); + if(in.fail()) + { + DebugOut(DebugOut::Error) << "Failed to open file '" << filename << "':' " << strerror(errno) << endl; + return ""; + } + + std::string output; + std::string line; + while(in.good()) + { + getline(in,line); + output.append(line); + } + return output; } PluginLoader::PluginLoader(string configFile, int argc, char** argv): f_create(NULL), routingEngine(nullptr), mMainLoop(nullptr) { - DebugOut()<<"Loading config file: "<<configFile<<endl; - std::string configBuffer = get_file_contents(configFile.c_str()); - - std::string picojsonerr = ""; - picojson::value v; - picojson::parse(v, configBuffer.begin(), configBuffer.end(), &picojsonerr); - - if(!picojsonerr.empty()) - { - DebugOut(DebugOut::Error) << "Failed to parse main config! " << picojsonerr << endl; - throw std::runtime_error("Error parsing config"); - } - - if(v.contains("routingEngine")) - { - string restr = v.get("routingEngine").to_str(); - - routingEngine = loadRoutingEngine(restr); - - if(!routingEngine) - { - DebugOut(DebugOut::Warning)<<"Failed to load routing engine plugin: "<<restr<<endl; - } - } - - if(!routingEngine) - { - /// there is no mainloop entry, use default glib - DebugOut()<<"No routing engine specified in config. Using built-in 'core' routing engine by default."<<endl; - - /// core wants some specific configuration settings: - std::map<std::string,std::string> settings; - - - for (auto q : {"lowPriorityQueueSize", "normalPriorityQueueSize", "highPriorityQueueSize"}) - { - if (v.contains(q)) - { - string restr = v.get(q).to_str(); - settings[q] = restr; - } - } - - routingEngine = new Core(settings); - } - - - if(v.contains("plugins")) - { - std::string pluginsPath = v.get("plugins").to_str(); - scanPluginDir(pluginsPath); - } - - if(v.contains("mainloop")) - { - /// there is a mainloop entry. Load the plugin: - - string mainloopstr = v.get("mainloop").to_str(); - - mMainLoop = loadMainLoop(mainloopstr, argc, argv); - - if(!mMainLoop) - { - DebugOut(DebugOut::Warning)<<"Failed to load main loop plugin."<<endl; - } - } - else if(!mMainLoop) - { - /// there is no mainloop entry, use default glib - DebugOut()<<"No mainloop specified in config. Using glib by default."<<endl; - mMainLoop = new GlibMainLoop(argc, argv); - } - - - for (auto q : {"sources", "sinks"}) - { - if(v.contains("sources")) - { - picojson::array list = v.get(q).get<picojson::array>(); - if (!list.size()) - { - DebugOut() << "Error getting list for " << q << endl; - } - - for(auto src : list) - { - std::map<std::string, std::string> configurationMap; - for( auto obj : src.get<picojson::object>()) - { - string valstr = obj.second.to_str(); - string key = obj.first; - - DebugOut() << "plugin config key: " << key << "value:" << valstr << endl; - - configurationMap[key] = valstr; - } - - string path = configurationMap["path"]; - - if(!loadPlugin(path, configurationMap)) - DebugOut(DebugOut::Warning) << "Failed to load plugin: " << path <<endl; - } - - } - } - - Core* core = static_cast<Core*>(routingEngine); - if( core != nullptr ) - { - core->inspectSupported(); - } + DebugOut()<<"Loading config file: "<<configFile<<endl; + std::string configBuffer = get_file_contents(configFile.c_str()); + + std::string picojsonerr = ""; + picojson::value v; + picojson::parse(v, configBuffer.begin(), configBuffer.end(), &picojsonerr); + + if(!picojsonerr.empty()) + { + DebugOut(DebugOut::Error) << "Failed to parse main config! " << picojsonerr << endl; + throw std::runtime_error("Error parsing config"); + } + + if(v.contains("routingEngine")) + { + string restr = v.get("routingEngine").to_str(); + + routingEngine = loadRoutingEngine(restr); + + if(!routingEngine) + { + DebugOut(DebugOut::Warning)<<"Failed to load routing engine plugin: "<<restr<<endl; + } + } + + if(!routingEngine) + { + /// there is no mainloop entry, use default glib + DebugOut()<<"No routing engine specified in config. Using built-in 'core' routing engine by default."<<endl; + + /// core wants some specific configuration settings: + std::map<std::string,std::string> settings; + + + for (auto q : {"lowPriorityQueueSize", "normalPriorityQueueSize", "highPriorityQueueSize"}) + { + if (v.contains(q)) + { + string restr = v.get(q).to_str(); + settings[q] = restr; + } + } + + routingEngine = new Core(settings); + } + + + if(v.contains("plugins")) + { + std::string pluginsPath = v.get("plugins").to_str(); + scanPluginDir(pluginsPath); + } + + if(v.contains("mainloop")) + { + /// there is a mainloop entry. Load the plugin: + + string mainloopstr = v.get("mainloop").to_str(); + + mMainLoop = loadMainLoop(mainloopstr, argc, argv); + + if(!mMainLoop) + { + DebugOut(DebugOut::Warning)<<"Failed to load main loop plugin."<<endl; + } + } + else if(!mMainLoop) + { + /// there is no mainloop entry, use default glib + DebugOut()<<"No mainloop specified in config. Using glib by default."<<endl; + mMainLoop = new GlibMainLoop(argc, argv); + } + + + for (auto q : {"sources", "sinks"}) + { + if(v.contains("sources")) + { + picojson::array list = v.get(q).get<picojson::array>(); + if (!list.size()) + { + DebugOut() << "Error getting list for " << q << endl; + } + + for(auto src : list) + { + std::map<std::string, std::string> configurationMap; + for( auto obj : src.get<picojson::object>()) + { + string valstr = obj.second.to_str(); + string key = obj.first; + + DebugOut() << "plugin config key: " << key << "value:" << valstr << endl; + + configurationMap[key] = valstr; + } + + string path = configurationMap["path"]; + + if(!loadPlugin(path, configurationMap)) + DebugOut(DebugOut::Warning) << "Failed to load plugin: " << path <<endl; + } + + } + } + + Core* core = static_cast<Core*>(routingEngine); + if( core != nullptr ) + { + core->inspectSupported(); + } } PluginLoader::~PluginLoader() { - for(auto handle : openHandles) - dlclose(handle); + for(auto handle : openHandles) + dlclose(handle); } IMainLoop *PluginLoader::mainloop() { - return mMainLoop; + return mMainLoop; } std::string PluginLoader::errorString() { - return mErrorString; + return mErrorString; } void PluginLoader::scanPluginDir(const std::string & dir) { - DebugOut() << "Scanning plugin directory: " << dir << endl; + DebugOut() << "Scanning plugin directory: " << dir << endl; - auto pluginsDirectory = amb::make_gobject(g_file_new_for_path(dir.c_str())); + auto pluginsDirectory = amb::make_gobject(g_file_new_for_path(dir.c_str())); - GError* enumerateError = nullptr; + GError* enumerateError = nullptr; - auto enumerator = amb::make_gobject(g_file_enumerate_children(pluginsDirectory.get(), G_FILE_ATTRIBUTE_ID_FILE, - G_FILE_QUERY_INFO_NONE, nullptr, - &enumerateError)); - auto enumerateErrorPtr = amb::make_super(enumerateError); + auto enumerator = amb::make_gobject(g_file_enumerate_children(pluginsDirectory.get(), G_FILE_ATTRIBUTE_ID_FILE, + G_FILE_QUERY_INFO_NONE, nullptr, + &enumerateError)); + auto enumerateErrorPtr = amb::make_super(enumerateError); - if(enumerateErrorPtr) - { - DebugOut(DebugOut::Error) << "Scanning plugin directory: " << enumerateErrorPtr->message << endl; - return; - } + if(enumerateErrorPtr) + { + DebugOut(DebugOut::Error) << "Scanning plugin directory: " << enumerateErrorPtr->message << endl; + return; + } - GError* errorGetFile = nullptr; - while(auto pluginConfig = amb::make_gobject(g_file_enumerator_next_file(enumerator.get(), nullptr, &errorGetFile))) - { - std::string name = g_file_info_get_name(pluginConfig.get()); + GError* errorGetFile = nullptr; + while(auto pluginConfig = amb::make_gobject(g_file_enumerator_next_file(enumerator.get(), nullptr, &errorGetFile))) + { + std::string name = g_file_info_get_name(pluginConfig.get()); - DebugOut() << "Found file: " << name << endl; - std::string fullpath = dir + (boost::algorithm::ends_with(dir, "/") ? "":"/") + name; - std::string data = get_file_contents(fullpath.c_str()); + DebugOut() << "Found file: " << name << endl; + std::string fullpath = dir + (boost::algorithm::ends_with(dir, "/") ? "":"/") + name; + std::string data = get_file_contents(fullpath.c_str()); - DebugOut() << "data: " << data << endl; + DebugOut() << "data: " << data << endl; - if(!readPluginConfig(data)) - { - DebugOut(DebugOut::Error) << "Reading contentds of file: " << name << endl; - } - } + if(!readPluginConfig(data)) + { + DebugOut(DebugOut::Error) << "Reading contentds of file: " << name << endl; + } + } - auto errorGetFilePtr = amb::make_super(errorGetFile); + auto errorGetFilePtr = amb::make_super(errorGetFile); - if(errorGetFilePtr) - { - DebugOut(DebugOut::Error) << "enumerating file: " << errorGetFilePtr->message << endl; - return; - } + if(errorGetFilePtr) + { + DebugOut(DebugOut::Error) << "enumerating file: " << errorGetFilePtr->message << endl; + return; + } } bool PluginLoader::readPluginConfig(const string &configData) { - picojson::value v; - std::string err; - - picojson::parse(v, configData.begin(), configData.end(), &err); - - if (!err.empty()) - { - DebugOut(DebugOut::Error) << err << endl; - return false; - } - - std::string pluginName; - if(v.contains("name")) - { - pluginName = v.get("name").to_str(); - } - - std::string pluginPath; - if(v.contains("path")) - { - pluginPath = v.get("path").to_str(); - } - else - { - DebugOut(DebugOut::Error) << "config missing 'path'." << endl; - return false; - } - - bool enabled = false; - if(v.contains("enabled")) - { - enabled = v.get("enabled").get<bool>(); - } - else - { - DebugOut(DebugOut::Error) << "config missing 'enabled'." << endl; - return false; - } - - DebugOut() << "Plugin: " << pluginName << endl; - DebugOut() << "Path: " << pluginPath << endl; - DebugOut() << "Enabled: " << enabled << endl; - - if(enabled) - { - std::map<std::string, std::string> otherConfig; - - picojson::object obj = v.get<picojson::object>(); - for(auto itr : obj) - { - otherConfig[itr.first] = itr.second.to_str(); - } - - loadPlugin(pluginPath, otherConfig); - } - - return true; + picojson::value v; + std::string err; + + picojson::parse(v, configData.begin(), configData.end(), &err); + + if (!err.empty()) + { + DebugOut(DebugOut::Error) << err << endl; + return false; + } + + std::string pluginName; + if(v.contains("name")) + { + pluginName = v.get("name").to_str(); + } + + std::string pluginPath; + if(v.contains("path")) + { + pluginPath = v.get("path").to_str(); + } + else + { + DebugOut(DebugOut::Error) << "config missing 'path'." << endl; + return false; + } + + bool enabled = false; + if(v.contains("enabled")) + { + enabled = v.get("enabled").get<bool>(); + } + else + { + DebugOut(DebugOut::Error) << "config missing 'enabled'." << endl; + return false; + } + + DebugOut() << "Plugin: " << pluginName << endl; + DebugOut() << "Path: " << pluginPath << endl; + DebugOut() << "Enabled: " << enabled << endl; + + if(enabled) + { + std::map<std::string, std::string> otherConfig; + + picojson::object obj = v.get<picojson::object>(); + for(auto itr : obj) + { + if(!itr.second.is<std::string>()) + otherConfig[itr.first] = itr.second.serialize(); + else + otherConfig[itr.first] = itr.second.to_str(); + } + + loadPlugin(pluginPath, otherConfig); + } + + return true; } diff --git a/tools/ambctl.py b/tools/ambctl.py index fed0f592..ef755654 100644 --- a/tools/ambctl.py +++ b/tools/ambctl.py @@ -153,7 +153,7 @@ def processCommand(command, commandArgs, noMain=True): bus = dbus.SystemBus() managerObject = bus.get_object("org.automotive.message.broker", "/"); managerInterface = dbus.Interface(managerObject, "org.automotive.Manager") - return managerInterface + return managerInterface, bus except: print "Error connecting to AMB. is AMB running?" return None @@ -172,9 +172,9 @@ def processCommand(command, commandArgs, noMain=True): if commandArgs[0] == "help": print "ObjectName [ObjectName...]" return 1 - managerInterface = getManager() + managerInterface, bus = getManager() if managerInterface == None: - return 1 + return 0 for objectName in commandArgs: objects = managerInterface.FindObject(objectName) print objectName @@ -192,7 +192,7 @@ def processCommand(command, commandArgs, noMain=True): elif commandArgs[0] == "off": off=True commandArgs=commandArgs[1:] - managerInterface = getManager() + managerInterface, bus = getManager() if managerInterface == None: return 1 for objectName in commandArgs: @@ -232,7 +232,7 @@ def processCommand(command, commandArgs, noMain=True): zone = 0 if len(commandArgs) == 4: zone = int(commandArgs[3]) - managerInterface = getManager() + managerInterface, bus = getManager() if managerInterface == None: return 1 object = managerInterface.FindObjectForZone(objectName, zone) @@ -267,7 +267,7 @@ def processCommand(command, commandArgs, noMain=True): zone = 0 if len(commandArgs) >= 2: zone = int(commandArgs[1]) - managerInterface = getManager() + managerInterface, bus = getManager() if managerInterface == None: return 1 object = managerInterface.FindObjectForZone(objectName, zone); |