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