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