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"
30 #include "PluginTemplate.h"
31 #include "DLTWrapper.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) :
47 mlistActiveHandles(), //
49 mMapConnectionInterface(), //
50 mMapCrossfaderInterface(), //
51 mMapDomainInterface(), //
52 mMapSinkInterface(), //
53 mMapSourceInterface(), //
54 mMapHandleInterface() //
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();
60 // search communicator plugins in configured directories
61 for (; dirIter < dirIterEnd; ++dirIter)
63 const char* directoryName = dirIter->c_str();
64 logInfo("Searching for HookPlugins in",directoryName);
65 DIR *directory = opendir(directoryName);
69 logError("RoutingSender::RoutingSender Error opening directory: ", directoryName);
73 // iterate content of directory
74 struct dirent *itemInDirectory = 0;
75 while ((itemInDirectory = readdir(directory)))
77 unsigned char entryType = itemInDirectory->d_type;
78 std::string entryName = itemInDirectory->d_name;
80 bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
81 bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
83 if (regularFile && sharedLibExtension)
85 logInfo("RoutingSender::RoutingSender adding file: ", entryName);
86 std::string name(directoryName);
87 sharedLibraryNameList.push_back(name + "/" + entryName);
91 logInfo("RoutingSender::RoutingSender PluginSearch ignoring file :", entryName);
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();
102 for (; iter != iterEnd; ++iter)
104 logInfo("RoutingSender::RoutingSender try loading: " , *iter);
106 RoutingSendInterface* (*createFunc)();
107 void* tempLibHandle = NULL;
108 createFunc = getCreateFunction<RoutingSendInterface*()>(*iter, tempLibHandle);
112 logError("RoutingSender::RoutingSender Entry point of RoutingPlugin not found");
116 RoutingSendInterface* router = createFunc();
120 logError("RoutingSender::RoutingSender RoutingPlugin initialization failed. Entry Function not callable");
124 InterfaceNamePairs routerInterface;
125 routerInterface.routingInterface = router;
128 if (router->getInterfaceVersion() < REQUIRED_INTERFACE_VERSION)
130 logError("RoutingSender::RoutingSender RoutingPlugin initialization failed. Version of Interface to old");
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);
142 RoutingSender::~RoutingSender()
145 HandlesMap::iterator it = mlistActiveHandles.begin();
147 //clean up heap if existent
148 for (; it != mlistActiveHandles.end(); ++it)
150 if (it->first.handleType == H_SETSINKSOUNDPROPERTIES || it->first.handleType == H_SETSOURCESOUNDPROPERTIES)
152 delete it->second.soundProperties;
157 void RoutingSender::routingInterfacesReady()
159 CALL_ALL_INTERFACES(routingInterfacesReady())
162 void RoutingSender::routingInterfacesRundown()
164 CALL_ALL_INTERFACES(routingInterfacesRundown())
167 void RoutingSender::startupRoutingInterface(RoutingReceiveInterface *routingreceiveinterface)
169 CALL_ALL_INTERFACES(startupRoutingInterface(routingreceiveinterface))
172 am_Error_e RoutingSender::asyncAbort(const am_Handle_s& handle)
174 HandleInterfaceMap::iterator iter = mMapHandleInterface.begin();
175 iter = mMapHandleInterface.find(handle.handle);
176 if (iter != mMapHandleInterface.end())
178 return iter->second->asyncAbort(handle);
181 return E_NON_EXISTENT;
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)
186 am_handleData_c handleData;
187 SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
188 iter = mMapSinkInterface.find(sinkID);
189 if (iter != mMapSinkInterface.end())
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);
198 return E_NON_EXISTENT;
201 am_Error_e RoutingSender::asyncDisconnect(am_Handle_s& handle, const am_connectionID_t connectionID)
203 am_handleData_c handleData;
204 ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
205 mMapConnectionInterface.find(connectionID);
206 if (iter != mMapConnectionInterface.end())
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);
216 return E_NON_EXISTENT;
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)
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;
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)
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;
247 am_Error_e RoutingSender::asyncSetSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state)
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;
261 am_Error_e RoutingSender::asyncSetSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s & soundProperty)
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, sinkID, soundProperty);
272 return (E_NON_EXISTENT);
275 am_Error_e RoutingSender::asyncSetSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s & soundProperty)
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, sourceID, soundProperty);
286 return (E_NON_EXISTENT);
289 am_Error_e am::RoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sourceID_t sourceID)
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, sourceID, listSoundProperties);
300 return (E_NON_EXISTENT);
303 am_Error_e am::RoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sinkID_t sinkID)
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, sinkID, listSoundProperties);
314 return (E_NON_EXISTENT);
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)
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;
332 am_Error_e RoutingSender::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
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;
341 am_Error_e RoutingSender::addDomainLookup(const am_Domain_s& domainData)
343 std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
344 std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
345 for (; iter < iterEnd; ++iter)
347 if ((*iter).busName.compare(domainData.busname) == 0)
349 mMapDomainInterface.insert(std::make_pair(domainData.domainID, (*iter).routingInterface));
357 am_Error_e RoutingSender::addSourceLookup(const am_Source_s& sourceData)
359 DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
360 iter = mMapDomainInterface.find(sourceData.domainID);
361 if (iter != mMapDomainInterface.end())
363 mMapSourceInterface.insert(std::make_pair(sourceData.sourceID, iter->second));
370 am_Error_e RoutingSender::addSinkLookup(const am_Sink_s& sinkData)
372 DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
373 iter = mMapDomainInterface.find(sinkData.domainID);
374 if (iter != mMapDomainInterface.end())
376 mMapSinkInterface.insert(std::make_pair(sinkData.sinkID, iter->second));
383 am_Error_e RoutingSender::addCrossfaderLookup(const am_Crossfader_s& crossfaderData)
385 DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
386 iter = mMapSourceInterface.find(crossfaderData.sourceID);
387 if (iter != mMapSourceInterface.end())
389 mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID, iter->second));
396 am_Error_e RoutingSender::removeDomainLookup(const am_domainID_t domainID)
398 DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
399 iter = mMapDomainInterface.find(domainID);
400 if (iter != mMapDomainInterface.end())
402 mMapDomainInterface.erase(iter);
406 return E_NON_EXISTENT;
409 am_Error_e RoutingSender::removeSourceLookup(const am_sourceID_t sourceID)
411 SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
412 iter = mMapSourceInterface.find(sourceID);
413 if (iter != mMapSourceInterface.end())
415 mMapSourceInterface.erase(iter);
419 return E_NON_EXISTENT;
422 am_Error_e RoutingSender::removeSinkLookup(const am_sinkID_t sinkID)
424 SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
425 iter = mMapSinkInterface.find(sinkID);
426 if (iter != mMapSinkInterface.end())
428 mMapSinkInterface.erase(iter);
432 return E_NON_EXISTENT;
435 am_Error_e RoutingSender::removeCrossfaderLookup(const am_crossfaderID_t crossfaderID)
437 CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
438 iter = mMapCrossfaderInterface.find(crossfaderID);
439 if (iter != mMapCrossfaderInterface.end())
441 mMapCrossfaderInterface.erase(iter);
445 return E_NON_EXISTENT;
448 am_Error_e RoutingSender::removeHandle(const am_Handle_s& handle)
450 if (mlistActiveHandles.erase(handle))
455 am_Error_e RoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
458 HandlesMap::const_iterator it = mlistActiveHandles.begin();
459 for (; it != mlistActiveHandles.end(); ++it)
461 listHandles.push_back(it->first);
466 am_Handle_s RoutingSender::createHandle(const am_handleData_c& handleData, const am_Handle_e type)
469 handle.handle = ++mHandleCount; //todo: handle overflows here...
470 handle.handleType = type;
471 mlistActiveHandles.insert(std::make_pair(handle, handleData));
475 RoutingSender::am_handleData_c RoutingSender::returnHandleData(const am_Handle_s handle) const
477 HandlesMap::const_iterator it = mlistActiveHandles.begin();
478 it = mlistActiveHandles.find(handle);
482 void RoutingSender::unloadLibraries(void)
484 std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
485 for (; iterator < mListLibraryHandles.end(); ++iterator)
489 mListLibraryHandles.clear();
492 am_Error_e am::RoutingSender::getListPlugins(std::vector<std::string>& interfaces) const
494 std::vector<InterfaceNamePairs>::const_iterator it = mListInterfaces.begin();
495 for (; it != mListInterfaces.end(); ++it)
497 interfaces.push_back(it->busName);
502 uint16_t RoutingSender::getInterfaceVersion() const
504 return (RoutingSendVersion);