2 * Copyright (C) 2011, BMW AG
4 * GeniviAudioMananger AudioManagerDaemon
8 * \date 20-Oct-2011 3:42:04 PM
9 * \author Christian Mueller (christian.ei.mueller@bmw.de)
12 * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
13 * Copyright (C) 2011, BMW AG Christian Mueller Christian.ei.mueller@bmw.de
15 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
16 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License, version 2.1, for more details.
17 * You should have received a copy of the GNU Lesser General Public License, version 2.1, along with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
18 * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may also be applicable to programs even in cases in which the program is not a library in the technical sense.
19 * Linking AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. You may license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to license your linked modules under the GNU Lesser General Public License, version 2.1, you may use the program under the following exception.
20 * As a special exception, the copyright holders of AudioManager give you permission to combine AudioManager with software programs or libraries that are released under any license unless such a combination is not permitted by the license of such a software program or library. You may copy and distribute such a system following the terms of the GNU Lesser General Public License, version 2.1, including this special exception, for AudioManager and the licenses of the other code concerned.
21 * Note that people who make modified versions of AudioManager are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, version 2.1, gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
26 * Please make sure to have read the documentation on genivi.org!
29 //todo: create systemd compatibility
30 //todo: all communication like all plugins loaded etc...
31 //todo: seperate documentation of test from normal project
32 //todo: check the startup sequence. Dbus shall be activated last...
33 //todo: there is a bug in the visible flags of sinks and sources. fix it.
34 //todo: make sure all configurations are tested
35 //todo: clean up startup sequences controller, command and routing interfaces----
37 #include <SocketHandler.h>
38 #ifdef WITH_DBUS_WRAPPER
39 #include <dbus/DBusWrapper.h>
41 #include "DatabaseHandler.h"
42 #include "ControlSender.h"
43 #include "CommandSender.h"
44 #include "RoutingSender.h"
45 #include "RoutingReceiver.h"
46 #include "CommandReceiver.h"
47 #include "ControlReceiver.h"
48 #include "DatabaseObserver.h"
49 #include "TelnetServer.h"
51 #include "DLTWrapper.h"
52 #include <sys/resource.h>
63 DLT_DECLARE_CONTEXT(AudioManager)
67 const char* USAGE_DESCRIPTION = "Usage:\tAudioManagerDaemon [options]\n"
69 "\t-h: print this message\t\n"
70 "\t-i: info about current settings \t\n"
71 "\t-v: print version\t\n"
72 "\t-d: daemonize AudioManager \t\n"
73 "\t-p<path> path for sqlite database (default is in memory)\t\n"
74 "\t-t<port> port for telnetconnection\t\n"
75 "\t-m<max> number of max telnetconnections\t\n"
76 "\t-c<Name> use controllerPlugin <Name> (full path with .so ending)\t\n"
77 "\t-l<Name> replace command plugin directory with <Name> (full path)\t\n"
78 "\t-r<Name> replace routing plugin directory with <Name> (full path)\t\n"
79 "\t-L<Name> add command plugin directory with <Name> (full path)\t\n"
80 "\t-R<Name> add routing plugin directory with <Name> (full path)\t\n";
82 std::string controllerPlugin = std::string(CONTROLLER_PLUGIN);
83 std::vector<std::string> listCommandPluginDirs;
84 std::vector<std::string> listRoutingPluginDirs;
85 std::string databasePath = std::string(":memory:");
86 unsigned int telnetport = DEFAULT_TELNETPORT;
87 unsigned int maxConnections = MAX_TELNETCONNECTIONS;
93 std::string dir = "/";
96 if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
98 logError("can't get file limit ");
102 if ((pid = fork()) < 0)
104 logError("cannot fork!");
113 if (!dir.empty() && chdir(dir.c_str()) < 0)
115 logError("couldn't chdir to the new directory");
118 if (rl.rlim_max == RLIM_INFINITY)
123 for (unsigned int i = 0; i < rl.rlim_max; i++)
128 fd0 = open("/dev/null", O_RDONLY);
129 fd1 = open("/dev/null", O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
130 fd2 = open("/dev/null", O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
132 if (fd0 != STDIN_FILENO || fd1 != STDOUT_FILENO || fd2 != STDERR_FILENO)
134 logError("new standard file descriptors were not opened");
138 void parseCommandLine(int argc, char **argv)
140 while (optind < argc)
142 int option = getopt(argc, argv, "h::v::c::l::r::L::R::d::t::m::i::p::");
147 printf("Current settings:\n");
148 printf("\tAudioManagerDaemon Version:\t\t%s\n", DAEMONVERSION);
149 printf("\tTelnet portNumber:\t\t\t%i\n", telnetport);
150 printf("\tTelnet maxConnections:\t\t\t%i\n", maxConnections);
151 printf("\tSqlite Database path:\t\t\t%s\n", databasePath.c_str());
152 printf("\tControllerPlugin: \t\t\t%s\n", controllerPlugin.c_str());
153 printf("\tDirectory of CommandPlugins: \t\t%s\n", listCommandPluginDirs.front().c_str());
154 printf("\tDirectory of RoutingPlugins: \t\t%s\n", listRoutingPluginDirs.front().c_str());
158 assert(atoi(optarg)!=0);
159 telnetport = atoi(optarg);
162 assert(atoi(optarg)!=0);
163 maxConnections = atoi(optarg);
166 assert(!controllerPlugin.empty());
167 databasePath = std::string(optarg);
173 listCommandPluginDirs.clear();
174 listCommandPluginDirs.push_back(std::string(optarg));
177 listRoutingPluginDirs.clear();
178 listRoutingPluginDirs.push_back(std::string(optarg));
181 listCommandPluginDirs.push_back(std::string(optarg));
184 listRoutingPluginDirs.push_back(std::string(optarg));
187 controllerPlugin = std::string(optarg);
188 assert(!controllerPlugin.empty());
189 assert(controllerPlugin.find(".so")!=std::string::npos);
192 printf("AudioManagerDaemon Version: %s\n", DAEMONVERSION);
197 printf("AudioManagerDaemon Version: %s\n", DAEMONVERSION);
198 puts(USAGE_DESCRIPTION);
204 static void signalHandler(int sig, siginfo_t *siginfo, void *context)
209 logError("signal handler was called, exit now...");
211 //todo: maually fire the mainloop
212 //todo: ifdef no sockethandler
216 int main(int argc, char *argv[])
218 DLTWrapper::instance()->registerApp("AudioManagerDeamon", "AudioManagerDeamon");
219 DLTWrapper::instance()->registerContext(AudioManager,"Main", "Main Context");
220 logInfo("The Audiomanager is started");
221 log(&AudioManager,DLT_LOG_ERROR,"The version of the Audiomanager",DAEMONVERSION);
223 listCommandPluginDirs.push_back(std::string(DEFAULT_PLUGIN_COMMAND_DIR));
224 listRoutingPluginDirs.push_back(std::string(DEFAULT_PLUGIN_ROUTING_DIR));
226 //parse the commandline options
227 parseCommandLine(argc, (char**) argv);
229 //now the signal handler:
230 struct sigaction signalAction;
231 memset(&signalAction, '\0', sizeof(signalAction));
232 signalAction.sa_sigaction = &signalHandler;
233 signalAction.sa_flags = SA_SIGINFO;
234 sigaction(SIGINT, &signalAction, NULL);
235 sigaction(SIGQUIT, &signalAction, NULL);
236 sigaction(SIGTERM, &signalAction, NULL);
237 sigaction(SIGHUP, &signalAction, NULL);
238 sigaction(SIGQUIT, &signalAction, NULL);
240 struct sigaction signalChildAction;
241 memset(&signalChildAction, '\0', sizeof(signalChildAction));
242 signalChildAction.sa_flags = SA_NOCLDWAIT;
243 sigaction(SIGCHLD, &signalChildAction, NULL);
245 //Instantiate all classes. Keep in same order !
246 #ifdef WITH_SOCKETHANDLER_LOOP
247 SocketHandler iSocketHandler;
250 #ifdef WITH_DBUS_WRAPPER
251 #ifdef WITH_SOCKETHANDLER_LOOP
252 DBusWrapper iDBusWrapper(&iSocketHandler);
253 #else /*WITH_SOCKETHANDLER_LOOP*/
254 DBusWrapper iDBusWrapper;
255 #endif /*WITH_SOCKETHANDLER_LOOP*/
256 #endif /*WITH_DBUS_WRAPPER */
258 DatabaseHandler iDatabaseHandler(databasePath);
259 RoutingSender iRoutingSender(listRoutingPluginDirs);
260 CommandSender iCommandSender(listCommandPluginDirs);
261 ControlSender iControlSender(controllerPlugin);
262 Router iRouter(&iDatabaseHandler, &iControlSender);
264 #ifdef WITH_DBUS_WRAPPER
265 #ifdef WITH_SOCKETHANDLER_LOOP
266 CommandReceiver iCommandReceiver(&iDatabaseHandler, &iControlSender, &iSocketHandler, &iDBusWrapper);
267 RoutingReceiver iRoutingReceiver(&iDatabaseHandler, &iRoutingSender, &iControlSender, &iSocketHandler, &iDBusWrapper);
268 ControlReceiver iControlReceiver(&iDatabaseHandler, &iRoutingSender, &iCommandSender, &iSocketHandler, &iRouter);
270 TelnetServer iTelnetServer(&iSocketHandler,&iCommandSender,&iCommandReceiver,&iRoutingSender,&iRoutingReceiver,&iControlSender,&iControlReceiver,&iDatabaseHandler,telnetport,maxConnections);
272 #else /*WITH_SOCKETHANDLER_LOOP */
273 CommandReceiver iCommandReceiver(&iDatabaseHandler,&iControlSender,&iDBusWrapper);
274 RoutingReceiver iRoutingReceiver(&iDatabaseHandler,&iRoutingSender,&iControlSender,&iDBusWrapper);
275 ControlReceiver iControlReceiver(&iDatabaseHandler,&iRoutingSender,&iCommandSender, &iRouter);
276 #endif /*WITH_SOCKETHANDLER_LOOP*/
277 #else /*WITH_DBUS_WRAPPER*/
278 CommandReceiver iCommandReceiver(&iDatabaseHandler,&iControlSender,&iSocketHandler);
279 RoutingReceiver iRoutingReceiver(&iDatabaseHandler,&iRoutingSender,&iControlSender,&iSocketHandler);
280 ControlReceiver iControlReceiver(&iDatabaseHandler,&iRoutingSender,&iCommandSender,&iSocketHandler, &iRouter);
282 TelnetServer iTelnetServer(&iSocketHandler,telnetport,maxConnections);
284 #endif /*WITH_DBUS_WRAPPER*/
287 DatabaseObserver iObserver(&iCommandSender, &iRoutingSender,&iTelnetServer);
289 DatabaseObserver iObserver(&iCommandSender, &iRoutingSender);
292 //since the plugins have been loaded by the *Senders before, we can tell the Controller this:
293 iControlSender.hookAllPluginsLoaded();
295 //the controller should startup the interfaces - this is just for testing
296 iCommandSender.startupInterface(&iCommandReceiver);
297 iRoutingSender.startupRoutingInterface(&iRoutingReceiver);
298 iRoutingSender.routingInterfacesReady();
300 #ifdef WITH_SOCKETHANDLER_LOOP
301 iSocketHandler.start_listenting();
302 #endif /*WITH_SOCKETHANDLER_LOOP*/
304 #ifdef WITH_DBUS_WRAPPER
305 #ifdef WITH_SIMPLEDBUS_LOOP
306 iDBusWrapper.dbusMainLoop();
307 #endif/*WITH_SIMPLEDBUS_LOOP*/
308 #endif /*WITH_DBUS_WRAPPER*/