* wrapping DLT calls in a new Class because of performance, codesize and lazyness...
[profile/ivi/audiomanager.git] / AudioManagerDaemon / src / CommandSender.cpp
1 /**
2  * Copyright (C) 2011, BMW AG
3  *
4  * GeniviAudioMananger AudioManagerDaemon
5  *
6  * \file CommandSender.cpp
7  *
8  * \date 20-Oct-2011 3:42:04 PM
9  * \author Christian Mueller (christian.ei.mueller@bmw.de)
10  *
11  * \section License
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
14  *
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.
22  *
23  */
24
25 #include "CommandSender.h"
26 #include "command/CommandReceiveInterface.h"
27 #include <dirent.h>
28 #include "PluginTemplate.h"
29 #include "DLTWrapper.h"
30 using namespace am;
31
32 #define REQUIRED_INTERFACE_VERSION 1
33
34 //!< macro to call all interfaces
35 #define CALL_ALL_INTERFACES(...)                                                                                                                 \
36                 std::vector<CommandSendInterface*>::iterator iter = mListInterfaces.begin();     \
37                 std::vector<CommandSendInterface*>::iterator iterEnd = mListInterfaces.end();    \
38                 for (; iter<iterEnd;++iter)                                                                                                              \
39                 {                                                                                                                                                                \
40                         (*iter)->__VA_ARGS__;                                                                                                            \
41                 }
42
43 CommandSender::CommandSender(const std::vector<std::string>& listOfPluginDirectories) :
44         mListInterfaces(), //
45         mListLibraryHandles()
46 {
47     std::vector<std::string> sharedLibraryNameList;
48     std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
49     std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
50
51     // search communicator plugins in configured directories
52     for (; dirIter < dirIterEnd; ++dirIter)
53     {
54         const char* directoryName = dirIter->c_str();
55         logInfo("Searching for CommandPlugins in",directoryName);
56         DIR *directory = opendir(directoryName);
57
58         if (!directory)
59         {
60             logInfo("Error opening directory ",directoryName);
61             continue;
62         }
63
64         // iterate content of directory
65         struct dirent *itemInDirectory = 0;
66         while ((itemInDirectory = readdir(directory)))
67         {
68             unsigned char entryType = itemInDirectory->d_type;
69             std::string entryName = itemInDirectory->d_name;
70
71             bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
72             bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
73
74             if (regularFile && sharedLibExtension)
75             {
76                 std::string name(directoryName);
77                 sharedLibraryNameList.push_back(name + "/" + entryName);
78             }
79         }
80         closedir(directory);
81     }
82
83     // iterate all communicator plugins and start them
84     std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
85     std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
86
87     for (; iter < iterEnd; ++iter)
88     {
89         logInfo("Loading CommandSender plugin",*iter);
90         CommandSendInterface* (*createFunc)();
91         void* tempLibHandle = NULL;
92         createFunc = getCreateFunction<CommandSendInterface*()>(*iter, tempLibHandle);
93
94         if (!createFunc)
95         {
96             logInfo("Entry point of CommandPlugin not found",*iter);
97             continue;
98         }
99
100         CommandSendInterface* commander = createFunc();
101
102         if (!commander)
103         {
104             logInfo("CommandPlugin initialization failed. Entry Function not callable");
105             continue;
106         }
107
108         //check libversion
109         if (commander->getInterfaceVersion() < REQUIRED_INTERFACE_VERSION)
110         {
111             logInfo("RoutingPlugin initialization failed. Version of Interface to old");
112             continue;
113         }
114
115         mListInterfaces.push_back(commander);
116         mListLibraryHandles.push_back(tempLibHandle);
117     }
118 }
119
120 CommandSender::~CommandSender()
121 {
122     unloadLibraries();
123 }
124
125 am_Error_e CommandSender::stopInterface()
126 {
127     am_Error_e returnError = E_OK;
128
129     std::vector<CommandSendInterface*>::iterator iter = mListInterfaces.begin();
130     std::vector<CommandSendInterface*>::iterator iterEnd = mListInterfaces.end();
131     for (; iter < iterEnd; ++iter)
132     {
133         am_Error_e error = (*iter)->stopInterface();
134         if (error != E_OK)
135         {
136             returnError = error;
137         }
138     }
139     return returnError;
140 }
141
142 am_Error_e CommandSender::startupInterface(CommandReceiveInterface *commandreceiveinterface)
143 {
144     am_Error_e returnError = E_OK;
145
146     std::vector<CommandSendInterface*>::iterator iter = mListInterfaces.begin();
147     std::vector<CommandSendInterface*>::iterator iterEnd = mListInterfaces.end();
148     for (; iter < iterEnd; ++iter)
149     {
150         am_Error_e error = (*iter)->startupInterface(commandreceiveinterface);
151         if (error != E_OK)
152         {
153             returnError = error;
154         }
155     }
156     return returnError;
157 }
158
159 void CommandSender::cbCommunicationReady()
160 {
161     CALL_ALL_INTERFACES(cbCommunicationReady())
162 }
163
164 void CommandSender::cbCommunicationRundown()
165 {
166     CALL_ALL_INTERFACES(cbCommunicationRundown())
167 }
168
169 void CommandSender::cbNumberOfMainConnectionsChanged()
170 {
171     CALL_ALL_INTERFACES(cbNumberOfMainConnectionsChanged())
172 }
173
174 void CommandSender::cbNumberOfSinksChanged()
175 {
176     CALL_ALL_INTERFACES(cbNumberOfSinksChanged())
177 }
178
179 void CommandSender::cbNumberOfSourcesChanged()
180 {
181     CALL_ALL_INTERFACES(cbNumberOfSourcesChanged())
182 }
183
184 void CommandSender::cbNumberOfSinkClassesChanged()
185 {
186     CALL_ALL_INTERFACES(cbNumberOfSinkClassesChanged())
187 }
188
189 void CommandSender::cbNumberOfSourceClassesChanged()
190 {
191     CALL_ALL_INTERFACES(cbNumberOfSourceClassesChanged())
192 }
193
194 void CommandSender::cbMainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState)
195 {
196     CALL_ALL_INTERFACES(cbMainConnectionStateChanged(connectionID,connectionState))
197 }
198
199 void CommandSender::cbMainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s SoundProperty)
200 {
201     CALL_ALL_INTERFACES(cbMainSinkSoundPropertyChanged(sinkID,SoundProperty))
202 }
203
204 void CommandSender::cbMainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s & SoundProperty)
205 {
206     CALL_ALL_INTERFACES(cbMainSourceSoundPropertyChanged(sourceID,SoundProperty))
207 }
208
209 void CommandSender::cbSinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s & availability)
210 {
211     CALL_ALL_INTERFACES(cbSinkAvailabilityChanged(sinkID,availability))
212 }
213
214 void CommandSender::cbSourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s & availability)
215 {
216     CALL_ALL_INTERFACES(cbSourceAvailabilityChanged(sourceID,availability))
217 }
218
219 void CommandSender::cbVolumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume)
220 {
221     CALL_ALL_INTERFACES(cbVolumeChanged(sinkID,volume))
222 }
223
224 void CommandSender::cbSinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState)
225 {
226     CALL_ALL_INTERFACES(cbSinkMuteStateChanged(sinkID,muteState))
227 }
228
229 void CommandSender::cbSystemPropertyChanged(const am_SystemProperty_s & SystemProperty)
230 {
231     CALL_ALL_INTERFACES(cbSystemPropertyChanged(SystemProperty))
232 }
233
234 void CommandSender::cbTimingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time)
235 {
236     CALL_ALL_INTERFACES(cbTimingInformationChanged(mainConnection,time))
237 }
238
239 void CommandSender::unloadLibraries(void)
240 {
241     std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
242     for (; iterator < mListLibraryHandles.end(); ++iterator)
243     {
244         dlclose(*iterator);
245     }
246     mListLibraryHandles.clear();
247 }
248
249 uint16_t CommandSender::getInterfaceVersion() const
250 {
251     return CommandSendVersion;
252 }
253