AudioManager  7.6.6
Native Application Runtime Environment
CAmRoutingSender.cpp
Go to the documentation of this file.
1 
24 #include "CAmRoutingSender.h"
25 #include <utility>
26 #include <dirent.h>
27 #include <errno.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <dlfcn.h>
31 #include <cassert>
32 #include <iostream>
33 #include <sstream>
34 #include <stdexcept>
35 #include "CAmRoutingReceiver.h"
36 #include "TAmPluginTemplate.h"
37 #include "CAmDltWrapper.h"
38 #include "IAmDatabaseHandler.h"
39 
40 namespace am
41 {
42 
43 #define REQUIRED_INTERFACE_VERSION_MAJOR 1
44 #define REQUIRED_INTERFACE_VERSION_MINOR 0
45 
46 #define __METHOD_NAME__ std::string (std::string("CAmRoutingSender::") + __func__)
47 
49  const std::vector<std::string>& listOfPluginDirectories,
50  IAmDatabaseHandler* databaseHandler) :
51  mHandleCount(0), //
52  mlistActiveHandles(), //
53  mListInterfaces(), //
54  mMapConnectionInterface(), //
55  mMapCrossfaderInterface(), //
56  mMapDomainInterface(), //
57  mMapSinkInterface(), //
58  mMapSourceInterface(), //
59  mpRoutingReceiver(), //
60  mpDatabaseHandler(databaseHandler) {
61 
62  loadPlugins(listOfPluginDirectories);
63 
64  dboNewSink = [&](const am_Sink_s& sink) {
65  addSinkLookup(sink);
66  };
67  dboNewSource = [&](const am_Source_s& source) {
68  addSourceLookup(source);
69  };
70  dboNewDomain = [&](const am_Domain_s& domain) {
71  addDomainLookup(domain);
72  };
73  //todo: newGateway implement something
74  //todo: newConverter implement something
75  dboNewCrossfader = [&](const am_Crossfader_s& crossfader) {
76  addCrossfaderLookup(crossfader);
77  };
78  dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) {
79  removeSinkLookup(sinkID);
80  };
81  dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) {
82  removeSourceLookup(sourceID);
83  };
84  dboRemoveDomain = [&](const am_domainID_t domainID) {
85  removeDomainLookup(domainID);
86  };
87  //todo: removeGateway implement something
88  //todo: removeConverter implement something
89  dboRemoveCrossfader = [&](const am_crossfaderID_t crossfaderID) {
90  removeCrossfaderLookup(crossfaderID);
91  };
92 }
93 
94 void CAmRoutingSender::loadPlugins(const std::vector<std::string>& listOfPluginDirectories)
95 {
96  if (listOfPluginDirectories.empty())
97  {
98  logError(__METHOD_NAME__,"List of routingplugins is empty");
99  }
100 
101  std::vector<std::string> sharedLibraryNameList;
102  std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
103  std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
104 
105  // search communicator plugins in configured directories
106  for (; dirIter < dirIterEnd; ++dirIter)
107  {
108  const char* directoryName = dirIter->c_str();
109  logInfo(__METHOD_NAME__,"Searching for HookPlugins in", directoryName);
110  DIR *directory = opendir(directoryName);
111 
112  if (!directory)
113  {
114  logError(__METHOD_NAME__,"Error opening directory: ", directoryName);
115  continue;
116  }
117 
118  // iterate content of directory
119  struct dirent *itemInDirectory = 0;
120  while ((itemInDirectory = readdir(directory)))
121  {
122  unsigned char entryType = itemInDirectory->d_type;
123  std::string entryName = itemInDirectory->d_name;
124  std::string fullName = *dirIter + "/" + entryName;
125 
126  bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
127  bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
128 
129  // Handle cases where readdir() could not determine the file type
130  if (entryType == DT_UNKNOWN)
131  {
132  struct stat buf;
133 
134  if (stat(fullName.c_str(), &buf))
135  {
136  logInfo(__METHOD_NAME__,"Failed to stat file: ", entryName, errno);
137  continue;
138  }
139 
140  regularFile = S_ISREG(buf.st_mode);
141  }
142 
143  if (regularFile && sharedLibExtension)
144  {
145  logInfo(__METHOD_NAME__,"adding file: ", entryName);
146  std::string name(directoryName);
147  sharedLibraryNameList.push_back(name + "/" + entryName);
148  }
149  else
150  {
151  logInfo(__METHOD_NAME__, "plugin search ignoring file :", entryName);
152  }
153  }
154 
155  closedir(directory);
156  }
157 
158  // iterate all communicator plugins and start them
159  std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
160  std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
161 
162  for (; iter != iterEnd; ++iter)
163  {
164  logInfo(__METHOD_NAME__,"try loading: ", *iter);
165 
166  IAmRoutingSend* (*createFunc)();
167  void* tempLibHandle = NULL;
168  createFunc = getCreateFunction<IAmRoutingSend*()>(*iter, tempLibHandle);
169 
170  if (!createFunc)
171  {
172  logError(__METHOD_NAME__,"Entry point of RoutingPlugin not found");
173  continue;
174  }
175 
176  IAmRoutingSend* router = createFunc();
177 
178  if (!router)
179  {
180  logError(__METHOD_NAME__,"initialization of plugin ",*iter,"failed. Entry Function not callable");
181  dlclose(tempLibHandle);
182  continue;
183  }
184 
185  InterfaceNamePairs routerInterface;
186  routerInterface.routingInterface = router;
187 
188  //check libversion
189  std::string version, cVersion(RoutingVersion);
190  router->getInterfaceVersion(version);
191  uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion;
192  std::istringstream(version.substr(0, 1)) >> majorVersion;
193  std::istringstream(version.substr(2, 1)) >> minorVersion;
194  std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion;
195  std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion;
196 
197  if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion)))
198  {
199  logError(__METHOD_NAME__,"Routing initialization failed. Version of Interface to old");
200  dlclose(tempLibHandle);
201  continue;
202  }
203 
204  //here, the busname is saved together with the interface. Later The domains will register with the name and sinks, sources etc with the domain....
205  router->returnBusName(routerInterface.busName);
206  assert(!routerInterface.busName.empty());
207  mListInterfaces.push_back(routerInterface);
208  mListLibraryHandles.push_back(tempLibHandle);
209  }
210 }
211 
213 {
214  //unloadLibraries();
215  HandlesMap::iterator it = mlistActiveHandles.begin();
216 
217  //every open handle is assumed to be an error...
218  for (; it != mlistActiveHandles.end(); ++it)
219  {
220  logError(__METHOD_NAME__,"The action for the handle",it->first,"is still open");
221  }
222 }
223 
225 {
226  mpRoutingReceiver = iRoutingReceiver;
227  am_Error_e returnError = E_OK;
228 
229  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
230  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
231  for (; iter < iterEnd; ++iter)
232  {
233  am_Error_e error = (*iter).routingInterface->startupInterface(iRoutingReceiver);
234  if (error != E_OK)
235  {
236  returnError = error;
237  }
238  }
239  return (returnError);
240 }
241 
243 {
244  auto iter (mlistActiveHandles.find(handle));
245  if (iter == mlistActiveHandles.end())
246  {
247  logError(__METHOD_NAME__,"Could not find handle",handle);
248  return (E_NON_EXISTENT);
249  }
250  logInfo(__METHOD_NAME__," handle", handle);
251  return (iter->second->returnInterface()->asyncAbort(handle));
252 }
253 
254 am_Error_e CAmRoutingSender::asyncConnect(am_Handle_s& handle, am_connectionID_t& connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat)
255 {
256  auto iter (mMapSinkInterface.find(sinkID));
257  if (iter == mMapSinkInterface.end())
258  {
259  logError(__METHOD_NAME__,"Could not find sink",sinkID);
260  return (E_NON_EXISTENT);
261  }
262 
263  if(handleExists(handle))
264  {
266  {
267  logInfo(__METHOD_NAME__,"Resending for handle",handle);
268  }
269  else
270  {
271  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
272  return(E_UNKNOWN);
273  }
274  }
275  else
276  {
277 
278  am_Connection_s tempConnection;
279  tempConnection.sinkID = sinkID;
280  tempConnection.sourceID = sourceID;
281  tempConnection.connectionFormat = connectionFormat;
282  tempConnection.connectionID = 0;
283  tempConnection.delay=-1;
284 
285  am_Error_e connError(mpDatabaseHandler->enterConnectionDB(tempConnection, connectionID));
286  if (connError)
287  {
288  return(connError);
289  }
290  mMapConnectionInterface.insert(std::make_pair(connectionID, iter->second));
291  auto handleData = std::make_shared<handleConnect>(iter->second,connectionID,mpDatabaseHandler);
292  handle = createHandle(handleData, am_Handle_e::H_CONNECT);
293  }
294 
295  logInfo(__METHOD_NAME__,"connectionID=",connectionID,"connectionFormat=", connectionFormat, "sourceID=", sourceID, "sinkID=", sinkID,"handle=",handle);
296  am_Error_e syncError(iter->second->asyncConnect(handle, connectionID, sourceID, sinkID, connectionFormat));
297  if (syncError)
298  {
299  removeHandle(handle);
300  logError(__METHOD_NAME__,"Error while calling connect connectionID:",connectionID,"sourceID:",sourceID,"sinkID:",sinkID,"connectionFormat:",connectionFormat,"handle",handle);
301  mpDatabaseHandler->removeConnection(connectionID);
302  }
303  return(syncError);
304 }
305 
307 {
308  auto iter(mMapConnectionInterface.find(connectionID));
309  if (iter == mMapConnectionInterface.end())
310  {
311  logError(__METHOD_NAME__,"Could not find connection",connectionID);
312  return (E_NON_EXISTENT);
313  }
314 
315  if(handleExists(handle))
316  {
318  {
319  logInfo(__METHOD_NAME__,"Resending for handle",handle);
320  }
321  else
322  {
323  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
324  return(E_UNKNOWN);
325  }
326  }
327  else
328  {
329  auto handleData = std::make_shared<handleDisconnect>(iter->second,connectionID,mpDatabaseHandler,this);
330  handle = createHandle(handleData, am_Handle_e::H_DISCONNECT);
331  }
332 
333  logInfo(__METHOD_NAME__,"connectionID=", connectionID, "handle=",handle);
334  am_Error_e syncError(iter->second->asyncDisconnect(handle, connectionID));
335  if (syncError)
336  {
337  removeHandle(handle);
338  logError(__METHOD_NAME__,"Error while calling disconnect connectionID:",connectionID,"handle",handle);
339  }
340  return(syncError);
341 }
342 
344 {
345  auto iter (mMapSinkInterface.find(sinkID));
346  if (iter == mMapSinkInterface.end())
347  {
348  logError(__METHOD_NAME__,"Could not find sink",sinkID);
349  return (E_NON_EXISTENT);
350  }
351 
352  if(handleExists(handle))
353  {
355  {
356  logInfo(__METHOD_NAME__,"Resending for handle",handle);
357  }
358  else
359  {
360  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
361  return(E_UNKNOWN);
362  }
363  }
364  else
365  {
366  auto handleData = std::make_shared<handleSinkVolume>(iter->second,sinkID,mpDatabaseHandler,volume);
367  handle = createHandle(handleData, H_SETSINKVOLUME);
368  }
369 
370  logInfo(__METHOD_NAME__,"sinkID=", sinkID, "volume=", volume, "ramp=", ramp, "time=", time,"handle=",handle);
371  am_Error_e syncError(iter->second->asyncSetSinkVolume(handle, sinkID, volume, ramp, time));
372  if (syncError)
373  {
374  removeHandle(handle);
375  logError(__METHOD_NAME__,"Error while calling asyncSetSinkVolume sinkID:",sinkID,"handle:",handle,"volume:",volume,"ramp:",ramp,"time:",time);
376  }
377  return(syncError);
378 }
379 
381 {
382  auto iter (mMapSourceInterface.find(sourceID));
383  if (iter == mMapSourceInterface.end())
384  {
385  logError(__METHOD_NAME__,"Could not find sourceID",sourceID);
386  return (E_NON_EXISTENT);
387  }
388 
389  if(handleExists(handle))
390  {
392  {
393  logInfo(__METHOD_NAME__,"Resending for handle",handle);
394  }
395  else
396  {
397  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
398  return(E_UNKNOWN);
399  }
400  }
401  else
402  {
403  auto handleData = std::make_shared<handleSourceVolume>(iter->second,sourceID,mpDatabaseHandler,volume);
404  handle = createHandle(handleData, H_SETSOURCEVOLUME);
405  }
406 
407  logInfo(__METHOD_NAME__,"sourceID=", sourceID,"volume=", volume, "ramp=", ramp, "time=", time,"handle=",handle);
408  am_Error_e syncError(iter->second->asyncSetSourceVolume(handle, sourceID, volume, ramp, time));
409  if (syncError)
410  {
411  removeHandle(handle);
412  logError(__METHOD_NAME__,"Error while calling asyncSetSourceVolume sourceID:",sourceID,"handle:",handle,"volume:",volume,"ramp:",ramp,"time:",time);
413  }
414  return(syncError);
415 }
416 
418 {
419  auto iter (mMapSourceInterface.find(sourceID));
420  if (iter == mMapSourceInterface.end())
421  {
422  logError(__METHOD_NAME__,"Could not find sourceID",sourceID);
423  return (E_NON_EXISTENT);
424  }
425 
426  if(handleExists(handle))
427  {
429  {
430  logInfo(__METHOD_NAME__,"Resending for handle",handle);
431  }
432  else
433  {
434  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
435  return(E_UNKNOWN);
436  }
437  }
438  else
439  {
440  auto handleData = std::make_shared<handleSourceState>(iter->second,sourceID,state,mpDatabaseHandler);
441  handle = createHandle(handleData, H_SETSOURCESTATE);
442  }
443  logInfo(__METHOD_NAME__,"sourceID=", sourceID, "state=", state,"handle=",handle);
444  am_Error_e syncError(iter->second->asyncSetSourceState(handle, sourceID, state));
445  if (syncError)
446  {
447  removeHandle(handle);
448  logError(__METHOD_NAME__,"Error while calling asyncSetSourceState sourceID:",sourceID,"handle:",handle,"state:",state);
449  }
450  return(syncError);
451 }
452 
454 {
455  auto iter (mMapSinkInterface.find(sinkID));
456  if (iter == mMapSinkInterface.end())
457  {
458  logError(__METHOD_NAME__,"Could not find sink",sinkID);
459  return (E_NON_EXISTENT);
460  }
461 
462  if(handleExists(handle))
463  {
465  {
466  logInfo(__METHOD_NAME__,"Resending for handle",handle);
467  }
468  else
469  {
470  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
471  return(E_UNKNOWN);
472  }
473  }
474  else
475  {
476  auto handleData = std::make_shared<handleSinkSoundProperty>(iter->second,sinkID,soundProperty,mpDatabaseHandler);
477  handle = createHandle(handleData, H_SETSINKSOUNDPROPERTY);
478  }
479 
480  logInfo(__METHOD_NAME__,"sinkID=", sinkID, "soundProperty.Type=", soundProperty.type, "soundProperty.value=", soundProperty.value,"handle=",handle);
481  am_Error_e syncError(iter->second->asyncSetSinkSoundProperty(handle, sinkID, soundProperty));
482  if (syncError)
483  {
484  removeHandle(handle);
485  logError(__METHOD_NAME__,"Error while calling asyncSetSinkSoundProperty sinkID:",sinkID,"handle:",handle,"soundProperty:",soundProperty.type,soundProperty.value);
486  }
487  return(syncError);
488 }
489 
491 {
492  auto iter (mMapSourceInterface.find(sourceID));
493  if (iter == mMapSourceInterface.end())
494  {
495  logError(__METHOD_NAME__,"Could not find sourceID",sourceID);
496  return (E_NON_EXISTENT);
497  }
498 
499  if(handleExists(handle))
500  {
502  {
503  logInfo(__METHOD_NAME__,"Resending for handle",handle);
504  }
505  else
506  {
507  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
508  return(E_UNKNOWN);
509  }
510  }
511  else
512  {
513  auto handleData = std::make_shared<handleSourceSoundProperty>(iter->second,sourceID,soundProperty,mpDatabaseHandler);
514  handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTY);
515  }
516  logInfo(__METHOD_NAME__,"sourceID=", sourceID, "soundProperty.Type=", soundProperty.type, "soundProperty.value=", soundProperty.value,"handle=",handle);
517  am_Error_e syncError(iter->second->asyncSetSourceSoundProperty(handle, sourceID, soundProperty));
518  if (syncError)
519  {
520  removeHandle(handle);
521  logError(__METHOD_NAME__,"Error while calling asyncSetSourceSoundProperty sourceID:",sourceID,"handle:",handle,"soundProperty:",soundProperty.type,soundProperty.value);
522  }
523  return(syncError);
524 }
525 
526 am_Error_e CAmRoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sourceID_t sourceID)
527 {
528  auto iter (mMapSourceInterface.find(sourceID));
529  if (iter == mMapSourceInterface.end())
530  {
531  logError(__METHOD_NAME__,"Could not find sourceID",sourceID);
532  return (E_NON_EXISTENT);
533  }
534 
535  if(handleExists(handle))
536  {
538  {
539  logInfo(__METHOD_NAME__,"Resending for handle",handle);
540  }
541  else
542  {
543  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
544  return(E_UNKNOWN);
545  }
546  }
547  else
548  {
549  auto handleData = std::make_shared<handleSourceSoundProperties>(iter->second,sourceID,listSoundProperties,mpDatabaseHandler);
550  handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTIES);
551  }
552 
553  logInfo(__METHOD_NAME__,"sourceID=", sourceID);
554  am_Error_e syncError(iter->second->asyncSetSourceSoundProperties(handle, sourceID, listSoundProperties));
555  if (syncError)
556  {
557  removeHandle(handle);
558  logError(__METHOD_NAME__,"Error while calling asyncSetSourceSoundProperties sourceID:",sourceID,"handle:",handle);
559  }
560  return(syncError);
561 }
562 
563 am_Error_e CAmRoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sinkID_t sinkID)
564 {
565  auto iter (mMapSinkInterface.find(sinkID));
566  if (iter == mMapSinkInterface.end())
567  {
568  logError(__METHOD_NAME__,"Could not find sink",sinkID);
569  return (E_NON_EXISTENT);
570  }
571 
572  if(handleExists(handle))
573  {
575  {
576  logInfo(__METHOD_NAME__,"Resending for handle",handle);
577  }
578  else
579  {
580  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
581  return(E_UNKNOWN);
582  }
583  }
584  else
585  {
586  auto handleData = std::make_shared<handleSinkSoundProperties>(iter->second,sinkID,listSoundProperties,mpDatabaseHandler);
587  handle = createHandle(handleData, H_SETSINKSOUNDPROPERTIES);
588  }
589 
590  logInfo(__METHOD_NAME__,"sinkID=", sinkID,"handle=",handle);
591  am_Error_e syncError(iter->second->asyncSetSinkSoundProperties(handle, sinkID, listSoundProperties));
592  if (syncError)
593  {
594  removeHandle(handle);
595  logError(__METHOD_NAME__,"Error while calling asyncSetSinkSoundProperties sinkID:",sinkID,"handle:",handle);
596  }
597  return(syncError);
598 }
599 
600 am_Error_e CAmRoutingSender::asyncCrossFade(am_Handle_s& handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_CustomRampType_t rampType, const am_time_t time)
601 {
602  auto iter (mMapCrossfaderInterface.find(crossfaderID));
603  if (iter == mMapCrossfaderInterface.end())
604  {
605  logError(__METHOD_NAME__,"Could not find crossfaderID",crossfaderID);
606  return (E_NON_EXISTENT);
607  }
608 
609  if(handleExists(handle))
610  {
612  {
613  logInfo(__METHOD_NAME__,"Resending for handle",handle);
614  }
615  else
616  {
617  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
618  return(E_UNKNOWN);
619  }
620  }
621  else
622  {
623  auto handleData = std::make_shared<handleCrossFader>(iter->second,crossfaderID,hotSink,mpDatabaseHandler);
624  handle = createHandle(handleData, H_CROSSFADE);
625  }
626 
627  logInfo(__METHOD_NAME__,"hotSource=", hotSink, "crossfaderID=", crossfaderID, "rampType=", rampType, "rampTime=", time,"handle=",handle);
628  am_Error_e syncError(iter->second->asyncCrossFade(handle, crossfaderID, hotSink, rampType, time));
629  if (syncError)
630  {
631  removeHandle(handle);
632  }
633  return(syncError);
634 }
635 
637 {
638  logInfo(__METHOD_NAME__,"domainID=", domainID, "domainState=", domainState);
639  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
640  iter = mMapDomainInterface.find(domainID);
641  if (iter != mMapDomainInterface.end())
642  return (iter->second->setDomainState(domainID, domainState));
643  return (E_NON_EXISTENT);
644 }
645 
652 {
653  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
654  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
655  for (; iter < iterEnd; ++iter)
656  {
657  if ((*iter).busName.compare(domainData.busname) == 0)
658  {
659  mMapDomainInterface.insert(std::make_pair(domainData.domainID, (*iter).routingInterface));
660  return (E_OK);
661  }
662  }
663  logError(__PRETTY_FUNCTION__," Could not find busname for bus",domainData.busname);
664  return (E_UNKNOWN);
665 }
666 
673 {
674  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
675  iter = mMapDomainInterface.find(sourceData.domainID);
676  if (iter != mMapDomainInterface.end())
677  {
678  mMapSourceInterface.insert(std::make_pair(sourceData.sourceID, iter->second));
679  return (E_OK);
680  }
681  logError(__PRETTY_FUNCTION__," Could not find domainInterface for domainID",sourceData.domainID);
682  return (E_UNKNOWN);
683 }
684 
691 {
692  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
693  iter = mMapDomainInterface.find(sinkData.domainID);
694  if (iter != mMapDomainInterface.end())
695  {
696  mMapSinkInterface.insert(std::make_pair(sinkData.sinkID, iter->second));
697  return (E_OK);
698  }
699  logError(__PRETTY_FUNCTION__,"Could not find domainInterface for domainID",sinkData.domainID);
700  return (E_UNKNOWN);
701 }
702 
709 {
710  DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
711  iter = mMapSourceInterface.find(crossfaderData.sourceID);
712  if (iter != mMapSourceInterface.end())
713  {
714  mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID, iter->second));
715  return (E_OK);
716  }
717  logError(__PRETTY_FUNCTION__," Could not find sourceInterface for source",crossfaderData.sourceID);
718  return (E_UNKNOWN);
719 }
720 
726 {
727  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
728  iter = mMapDomainInterface.find(domainID);
729  if (iter != mMapDomainInterface.end())
730  {
731  mMapDomainInterface.erase(iter);
732  return (E_OK);
733  }
734 
735  return (E_NON_EXISTENT);
736 }
737 
743 {
744  SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
745  iter = mMapSourceInterface.find(sourceID);
746  if (iter != mMapSourceInterface.end())
747  {
748  mMapSourceInterface.erase(iter);
749  return (E_OK);
750  }
751 
752  return (E_NON_EXISTENT);
753 }
754 
760 {
761  SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
762  iter = mMapSinkInterface.find(sinkID);
763  if (iter != mMapSinkInterface.end())
764  {
765  mMapSinkInterface.erase(iter);
766  return (E_OK);
767  }
768 
769  return (E_NON_EXISTENT);
770 }
771 
777 {
778  CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
779  iter = mMapCrossfaderInterface.find(crossfaderID);
780  if (iter != mMapCrossfaderInterface.end())
781  {
782  mMapCrossfaderInterface.erase(iter);
783  return (E_OK);
784  }
785 
786  return (E_NON_EXISTENT);
787 }
788 
795 {
796  if (mlistActiveHandles.erase(handle))
797  {
798  return (E_OK);
799  }
800  logError(__METHOD_NAME__,"Could not remove handle",handle.handle);
801  return (E_NON_EXISTENT);
802 }
803 
804 am_Error_e CAmRoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
805 {
806  listHandles.clear();
807  HandlesMap::const_iterator it = mlistActiveHandles.begin();
808  for (; it != mlistActiveHandles.end(); ++it)
809  {
810  listHandles.push_back(it->first);
811  }
812  return (E_OK);
813 }
814 
821 am_Handle_s CAmRoutingSender::createHandle(std::shared_ptr<handleDataBase> handleData, const am_Handle_e type)
822 {
823  am_Handle_s handle;
824  handle.handleType = type;
825 
826  for (int checkOverflow=0;checkOverflow<1024;checkOverflow++)
827  {
828  if (++mHandleCount>=1024) //defined by 10 bit (out if structure!)
829  {
830  mHandleCount=1;
831  }
832  handle.handle = mHandleCount;
833 
834  if ( mlistActiveHandles.find(handle) == mlistActiveHandles.end() )
835  {
836  mlistActiveHandles.insert(std::make_pair(handle, handleData));
837  if (mlistActiveHandles.size()>100)
838  {
839  logWarning(__METHOD_NAME__,"too many open handles, number of handles: ", mlistActiveHandles.size());
840  }
841  logInfo(__METHOD_NAME__,handle.handle, handle.handleType);
842  return (handle);
843  }
844  }
845 
846  logError(__METHOD_NAME__,"could not create new handle, all handles in use!");
847  handle.handle=0;
848 
849  return(handle);
850 }
851 
853 {
854  mpRoutingReceiver->waitOnStartup(false);
855 
856  //create a list of handles
857  std::vector<uint16_t> listStartupHandles;
858  for (size_t i = 0; i < mListInterfaces.size(); i++)
859  {
860  listStartupHandles.push_back(mpRoutingReceiver->getStartupHandle());
861  }
862 
863  //set the receiver ready to wait for replies
864  mpRoutingReceiver->waitOnStartup(true);
865 
866  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
867  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
868  std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
869  for (; iter < iterEnd; ++iter)
870  {
871  (*iter).routingInterface->setRoutingReady(*(handleIter++));
872  }
873 }
874 
876 {
877  mpRoutingReceiver->waitOnRundown(false);
878  //create a list of handles
879  std::vector<uint16_t> listStartupHandles;
880  for (size_t i = 0; i < mListInterfaces.size(); i++)
881  {
882  listStartupHandles.push_back(mpRoutingReceiver->getRundownHandle());
883  }
884 
885  //set the receiver ready to wait for replies
886  mpRoutingReceiver->waitOnRundown(true);
887 
888  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
889  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
890  std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
891  for (; iter < iterEnd; ++iter)
892  {
893  (*iter).routingInterface->setRoutingRundown(*(handleIter++));
894  }
895 }
896 
897 am_Error_e CAmRoutingSender::asyncSetVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes)
898 {
899  IAmRoutingSend* pRoutingInterface(NULL);
900  if (listVolumes.empty())
901  return (E_NOT_POSSIBLE);
902 
903  //we need an interface so lets get either the sink or source ID from the first entry in the listVolumes
904  if (listVolumes[0].volumeType==VT_SINK)
905  {
906  am_sinkID_t sinkID=listVolumes[0].volumeID.sink;
907  SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
908  iter = mMapSinkInterface.find(sinkID);
909  if(iter!=mMapSinkInterface.end())
910  pRoutingInterface=iter->second;
911  else
912  return(E_NON_EXISTENT);
913  }
914 
915  else if (listVolumes[0].volumeType==VT_SOURCE)
916  {
917  am_sourceID_t sourceID=listVolumes[0].volumeID.source;
918  SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
919  iter = mMapSourceInterface.find(sourceID);
920  if (iter!=mMapSourceInterface.end())
921  pRoutingInterface=iter->second;
922  else
923  return(E_NON_EXISTENT);
924  }
925  else
926  return (E_NON_EXISTENT);
927 
928  auto handleData = std::make_shared<handleSetVolumes>(pRoutingInterface,listVolumes,mpDatabaseHandler);
929  handle = createHandle(handleData, H_SETVOLUMES);
930 
931  logInfo(__METHOD_NAME__, "handle=", handle);
932  am_Error_e syncError(pRoutingInterface->asyncSetVolumes(handle, listVolumes));
933  if (syncError)
934  {
935  removeHandle(handle);
936  }
937  return(syncError);
938 
939 }
940 
942 {
943  auto iter (mMapSinkInterface.find(sinkID));
944  if (iter == mMapSinkInterface.end())
945  {
946  logError(__METHOD_NAME__,"Could not find sink",sinkID);
947  return (E_NON_EXISTENT);
948  }
949 
950  if(handleExists(handle))
951  {
953  {
954  logInfo(__METHOD_NAME__,"Resending for handle",handle);
955  }
956  else
957  {
958  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
959  return(E_UNKNOWN);
960  }
961  }
962  else
963  {
964  auto handleData = std::make_shared<handleSetSinkNotificationConfiguration>(iter->second,sinkID,notificationConfiguration,mpDatabaseHandler);
965  handle = createHandle(handleData, H_SETSINKNOTIFICATION);
966  }
967 
968  logInfo(__METHOD_NAME__,"sinkID=",sinkID,"notificationConfiguration.type=",notificationConfiguration.type,"notificationConfiguration.status",notificationConfiguration.status,"notificationConfiguration.parameter",notificationConfiguration.parameter);
969  am_Error_e syncError(iter->second->asyncSetSinkNotificationConfiguration(handle, sinkID, notificationConfiguration));
970  if (syncError)
971  {
972  removeHandle(handle);
973  logError(__METHOD_NAME__,"Error while calling asyncSetSinkNotificationConfiguration sinkID:",sinkID,"handle:",handle);
974  }
975  return(syncError);
976 }
977 
979 {
980  auto iter (mMapSourceInterface.find(sourceID));
981  if (iter == mMapSourceInterface.end())
982  {
983  logError(__METHOD_NAME__,"Could not find sourceID",sourceID);
984  return (E_NON_EXISTENT);
985  }
986 
987  if(handleExists(handle))
988  {
990  {
991  logInfo(__METHOD_NAME__,"Resending for handle",handle);
992  }
993  else
994  {
995  logError(__METHOD_NAME__,"Handle exists but wrong type",handle);
996  return(E_UNKNOWN);
997  }
998  }
999  else
1000  {
1001  auto handleData = std::make_shared<handleSetSourceNotificationConfiguration>(iter->second,sourceID,notificationConfiguration,mpDatabaseHandler);
1002  handle = createHandle(handleData, H_SETSOURCENOTIFICATION);
1003  }
1004 
1005  logInfo(__METHOD_NAME__,"sourceID=",sourceID,"notificationConfiguration.type=",notificationConfiguration.type,"notificationConfiguration.status",notificationConfiguration.status,"notificationConfiguration.parameter",notificationConfiguration.parameter);
1006  am_Error_e syncError(iter->second->asyncSetSourceNotificationConfiguration(handle, sourceID, notificationConfiguration));
1007  if (syncError)
1008  {
1009  removeHandle(handle);
1010  logError(__METHOD_NAME__,"Error while calling asyncSetSourceNotificationConfiguration sourceID:",sourceID,"handle:",handle);
1011  }
1012  return(syncError);
1013 }
1014 
1015 void CAmRoutingSender::unloadLibraries(void)
1016 {
1017  std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
1018  for (; iterator < mListLibraryHandles.end(); ++iterator)
1019  {
1020  dlclose(*iterator);
1021  }
1022  mListLibraryHandles.clear();
1023 }
1024 
1025 am_Error_e CAmRoutingSender::getListPlugins(std::vector<std::string>& interfaces) const
1026 {
1027  std::vector<InterfaceNamePairs>::const_iterator it = mListInterfaces.begin();
1028  for (; it != mListInterfaces.end(); ++it)
1029  {
1030  interfaces.push_back(it->busName);
1031  }
1032  return (E_OK);
1033 }
1034 
1035 void CAmRoutingSender::getInterfaceVersion(std::string & version) const
1036 {
1037  version = RoutingVersion;
1038 }
1039 am_Error_e CAmRoutingSender::resyncConnectionState(const am_domainID_t domainID,std::vector<am_Connection_s>& listOfExistingConnections)
1040 {
1041  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
1042  iter = mMapDomainInterface.find(domainID);
1043  if (iter != mMapDomainInterface.end())
1044  return (iter->second->resyncConnectionState(domainID, listOfExistingConnections));
1045  return (E_NON_EXISTENT);
1046 }
1047 
1049 {
1050  auto it(mlistActiveHandles.find(handle));
1051  if (it!=mlistActiveHandles.end())
1052  {
1053  am_Error_e error(it->second->writeDataToDatabase());
1054  mlistActiveHandles.erase(handle);
1055  return (error);
1056  }
1057  logError(__METHOD_NAME__,"could not find handle data for handle",handle);
1058  return (am_Error_e::E_NON_EXISTENT);
1059 }
1060 
1062 {
1063  auto it(mlistActiveHandles.find(handle));
1064  if (it!=mlistActiveHandles.end())
1065  {
1066  handleVolumeBase* basePtr = static_cast<handleVolumeBase*>(it->second.get());
1067  if (basePtr->returnVolume()!=volume)
1068  {
1069  logError(__METHOD_NAME__,"volume returned for handle does not match: ",volume,"expected:",basePtr->returnVolume());
1070  }
1071  return;
1072  }
1073  logError(__METHOD_NAME__,"could not find handle data for handle",handle);
1074 }
1075 
1077 {
1078  auto iter(mlistActiveHandles.find(handle));
1079  if (iter!=mlistActiveHandles.end())
1080  {
1081  return (true);
1082  }
1083  return (false);
1084 }
1085 
1087 {
1088  return (mpDatabaseHandler->changeSinkSoundPropertyDB(mSoundProperty,mSinkID));
1089 }
1090 
1092 {
1093  std::vector<am_SoundProperty_s>::const_iterator it = mlistSoundProperties.begin();
1094  for (; it != mlistSoundProperties.end(); ++it)
1095  {
1096  mpDatabaseHandler->changeSinkSoundPropertyDB(*it, mSinkID);
1097  }
1098  return (am_Error_e::E_OK);
1099 }
1100 
1102 {
1103  return (mpDatabaseHandler->changeSourceSoundPropertyDB(mSoundProperty,mSourceID));
1104 }
1105 
1107 {
1108  std::vector<am_SoundProperty_s>::const_iterator it = mlistSoundProperties.begin();
1109  for (; it != mlistSoundProperties.end(); ++it)
1110  {
1111  mpDatabaseHandler->changeSourceSoundPropertyDB(*it, mSourceID);
1112  }
1113  return (am_Error_e::E_OK);
1114 }
1115 
1117 {
1118  return (mpDatabaseHandler->changeSourceState(mSourceID,mSourceState));
1119 }
1120 
1122 {
1123  return (mpDatabaseHandler->changeSourceVolume(mSourceID,returnVolume()));
1124 }
1125 
1127 {
1128  return (mpDatabaseHandler->changeSinkVolume(mSinkID,returnVolume()));
1129 }
1130 
1132 {
1133  return (mpDatabaseHandler->changeCrossFaderHotSink(mCrossfaderID, mHotSink));
1134 }
1135 
1137 {
1138  mConnectionPending = false;
1139  return (mpDatabaseHandler->changeConnectionFinal(mConnectionID));
1140 }
1141 
1143 {
1144  return E_OK;
1145 }
1146 
1148 {
1149  std::vector<am_Volumes_s>::const_iterator iterator (mlistVolumes.begin());
1150 
1151  for (;iterator!=mlistVolumes.end();++iterator)
1152  {
1153  if (iterator->volumeType==VT_SINK)
1154  {
1155  return (mpDatabaseHandler->changeSinkVolume(iterator->volumeID.sink,iterator->volume));
1156  }
1157  else if (iterator->volumeType==VT_SOURCE)
1158  {
1159  return (mpDatabaseHandler->changeSourceVolume(iterator->volumeID.source,iterator->volume));
1160  }
1161  }
1162  return (am_Error_e::E_WRONG_FORMAT);
1163 }
1164 
1166 {
1167  return (mpDatabaseHandler->changeSinkNotificationConfigurationDB(mSinkID,mNotificationConfiguration));
1168 }
1169 
1171 {
1172  return (mpDatabaseHandler->changeSourceNotificationConfigurationDB(mSourceID,mNotificationConfiguration));
1173 }
1174 
1176 {
1177  ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
1178  iter = mMapConnectionInterface.find(connectionID);
1179  if (iter != mMapConnectionInterface.end())
1180  {
1181  mMapConnectionInterface.erase(iter);
1182  return (E_OK);
1183  }
1184  return (E_UNKNOWN);
1185 }
1186 
1188 {
1189  if (mConnectionPending)
1190  {
1191  mpDatabaseHandler->removeConnection(mConnectionID);
1192  }
1193 }
1194 
1196 {
1197  mpDatabaseHandler->removeConnection(mConnectionID);
1198 }
1199 
1200 }
1201 
am_Error_e writeDataToDatabase()
function to write the handle data to the database
std::string busname
the busname.
SPDX license identifier: MPL-2.0.
This error is returned in case a connect is issued with a connectionFormat that cannot be selected fo...
std::function< void(const am_sourceID_t, const bool)> dboRemovedSource
am_Error_e asyncAbort(const am_Handle_s &handle)
uint16_t am_connectionID_t
a connection ID
std::function< void(const am_Sink_s &)> dboNewSink
am_timeSync_t delay
the delay of the conneciton
void logWarning(T value, TArgs...args)
logs given values with warninglevel with the default context
A Common-API wrapper class, which loads the common-api runtime and instantiates all necessary objects...
the desired object is non existent
virtual am_Error_e changeCrossFaderHotSink(const am_crossfaderID_t crossfaderID, const am_HotSink_e hotsink)=0
am_CustomNotificationType_t type
The notification type of the notification.
am_Error_e
the errors of the audiomanager.
This struct holds information about the configuration for notifications.
am_Error_e writeDataToDatabase()
function to write the handle data to the database
void logInfo(T value, TArgs...args)
logs given values with infolevel with the default context
am_Error_e getListHandles(std::vector< am_Handle_s > &listHandles) const
std::function< void(const am_sinkID_t, const bool)> dboRemovedSink
This struct describes the attribiutes of a sink.
am_Error_e writeDataToDatabase()
function to write the handle data to the database
This class implements everything from Audiomanager -> RoutingAdapter There are two rules that have to...
Definition: IAmRouting.h:357
virtual am_Error_e changeSourceState(const am_sourceID_t sourceID, const am_SourceState_e sourceState)=0
void getInterfaceVersion(std::string &version) const
am_Error_e asyncCrossFade(am_Handle_s &handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_CustomRampType_t rampType, const am_time_t time)
am_sinkID_t sinkID
This is the ID of the sink, it is unique in the system.
void checkVolume(const am_Handle_s handle, const am_volume_t volume)
This struct describes the attribiutes of a domain.
void waitOnRundown(bool rundown)
tells the RoutingReceiver to start waiting for all handles to be confirmed
am_Error_e addSinkLookup(const am_Sink_s &sinkData)
am_Error_e writeDataToDatabase()
function to write the handle data to the database
std::function< void(const am_crossfaderID_t)> dboRemoveCrossfader
virtual void getInterfaceVersion(std::string &version) const =0
This function returns the version of the interface.
uint16_t am_crossfaderID_t
a crossfader ID
uint16_t am_CustomConnectionFormat_t
This type classifies the format in which data is exchanged within a connection.
SPDX license identifier: MPL-2.0.
am_Error_e writeDataToDatabase()
function to write the handle data to the database
am_crossfaderID_t crossfaderID
This is the ID of the crossfader, it is unique in the system.
am_Error_e asyncSetSinkSoundProperty(am_Handle_s &handle, const am_sinkID_t sinkID, const am_SoundProperty_s &soundProperty)
am_Error_e setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
am_Error_e addCrossfaderLookup(const am_Crossfader_s &crossfaderData)
am_Error_e asyncDisconnect(am_Handle_s &handle, const am_connectionID_t connectionID)
am_Error_e addDomainLookup(const am_Domain_s &domainData)
SPDX license identifier: MPL-2.0.
std::function< void(const am_Source_s &)> dboNewSource
Implements the Receiving side of the RoutingPlugins.
std::function< void(const am_domainID_t)> dboRemoveDomain
the following type is a sink
am_CustomConnectionFormat_t connectionFormat
the used connectionformat
am_Error_e writeDataToDatabase()
function to write the handle data to the database
virtual am_Error_e changeConnectionFinal(const am_connectionID_t connectionID)=0
am_sourceID_t sourceID
The sourceID of the crossfader source.
am_Error_e removeCrossfaderLookup(const am_crossfaderID_t crossfaderID)
am_Error_e asyncSetSourceVolume(am_Handle_s &handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time)
am_Error_e asyncSetSourceSoundProperty(am_Handle_s &handle, const am_sourceID_t sourceID, const am_SoundProperty_s &soundProperty)
SPDX license identifier: MPL-2.0.
am_domainID_t domainID
The domainID is the domain the source belongs to.
#define __METHOD_NAME__
the following type is a source
am_Error_e addSourceLookup(const am_Source_s &sourceData)
am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector< am_Connection_s > &listOfExistingConnections)
am_Error_e asyncSetSourceSoundProperties(am_Handle_s &handle, const std::vector< am_SoundProperty_s > &listSoundProperties, const am_sourceID_t sourceID)
a handle is used for asynchronous operations and is uniquely assigned for each of this operations ...
am_Error_e writeDataToDatabase()
function to write the handle data to the database
am_Error_e writeDataToDatabase()
function to write the handle data to the database
IAmRoutingSend * routingInterface
pointer to the routingInterface
am_Error_e writeDataToDatabase()
function to write the handle data to the database
uint16_t am_sourceID_t
a source ID
am_Error_e asyncSetSinkSoundProperties(am_Handle_s &handle, const std::vector< am_SoundProperty_s > &listSoundProperties, const am_sinkID_t sinkID)
struct describing the sound property
am_Error_e asyncSetSourceState(am_Handle_s &handle, const am_sourceID_t sourceID, const am_SourceState_e state)
am_sourceID_t sourceID
the source the audio flows from
virtual am_Error_e removeConnection(const am_connectionID_t connectionID)=0
uint16_t getStartupHandle()
returns a startup handle
am_NotificationStatus_e status
The Notification status.
virtual am_Error_e returnBusName(std::string &BusName) const =0
this method is used to retrieve the busname during startup of the plugin.
This class handles and abstracts the database.
SPDX license identifier: MPL-2.0.
am_Error_e writeDataToDatabase()
function to write the handle data to the database
am_HotSink_e
describes the active sink of a crossfader.
std::function< void(const am_Domain_s &)> dboNewDomain
int16_t am_volume_t
The unit is 0.1 db steps,The smallest value -3000 (=AM_MUTE).
This struct describes the attribiutes of a crossfader.
am_Error_e asyncSetSinkVolume(am_Handle_s &handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time)
am_sourceID_t sourceID
This is the ID of the source, it is unique in the system.
am_CustomSoundPropertyType_t type
the type of the property - a project specific enum
bool handleExists(const am_Handle_s handle)
returns true if the handle exists
am_Handle_e handleType
the handletype
am_Error_e getListPlugins(std::vector< std::string > &interfaces) const
uint16_t getRundownHandle()
returns a rundown handle
am_Error_e writeToDatabaseAndRemove(const am_Handle_s handle)
write data to Database and remove handle
the desired action is not possible
virtual am_Error_e changeSinkSoundPropertyDB(const am_SoundProperty_s &soundProperty, const am_sinkID_t sinkID)=0
am_connectionID_t connectionID
the assigned ID
am_domainID_t domainID
the domain ID
virtual am_Error_e changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s notificationConfiguration)=0
am_Error_e startupInterfaces(CAmRoutingReceiver *iRoutingReceiver)
uint16_t handle
the handle as value
void logError(T value, TArgs...args)
logs given values with errorlevel with the default context
am_Error_e removeHandle(const am_Handle_s &handle)
removes a handle from the list
uint16_t am_time_t
time in ms!
#define RoutingVersion
Definition: IAmRouting.h:38
am_Handle_e
This enumeration is used to define the type of the action that is correlated to a handle...
am_Error_e writeDataToDatabase()
function to write the handle data to the database
am_Error_e removeSinkLookup(const am_sinkID_t sinkID)
uint16_t am_domainID_t
a domain ID
no error - positive reply
virtual am_Error_e changeSourceVolume(const am_sourceID_t sourceID, const am_volume_t volume)=0
int16_t value
the actual value of the property
am_Error_e writeDataToDatabase()
function to write the handle data to the database
am_Error_e removeSourceLookup(const am_sourceID_t sourceID)
CAmRoutingSender(const std::vector< std::string > &listOfPluginDirectories, IAmDatabaseHandler *databaseHandler)
am_Error_e asyncSetVolumes(am_Handle_s &handle, const std::vector< am_Volumes_s > &listVolumes)
void waitOnStartup(bool startup)
tells the RoutingReceiver to start waiting for all handles to be confirmed
This struct describes the attribiutes of a source.
virtual am_Error_e changeSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s notificationConfiguration)=0
uint16_t am_CustomRampType_t
The given ramp types here are just examples.
virtual am_Error_e enterConnectionDB(const am_Connection_s &connection, am_connectionID_t &connectionID)=0
std::function< void(const am_Crossfader_s &)> dboNewCrossfader
am_Error_e writeDataToDatabase()
function to write the handle data to the database
uint16_t am_sinkID_t
a sink ID
am_Error_e asyncSetSinkNotificationConfiguration(am_Handle_s &handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s &notificationConfiguration)
int16_t parameter
This gives additional information to the notification status.
am_domainID_t domainID
The domainID is the domain the sink belongs to.
am_SourceState_e
The source state reflects the state of the source.
am_Error_e removeConnectionLookup(const am_connectionID_t connectionID)
virtual am_Error_e changeSourceSoundPropertyDB(const am_SoundProperty_s &soundProperty, const am_sourceID_t sourceID)=0
am_Error_e asyncConnect(am_Handle_s &handle, am_connectionID_t &connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat)
am_Error_e asyncSetSourceNotificationConfiguration(am_Handle_s &handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s &notificationConfiguration)
am_sinkID_t sinkID
the sink the audio flows to
< is used to pair interfaces with busnames
am_Error_e removeDomainLookup(const am_domainID_t domainID)
virtual am_Error_e changeSinkVolume(const am_sinkID_t sinkID, const am_volume_t volume)=0