2 * Copyright (C) 2011, BMW AG
4 * GeniviAudioMananger AudioManagerDaemon
6 * \file RoutingSender.h
8 * \date 20-Oct-2011 3:42:04 PM
9 * \author Christian Mueller (christian.ei.mueller@bmw.de)
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
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.
25 #include "RoutingSender.h"
31 #include "PluginTemplate.h"
35 #define REQUIRED_INTERFACE_VERSION 1
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) \
42 (*iter).routingInterface->__VA_ARGS__; \
45 RoutingSender::RoutingSender(const std::vector<std::string>& listOfPluginDirectories)
50 mMapConnectionInterface(),
51 mMapCrossfaderInterface(),
52 mMapDomainInterface(),
54 mMapSourceInterface(),
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();
61 // search communicator plugins in configured directories
62 for (; dirIter < dirIterEnd; ++dirIter)
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);
70 DLT_LOG(AudioManager,DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender Error opening directory "),DLT_STRING(directoryName));
74 // iterate content of directory
75 struct dirent *itemInDirectory = 0;
76 while ((itemInDirectory = readdir(directory)))
78 unsigned char entryType = itemInDirectory->d_type;
79 std::string entryName = itemInDirectory->d_name;
81 bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
82 bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
84 if (regularFile && sharedLibExtension)
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);
92 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("RoutingSender::RoutingSender PluginSearch ignoring file "),DLT_STRING(entryName.c_str()));
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();
103 for (; iter != iterEnd; ++iter)
105 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("RoutingSender::RoutingSender try loading "),DLT_STRING(iter->c_str()));
107 RoutingSendInterface* (*createFunc)();
108 void* tempLibHandle=NULL;
109 createFunc = getCreateFunction<RoutingSendInterface*()>(*iter,tempLibHandle);
113 DLT_LOG(AudioManager,DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender Entry point of RoutingPlugin not found"));
117 RoutingSendInterface* router = createFunc();
121 DLT_LOG(AudioManager,DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender RoutingPlugin initialization failed. Entry Function not callable"));
125 InterfaceNamePairs routerInterface;
126 routerInterface.routingInterface = router;
129 if (router->getInterfaceVersion()<REQUIRED_INTERFACE_VERSION)
131 DLT_LOG(AudioManager,DLT_LOG_ERROR, DLT_STRING("RoutingSender::RoutingSender RoutingPlugin initialization failed. Version of Interface to old"));
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);
144 RoutingSender::~RoutingSender()
147 HandlesMap::iterator it=mlistActiveHandles.begin();
149 //clean up heap if existent
150 for(;it!=mlistActiveHandles.end();++it)
152 if (it->first.handleType==H_SETSINKSOUNDPROPERTIES || it->first.handleType==H_SETSOURCESOUNDPROPERTIES)
154 delete it->second.soundProperties;
159 void RoutingSender::routingInterfacesReady()
161 CALL_ALL_INTERFACES(routingInterfacesReady())
164 void RoutingSender::routingInterfacesRundown()
166 CALL_ALL_INTERFACES(routingInterfacesRundown())
169 void RoutingSender::startupRoutingInterface(RoutingReceiveInterface *routingreceiveinterface)
171 CALL_ALL_INTERFACES(startupRoutingInterface(routingreceiveinterface))
174 am_Error_e RoutingSender::asyncAbort(const am_Handle_s& handle)
176 HandleInterfaceMap::iterator iter = mMapHandleInterface.begin();
177 iter=mMapHandleInterface.find(handle.handle);
178 if (iter != mMapHandleInterface.end())
180 return iter->second->asyncAbort(handle);
183 return E_NON_EXISTENT;
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)
190 am_handleData_c handleData;
191 SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
192 iter=mMapSinkInterface.find(sinkID);
193 if (iter != mMapSinkInterface.end())
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);
202 return E_NON_EXISTENT;
207 am_Error_e RoutingSender::asyncDisconnect(am_Handle_s& handle, const am_connectionID_t connectionID)
209 am_handleData_c handleData;
210 ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
211 mMapConnectionInterface.find(connectionID);
212 if (iter != mMapConnectionInterface.end())
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);
222 return E_NON_EXISTENT;
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)
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;
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)
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;
259 am_Error_e RoutingSender::asyncSetSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state)
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;
275 am_Error_e RoutingSender::asyncSetSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s & soundProperty)
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);
290 am_Error_e RoutingSender::asyncSetSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s & soundProperty)
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);
304 am_Error_e am::RoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sourceID_t sourceID)
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);
319 am_Error_e am::RoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sinkID_t sinkID)
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);
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)
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;
350 am_Error_e RoutingSender::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
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;
359 am_Error_e RoutingSender::addDomainLookup(const am_Domain_s& domainData)
361 std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
362 std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
363 for (; iter<iterEnd;++iter)
365 if((*iter).busName.compare(domainData.busname) == 0)
367 mMapDomainInterface.insert(std::make_pair(domainData.domainID,(*iter).routingInterface));
377 am_Error_e RoutingSender::addSourceLookup(const am_Source_s& sourceData)
379 DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
380 iter=mMapDomainInterface.find(sourceData.domainID);
381 if (iter != mMapDomainInterface.end())
383 mMapSourceInterface.insert(std::make_pair(sourceData.sourceID,iter->second));
392 am_Error_e RoutingSender::addSinkLookup(const am_Sink_s& sinkData)
394 DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
395 iter=mMapDomainInterface.find(sinkData.domainID);
396 if (iter != mMapDomainInterface.end())
398 mMapSinkInterface.insert(std::make_pair(sinkData.sinkID,iter->second));
407 am_Error_e RoutingSender::addCrossfaderLookup(const am_Crossfader_s& crossfaderData)
409 DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
410 iter=mMapSourceInterface.find(crossfaderData.sourceID);
411 if (iter != mMapSourceInterface.end())
413 mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID,iter->second));
420 am_Error_e RoutingSender::removeDomainLookup(const am_domainID_t domainID)
422 DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
423 iter=mMapDomainInterface.find(domainID);
424 if (iter != mMapDomainInterface.end())
426 mMapDomainInterface.erase(iter);
430 return E_NON_EXISTENT;
435 am_Error_e RoutingSender::removeSourceLookup(const am_sourceID_t sourceID)
437 SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
438 iter=mMapSourceInterface.find(sourceID);
439 if (iter != mMapSourceInterface.end())
441 mMapSourceInterface.erase(iter);
445 return E_NON_EXISTENT;
450 am_Error_e RoutingSender::removeSinkLookup(const am_sinkID_t sinkID)
452 SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
453 iter=mMapSinkInterface.find(sinkID);
454 if (iter != mMapSinkInterface.end())
456 mMapSinkInterface.erase(iter);
460 return E_NON_EXISTENT;
465 am_Error_e RoutingSender::removeCrossfaderLookup(const am_crossfaderID_t crossfaderID)
467 CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
468 iter=mMapCrossfaderInterface.find(crossfaderID);
469 if (iter != mMapCrossfaderInterface.end())
471 mMapCrossfaderInterface.erase(iter);
475 return E_NON_EXISTENT;
479 am_Error_e RoutingSender::removeHandle(const am_Handle_s& handle)
481 if(mlistActiveHandles.erase(handle)) return E_OK;
485 am_Error_e RoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
488 HandlesMap::const_iterator it=mlistActiveHandles.begin();
489 for(;it!=mlistActiveHandles.end();++it)
491 listHandles.push_back(it->first);
496 am_Handle_s RoutingSender::createHandle(const am_handleData_c& handleData, const am_Handle_e type)
499 handle.handle=++mHandleCount; //todo: handle overflows here...
500 handle.handleType=type;
501 mlistActiveHandles.insert(std::make_pair(handle,handleData));
505 RoutingSender::am_handleData_c RoutingSender::returnHandleData(const am_Handle_s handle) const
507 HandlesMap::const_iterator it=mlistActiveHandles.begin();
508 it=mlistActiveHandles.find(handle);
512 void RoutingSender::unloadLibraries(void)
514 std::vector<void*>::iterator iterator=mListLibraryHandles.begin();
515 for(;iterator<mListLibraryHandles.end();++iterator)
519 mListLibraryHandles.clear();
522 am_Error_e am::RoutingSender::getListPlugins(std::vector<std::string>& interfaces) const
524 std::vector<InterfaceNamePairs>::const_iterator it=mListInterfaces.begin();
525 for(;it!=mListInterfaces.end();++it)
527 interfaces.push_back(it->busName);
533 uint16_t RoutingSender::getInterfaceVersion() const
535 return (RoutingSendVersion);