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