735f2601a63b217259c804e84a0df834b3ecd019
[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         router->returnBusName(routerInterface.busName);
122         mListInterfaces.push_back(routerInterface);
123         mListLibraryHandles.push_back(tempLibHandle);
124     }
125 }
126
127 RoutingSender::~RoutingSender()
128 {
129         unloadLibraries();
130 }
131
132 void RoutingSender::routingInterfacesReady()
133 {
134         CALL_ALL_INTERFACES(routingInterfacesReady())
135 }
136
137 void RoutingSender::routingInterfacesRundown()
138 {
139         CALL_ALL_INTERFACES(routingInterfacesRundown())
140 }
141
142 void RoutingSender::startupRoutingInterface(RoutingReceiveInterface *routingreceiveinterface)
143 {
144         CALL_ALL_INTERFACES(startupRoutingInterface(routingreceiveinterface))
145 }
146
147 am_Error_e RoutingSender::asyncAbort(const am_Handle_s& handle)
148 {
149         HandleInterfaceMap::iterator iter = mMapHandleInterface.begin();
150         iter=mMapHandleInterface.find(handle.handle);
151     if (iter != mMapHandleInterface.end())
152     {
153         return iter->second->asyncAbort(handle);
154     }
155
156     return E_NON_EXISTENT;
157 }
158
159
160
161 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)
162 {
163         am_handleData_c handleData;
164         SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
165         iter=mMapSinkInterface.find(sinkID);
166     if (iter != mMapSinkInterface.end())
167     {
168         handleData.connectionID=connectionID;
169         handle=createHandle(handleData,H_CONNECT);
170         mMapConnectionInterface.insert(std::make_pair(connectionID,iter->second));
171         mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
172         return iter->second->asyncConnect(handle,connectionID,sourceID,sinkID,connectionFormat);
173     }
174
175     return E_NON_EXISTENT;
176 }
177
178
179
180 am_Error_e RoutingSender::asyncDisconnect(am_Handle_s& handle, const am_connectionID_t connectionID)
181 {
182         am_handleData_c handleData;
183         ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
184         mMapConnectionInterface.find(connectionID);
185     if (iter != mMapConnectionInterface.end())
186     {
187         handleData.connectionID=connectionID;
188         handle=createHandle(handleData,H_DISCONNECT);
189         mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
190         am_Error_e returnVal=iter->second->asyncDisconnect(handle,connectionID);
191         mMapConnectionInterface.erase(iter);
192         return returnVal;
193     }
194
195     return E_NON_EXISTENT;
196 }
197
198
199
200 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)
201 {
202         am_handleData_c handleData;
203         SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
204         iter=mMapSinkInterface.find(sinkID);
205     if (iter != mMapSinkInterface.end())
206         handleData.sinkID=sinkID;
207         handleData.volume=volume;
208         handle=createHandle(handleData,H_SETSINKVOLUME);
209                 mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
210         return iter->second->asyncSetSinkVolume(handle,sinkID,volume,ramp,time);
211     return E_NON_EXISTENT;
212 }
213
214
215
216 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)
217 {
218         am_handleData_c handleData;
219         SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
220         iter=mMapSourceInterface.find(sourceID);
221     if (iter != mMapSourceInterface.end())
222         handleData.sourceID=sourceID;
223         handleData.volume=volume;
224         handle=createHandle(handleData,H_SETSOURCEVOLUME);
225                 mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
226         return iter->second->asyncSetSourceVolume(handle,sourceID,volume,ramp,time);
227     return E_NON_EXISTENT;
228 }
229
230
231
232 am_Error_e RoutingSender::asyncSetSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state)
233 {
234         am_handleData_c handleData;
235         SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
236         iter=mMapSourceInterface.find(sourceID);
237     if (iter != mMapSourceInterface.end())
238         handleData.sourceID=sourceID;
239         handleData.sourceState=state;
240         handle=createHandle(handleData,H_SETSOURCESTATE);
241                 mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
242         return iter->second->asyncSetSourceState(handle,sourceID,state);
243     return E_NON_EXISTENT;
244 }
245
246
247
248 am_Error_e RoutingSender::asyncSetSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s & soundProperty)
249 {
250         am_handleData_c handleData;
251         SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
252         iter=mMapSinkInterface.find(sinkID);
253     if (iter != mMapSinkInterface.end())
254         handleData.sinkID=sinkID;
255         handleData.soundPropery=soundProperty;
256         handle=createHandle(handleData,H_SETSINKSOUNDPROPERTY);
257                 mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
258         return iter->second->asyncSetSinkSoundProperty(handle,soundProperty,sinkID);
259     return E_NON_EXISTENT;
260 }
261
262
263
264 am_Error_e RoutingSender::asyncSetSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s & soundProperty)
265 {
266         am_handleData_c handleData;
267         SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
268         iter=mMapSourceInterface.find(sourceID);
269     if (iter != mMapSourceInterface.end())
270         handleData.sourceID=sourceID;
271         handleData.soundPropery=soundProperty;
272         handle=createHandle(handleData,H_SETSOURCESOUNDPROPERTY);
273                 mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
274         return iter->second->asyncSetSourceSoundProperty(handle,soundProperty,sourceID);
275     return E_NON_EXISTENT;
276 }
277
278
279
280 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)
281 {
282         am_handleData_c handleData;
283         CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
284         iter=mMapCrossfaderInterface.find(crossfaderID);
285     if (iter != mMapCrossfaderInterface.end())
286         handleData.crossfaderID=crossfaderID;
287         handleData.hotSink=hotSink;
288         handle=createHandle(handleData,H_CROSSFADE);
289                 mMapHandleInterface.insert(std::make_pair(handle.handle,iter->second));
290         return iter->second->asyncCrossFade(handle,crossfaderID,hotSink,rampType,time);
291     return E_NON_EXISTENT;
292 }
293
294
295
296 am_Error_e RoutingSender::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
297 {
298         DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
299         iter=mMapDomainInterface.find(domainID);
300     if (iter != mMapDomainInterface.end())
301         return iter->second->setDomainState(domainID,domainState);
302     return E_NON_EXISTENT;
303 }
304
305 am_Error_e RoutingSender::addDomainLookup(const am_Domain_s& domainData)
306 {
307         std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
308         std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
309         for (; iter<iterEnd;++iter)
310         {
311                 if((*iter).busName.compare(domainData.busname) == 0)
312                 {
313                         mMapDomainInterface.insert(std::make_pair(domainData.domainID,(*iter).routingInterface));
314                         return E_OK;
315                 }
316         }
317
318         return E_UNKNOWN;
319 }
320
321
322
323 am_Error_e RoutingSender::addSourceLookup(const am_Source_s& sourceData)
324 {
325         DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
326         iter=mMapDomainInterface.find(sourceData.domainID);
327     if (iter != mMapDomainInterface.end())
328     {
329         mMapSourceInterface.insert(std::make_pair(sourceData.sourceID,iter->second));
330         return E_OK;
331     }
332
333     return E_UNKNOWN;
334 }
335
336
337
338 am_Error_e RoutingSender::addSinkLookup(const am_Sink_s& sinkData)
339 {
340         DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
341         iter=mMapDomainInterface.find(sinkData.domainID);
342     if (iter != mMapDomainInterface.end())
343     {
344         mMapSinkInterface.insert(std::make_pair(sinkData.sinkID,iter->second));
345         return E_OK;
346     }
347
348     return E_UNKNOWN;
349 }
350
351
352
353 am_Error_e RoutingSender::addCrossfaderLookup(const am_Crossfader_s& crossfaderData)
354 {
355         DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
356         iter=mMapSourceInterface.find(crossfaderData.sourceID);
357     if (iter != mMapSourceInterface.end())
358     {
359         mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID,iter->second));
360         return E_OK;
361     }
362
363     return E_UNKNOWN;
364 }
365
366 am_Error_e RoutingSender::removeDomainLookup(const am_domainID_t domainID)
367 {
368         DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
369         iter=mMapDomainInterface.find(domainID);
370     if (iter != mMapDomainInterface.end())
371     {
372         mMapDomainInterface.erase(iter);
373         return E_OK;
374     }
375
376     return E_NON_EXISTENT;
377 }
378
379
380
381 am_Error_e RoutingSender::removeSourceLookup(const am_sourceID_t sourceID)
382 {
383         SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
384         iter=mMapSourceInterface.find(sourceID);
385     if (iter != mMapSourceInterface.end())
386     {
387         mMapSourceInterface.erase(iter);
388         return E_OK;
389     }
390
391     return E_NON_EXISTENT;
392 }
393
394
395
396 am_Error_e RoutingSender::removeSinkLookup(const am_sinkID_t sinkID)
397 {
398         SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
399         iter=mMapSinkInterface.find(sinkID);
400     if (iter != mMapSinkInterface.end())
401     {
402         mMapSinkInterface.erase(iter);
403         return E_OK;
404     }
405
406     return E_NON_EXISTENT;
407 }
408
409
410
411 am_Error_e RoutingSender::removeCrossfaderLookup(const am_crossfaderID_t crossfaderID)
412 {
413         CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
414         iter=mMapCrossfaderInterface.find(crossfaderID);
415     if (iter != mMapCrossfaderInterface.end())
416     {
417         mMapCrossfaderInterface.erase(iter);
418         return E_OK;
419     }
420
421     return E_NON_EXISTENT;
422 }
423
424
425 am_Error_e RoutingSender::removeHandle(const am_Handle_s& handle)
426 {
427         if(mlistActiveHandles.erase(handle)) return E_OK;
428         return E_UNKNOWN;
429 }
430
431 am_Error_e RoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
432 {
433         listHandles.clear();
434         HandlesMap::const_iterator it=mlistActiveHandles.begin();
435         for(;it!=mlistActiveHandles.end();++it)
436         {
437                 listHandles.push_back(it->first);
438         }
439         return E_OK;
440 }
441
442 am_Handle_s RoutingSender::createHandle(const am_handleData_c& handleData, const am_Handle_e type)
443 {
444         am_Handle_s handle;
445         handle.handle=++mHandleCount; //todo: handle overflows here...
446         handle.handleType=type;
447         mlistActiveHandles.insert(std::make_pair(handle,handleData));
448         return handle;
449 }
450
451 RoutingSender::am_handleData_c RoutingSender::returnHandleData(am_Handle_s handle)
452 {
453         HandlesMap::iterator it=mlistActiveHandles.begin();
454         it=mlistActiveHandles.find(handle);
455         return (it->second);
456 }
457
458 void RoutingSender::unloadLibraries(void)
459 {
460         std::vector<void*>::iterator iterator=mListLibraryHandles.begin();
461         for(;iterator<mListLibraryHandles.end();++iterator)
462         {
463                 dlclose(*iterator);
464         }
465         mListLibraryHandles.clear();
466 }
467
468
469
470
471
472
473
474
475
476
477