* formatting all the source code with eclipse source code style
[profile/ivi/genivi/genivi-audio-manager.git] / AudioManagerDaemon / src / RoutingSender.cpp
1 /**
2  * Copyright (C) 2011, BMW AG
3  *
4  * GeniviAudioMananger AudioManagerDaemon
5  *
6  * \file RoutingSender.h
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 "RoutingSender.h"
26 #include <utility>
27 #include <dirent.h>
28 #include <dlfcn.h>
29 #include <dlt/dlt.h>
30 #include <assert.h>
31 #include "PluginTemplate.h"
32
33 using namespace am;
34
35 #define REQUIRED_INTERFACE_VERSION 1
36
37 #define CALL_ALL_INTERFACES(...)                                                                                                                 \
38                 std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();                \
39                 std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();               \
40                 for (; iter<iterEnd;++iter)                                                                                                          \
41                 {                                                                                                                                                                \
42                         (*iter).routingInterface->__VA_ARGS__;                                                                           \
43                 }
44
45 RoutingSender::RoutingSender(const std::vector<std::string>& listOfPluginDirectories) :
46         mHandleCount(0), //
47         mlistActiveHandles(), //
48         mListInterfaces(), //
49         mMapConnectionInterface(), //
50         mMapCrossfaderInterface(), //
51         mMapDomainInterface(), //
52         mMapSinkInterface(), //
53         mMapSourceInterface(), //
54         mMapHandleInterface() //
55 {
56     std::vector<std::string> sharedLibraryNameList;
57     std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
58     std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
59
60     // search communicator plugins in configured directories
61     for (; dirIter < dirIterEnd; ++dirIter)
62     {
63         const char* directoryName = dirIter->c_str();
64         //DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Searching for HookPlugins in"),DLT_STRING(directoryName));
65         DIR *directory = opendir(directoryName);
66
67         if (!directory)
68         {
69             DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender Error opening directory "), DLT_STRING(directoryName));
70             continue;
71         }
72
73         // iterate content of directory
74         struct dirent *itemInDirectory = 0;
75         while ((itemInDirectory = readdir(directory)))
76         {
77             unsigned char entryType = itemInDirectory->d_type;
78             std::string entryName = itemInDirectory->d_name;
79
80             bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
81             bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
82
83             if (regularFile && sharedLibExtension)
84             {
85                 DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("RoutingSender::RoutingSender adding file "), DLT_STRING(entryName.c_str()));
86                 std::string name(directoryName);
87                 sharedLibraryNameList.push_back(name + "/" + entryName);
88             }
89             else
90             {
91                 DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("RoutingSender::RoutingSender PluginSearch ignoring file "), DLT_STRING(entryName.c_str()));
92             }
93         }
94
95         closedir(directory);
96     }
97
98     // iterate all communicator plugins and start them
99     std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
100     std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
101
102     for (; iter != iterEnd; ++iter)
103     {
104         DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("RoutingSender::RoutingSender try loading "), DLT_STRING(iter->c_str()));
105
106         RoutingSendInterface* (*createFunc)();
107         void* tempLibHandle = NULL;
108         createFunc = getCreateFunction<RoutingSendInterface*()>(*iter, tempLibHandle);
109
110         if (!createFunc)
111         {
112             DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender Entry point of RoutingPlugin not found"));
113             continue;
114         }
115
116         RoutingSendInterface* router = createFunc();
117
118         if (!router)
119         {
120             DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender RoutingPlugin initialization failed. Entry Function not callable"));
121             continue;
122         }
123
124         InterfaceNamePairs routerInterface;
125         routerInterface.routingInterface = router;
126
127         //check libversion
128         if (router->getInterfaceVersion() < REQUIRED_INTERFACE_VERSION)
129         {
130             DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender RoutingPlugin initialization failed. Version of Interface to old"));
131             continue;
132         }
133
134         //here, the busname is saved together with the interface. Later The domains will register with the name and sinks, sources etc with the domain....
135         router->returnBusName(routerInterface.busName);
136         assert(!routerInterface.busName.empty());
137         mListInterfaces.push_back(routerInterface);
138         mListLibraryHandles.push_back(tempLibHandle);
139     }
140 }
141
142 RoutingSender::~RoutingSender()
143 {
144     unloadLibraries();
145     HandlesMap::iterator it = mlistActiveHandles.begin();
146
147     //clean up heap if existent
148     for (; it != mlistActiveHandles.end(); ++it)
149     {
150         if (it->first.handleType == H_SETSINKSOUNDPROPERTIES || it->first.handleType == H_SETSOURCESOUNDPROPERTIES)
151         {
152             delete it->second.soundProperties;
153         }
154     }
155 }
156
157 void RoutingSender::routingInterfacesReady()
158 {
159     CALL_ALL_INTERFACES(routingInterfacesReady())
160 }
161
162 void RoutingSender::routingInterfacesRundown()
163 {
164     CALL_ALL_INTERFACES(routingInterfacesRundown())
165 }
166
167 void RoutingSender::startupRoutingInterface(RoutingReceiveInterface *routingreceiveinterface)
168 {
169     CALL_ALL_INTERFACES(startupRoutingInterface(routingreceiveinterface))
170 }
171
172 am_Error_e RoutingSender::asyncAbort(const am_Handle_s& handle)
173 {
174     HandleInterfaceMap::iterator iter = mMapHandleInterface.begin();
175     iter = mMapHandleInterface.find(handle.handle);
176     if (iter != mMapHandleInterface.end())
177     {
178         return iter->second->asyncAbort(handle);
179     }
180
181     return E_NON_EXISTENT;
182 }
183
184 am_Error_e RoutingSender::asyncConnect(am_Handle_s& handle, const am_connectionID_t connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_ConnectionFormat_e connectionFormat)
185 {
186     am_handleData_c handleData;
187     SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
188     iter = mMapSinkInterface.find(sinkID);
189     if (iter != mMapSinkInterface.end())
190     {
191         handleData.connectionID = connectionID;
192         handle = createHandle(handleData, H_CONNECT);
193         mMapConnectionInterface.insert(std::make_pair(connectionID, iter->second));
194         mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
195         return iter->second->asyncConnect(handle, connectionID, sourceID, sinkID, connectionFormat);
196     }
197
198     return E_NON_EXISTENT;
199 }
200
201 am_Error_e RoutingSender::asyncDisconnect(am_Handle_s& handle, const am_connectionID_t connectionID)
202 {
203     am_handleData_c handleData;
204     ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
205     mMapConnectionInterface.find(connectionID);
206     if (iter != mMapConnectionInterface.end())
207     {
208         handleData.connectionID = connectionID;
209         handle = createHandle(handleData, H_DISCONNECT);
210         mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
211         am_Error_e returnVal = iter->second->asyncDisconnect(handle, connectionID);
212         mMapConnectionInterface.erase(iter);
213         return returnVal;
214     }
215
216     return E_NON_EXISTENT;
217 }
218
219 am_Error_e RoutingSender::asyncSetSinkVolume(am_Handle_s& handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_RampType_e ramp, const am_time_t time)
220 {
221     am_handleData_c handleData;
222     SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
223     iter = mMapSinkInterface.find(sinkID);
224     if (iter != mMapSinkInterface.end())
225         handleData.sinkID = sinkID;
226     handleData.volume = volume;
227     handle = createHandle(handleData, H_SETSINKVOLUME);
228     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
229     return iter->second->asyncSetSinkVolume(handle, sinkID, volume, ramp, time);
230     return E_NON_EXISTENT;
231 }
232
233 am_Error_e RoutingSender::asyncSetSourceVolume(am_Handle_s& handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_RampType_e ramp, const am_time_t time)
234 {
235     am_handleData_c handleData;
236     SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
237     iter = mMapSourceInterface.find(sourceID);
238     if (iter != mMapSourceInterface.end())
239         handleData.sourceID = sourceID;
240     handleData.volume = volume;
241     handle = createHandle(handleData, H_SETSOURCEVOLUME);
242     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
243     return iter->second->asyncSetSourceVolume(handle, sourceID, volume, ramp, time);
244     return E_NON_EXISTENT;
245 }
246
247 am_Error_e RoutingSender::asyncSetSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state)
248 {
249     am_handleData_c handleData;
250     SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
251     iter = mMapSourceInterface.find(sourceID);
252     if (iter != mMapSourceInterface.end())
253         handleData.sourceID = sourceID;
254     handleData.sourceState = state;
255     handle = createHandle(handleData, H_SETSOURCESTATE);
256     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
257     return iter->second->asyncSetSourceState(handle, sourceID, state);
258     return E_NON_EXISTENT;
259 }
260
261 am_Error_e RoutingSender::asyncSetSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s & soundProperty)
262 {
263     am_handleData_c handleData;
264     SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
265     iter = mMapSinkInterface.find(sinkID);
266     if (iter != mMapSinkInterface.end())
267         handleData.sinkID = sinkID;
268     handleData.soundPropery = soundProperty;
269     handle = createHandle(handleData, H_SETSINKSOUNDPROPERTY);
270     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
271     return iter->second->asyncSetSinkSoundProperty(handle, soundProperty, sinkID);
272     return (E_NON_EXISTENT);
273 }
274
275 am_Error_e RoutingSender::asyncSetSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s & soundProperty)
276 {
277     am_handleData_c handleData;
278     SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
279     iter = mMapSourceInterface.find(sourceID);
280     if (iter != mMapSourceInterface.end())
281         handleData.sourceID = sourceID;
282     handleData.soundPropery = soundProperty;
283     handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTY);
284     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
285     return iter->second->asyncSetSourceSoundProperty(handle, soundProperty, sourceID);
286     return (E_NON_EXISTENT);
287 }
288
289 am_Error_e am::RoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sourceID_t sourceID)
290 {
291     am_handleData_c handleData;
292     SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
293     iter = mMapSourceInterface.find(sourceID);
294     if (iter != mMapSourceInterface.end())
295         handleData.sourceID = sourceID;
296     handleData.soundProperties = new std::vector<am_SoundProperty_s>(listSoundProperties);
297     handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTIES);
298     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
299     return iter->second->asyncSetSourceSoundProperties(handle, listSoundProperties, sourceID);
300     return (E_NON_EXISTENT);
301 }
302
303 am_Error_e am::RoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sinkID_t sinkID)
304 {
305     am_handleData_c handleData;
306     SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
307     iter = mMapSinkInterface.find(sinkID);
308     if (iter != mMapSinkInterface.end())
309         handleData.sinkID = sinkID;
310     handleData.soundProperties = new std::vector<am_SoundProperty_s>(listSoundProperties);
311     handle = createHandle(handleData, H_SETSINKSOUNDPROPERTIES);
312     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
313     return iter->second->asyncSetSinkSoundProperties(handle, listSoundProperties, sinkID);
314     return (E_NON_EXISTENT);
315
316 }
317
318 am_Error_e RoutingSender::asyncCrossFade(am_Handle_s& handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_RampType_e rampType, const am_time_t time)
319 {
320     am_handleData_c handleData;
321     CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
322     iter = mMapCrossfaderInterface.find(crossfaderID);
323     if (iter != mMapCrossfaderInterface.end())
324         handleData.crossfaderID = crossfaderID;
325     handleData.hotSink = hotSink;
326     handle = createHandle(handleData, H_CROSSFADE);
327     mMapHandleInterface.insert(std::make_pair(handle.handle, iter->second));
328     return iter->second->asyncCrossFade(handle, crossfaderID, hotSink, rampType, time);
329     return E_NON_EXISTENT;
330 }
331
332 am_Error_e RoutingSender::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
333 {
334     DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
335     iter = mMapDomainInterface.find(domainID);
336     if (iter != mMapDomainInterface.end())
337         return iter->second->setDomainState(domainID, domainState);
338     return E_NON_EXISTENT;
339 }
340
341 am_Error_e RoutingSender::addDomainLookup(const am_Domain_s& domainData)
342 {
343     std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
344     std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
345     for (; iter < iterEnd; ++iter)
346     {
347         if ((*iter).busName.compare(domainData.busname) == 0)
348         {
349             mMapDomainInterface.insert(std::make_pair(domainData.domainID, (*iter).routingInterface));
350             return E_OK;
351         }
352     }
353
354     return E_UNKNOWN;
355 }
356
357 am_Error_e RoutingSender::addSourceLookup(const am_Source_s& sourceData)
358 {
359     DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
360     iter = mMapDomainInterface.find(sourceData.domainID);
361     if (iter != mMapDomainInterface.end())
362     {
363         mMapSourceInterface.insert(std::make_pair(sourceData.sourceID, iter->second));
364         return E_OK;
365     }
366
367     return E_UNKNOWN;
368 }
369
370 am_Error_e RoutingSender::addSinkLookup(const am_Sink_s& sinkData)
371 {
372     DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
373     iter = mMapDomainInterface.find(sinkData.domainID);
374     if (iter != mMapDomainInterface.end())
375     {
376         mMapSinkInterface.insert(std::make_pair(sinkData.sinkID, iter->second));
377         return E_OK;
378     }
379
380     return E_UNKNOWN;
381 }
382
383 am_Error_e RoutingSender::addCrossfaderLookup(const am_Crossfader_s& crossfaderData)
384 {
385     DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
386     iter = mMapSourceInterface.find(crossfaderData.sourceID);
387     if (iter != mMapSourceInterface.end())
388     {
389         mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID, iter->second));
390         return E_OK;
391     }
392
393     return E_UNKNOWN;
394 }
395
396 am_Error_e RoutingSender::removeDomainLookup(const am_domainID_t domainID)
397 {
398     DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
399     iter = mMapDomainInterface.find(domainID);
400     if (iter != mMapDomainInterface.end())
401     {
402         mMapDomainInterface.erase(iter);
403         return E_OK;
404     }
405
406     return E_NON_EXISTENT;
407 }
408
409 am_Error_e RoutingSender::removeSourceLookup(const am_sourceID_t sourceID)
410 {
411     SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
412     iter = mMapSourceInterface.find(sourceID);
413     if (iter != mMapSourceInterface.end())
414     {
415         mMapSourceInterface.erase(iter);
416         return E_OK;
417     }
418
419     return E_NON_EXISTENT;
420 }
421
422 am_Error_e RoutingSender::removeSinkLookup(const am_sinkID_t sinkID)
423 {
424     SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
425     iter = mMapSinkInterface.find(sinkID);
426     if (iter != mMapSinkInterface.end())
427     {
428         mMapSinkInterface.erase(iter);
429         return E_OK;
430     }
431
432     return E_NON_EXISTENT;
433 }
434
435 am_Error_e RoutingSender::removeCrossfaderLookup(const am_crossfaderID_t crossfaderID)
436 {
437     CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
438     iter = mMapCrossfaderInterface.find(crossfaderID);
439     if (iter != mMapCrossfaderInterface.end())
440     {
441         mMapCrossfaderInterface.erase(iter);
442         return E_OK;
443     }
444
445     return E_NON_EXISTENT;
446 }
447
448 am_Error_e RoutingSender::removeHandle(const am_Handle_s& handle)
449 {
450     if (mlistActiveHandles.erase(handle))
451         return E_OK;
452     return E_UNKNOWN;
453 }
454
455 am_Error_e RoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
456 {
457     listHandles.clear();
458     HandlesMap::const_iterator it = mlistActiveHandles.begin();
459     for (; it != mlistActiveHandles.end(); ++it)
460     {
461         listHandles.push_back(it->first);
462     }
463     return E_OK;
464 }
465
466 am_Handle_s RoutingSender::createHandle(const am_handleData_c& handleData, const am_Handle_e type)
467 {
468     am_Handle_s handle;
469     handle.handle = ++mHandleCount; //todo: handle overflows here...
470     handle.handleType = type;
471     mlistActiveHandles.insert(std::make_pair(handle, handleData));
472     return handle;
473 }
474
475 RoutingSender::am_handleData_c RoutingSender::returnHandleData(const am_Handle_s handle) const
476 {
477     HandlesMap::const_iterator it = mlistActiveHandles.begin();
478     it = mlistActiveHandles.find(handle);
479     return (it->second);
480 }
481
482 void RoutingSender::unloadLibraries(void)
483 {
484     std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
485     for (; iterator < mListLibraryHandles.end(); ++iterator)
486     {
487         dlclose(*iterator);
488     }
489     mListLibraryHandles.clear();
490 }
491
492 am_Error_e am::RoutingSender::getListPlugins(std::vector<std::string>& interfaces) const
493 {
494     std::vector<InterfaceNamePairs>::const_iterator it = mListInterfaces.begin();
495     for (; it != mListInterfaces.end(); ++it)
496     {
497         interfaces.push_back(it->busName);
498     }
499     return E_OK;
500 }
501
502 uint16_t RoutingSender::getInterfaceVersion() const
503 {
504     return (RoutingSendVersion);
505 }
506