AudioManager  7.5.11
Native Application Runtime Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 CAmRoutingSender::CAmRoutingSender(const std::vector<std::string>& listOfPluginDirectories, IAmDatabaseHandler* databaseHandler) :
47  mHandleCount(0), //
48  mlistActiveHandles(), //
49  mListInterfaces(), //
50  mMapConnectionInterface(), //
51  mMapCrossfaderInterface(), //
52  mMapDomainInterface(), //
53  mMapSinkInterface(), //
54  mMapSourceInterface(), //
55  mpRoutingReceiver(), //
56  mpDatabaseHandler(databaseHandler)
57 {
58 
59  if (listOfPluginDirectories.empty())
60  {
61  logError(__func__,"List of routingplugins is empty");
62  }
63 
64  std::vector<std::string> sharedLibraryNameList;
65  std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
66  std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
67 
68  // search communicator plugins in configured directories
69  for (; dirIter < dirIterEnd; ++dirIter)
70  {
71  const char* directoryName = dirIter->c_str();
72  logInfo("Searching for HookPlugins in", directoryName);
73  DIR *directory = opendir(directoryName);
74 
75  if (!directory)
76  {
77  logError("RoutingSender::RoutingSender Error opening directory: ", directoryName);
78  continue;
79  }
80 
81  // iterate content of directory
82  struct dirent *itemInDirectory = 0;
83  while ((itemInDirectory = readdir(directory)))
84  {
85  unsigned char entryType = itemInDirectory->d_type;
86  std::string entryName = itemInDirectory->d_name;
87  std::string fullName = *dirIter + "/" + entryName;
88 
89  bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
90  bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
91 
92  // Handle cases where readdir() could not determine the file type
93  if (entryType == DT_UNKNOWN) {
94  struct stat buf;
95 
96  if (stat(fullName.c_str(), &buf)) {
97  logInfo(__PRETTY_FUNCTION__,"Failed to stat file: ", entryName, errno);
98  continue;
99  }
100 
101  regularFile = S_ISREG(buf.st_mode);
102  }
103 
104  if (regularFile && sharedLibExtension)
105  {
106  logInfo("RoutingSender::RoutingSender adding file: ", entryName);
107  std::string name(directoryName);
108  sharedLibraryNameList.push_back(name + "/" + entryName);
109  }
110  else
111  {
112  logInfo("RoutingSender::RoutingSender PluginSearch ignoring file :", entryName);
113  }
114  }
115 
116  closedir(directory);
117  }
118 
119  // iterate all communicator plugins and start them
120  std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
121  std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
122 
123  for (; iter != iterEnd; ++iter)
124  {
125  logInfo("RoutingSender::RoutingSender try loading: ", *iter);
126 
127  IAmRoutingSend* (*createFunc)();
128  void* tempLibHandle = NULL;
129  createFunc = getCreateFunction<IAmRoutingSend*()>(*iter, tempLibHandle);
130 
131  if (!createFunc)
132  {
133  logError("RoutingSender::RoutingSender Entry point of RoutingPlugin not found");
134  continue;
135  }
136 
137  IAmRoutingSend* router = createFunc();
138 
139  if (!router)
140  {
141  logError("RoutingSender::RoutingSender RoutingPlugin initialization failed. Entry Function not callable");
142  dlclose(tempLibHandle);
143  continue;
144  }
145 
146  InterfaceNamePairs routerInterface;
147  routerInterface.routingInterface = router;
148 
149  //check libversion
150  std::string version, cVersion(RoutingVersion);
151  router->getInterfaceVersion(version);
152  uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion;
153  std::istringstream(version.substr(0, 1)) >> majorVersion;
154  std::istringstream(version.substr(2, 1)) >> minorVersion;
155  std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion;
156  std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion;
157 
158 
159 
160  if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion)))
161  {
162  logError("Routing initialization failed. Version of Interface to old");
163  dlclose(tempLibHandle);
164  continue;
165  }
166 
167  //here, the busname is saved together with the interface. Later The domains will register with the name and sinks, sources etc with the domain....
168  router->returnBusName(routerInterface.busName);
169  assert(!routerInterface.busName.empty());
170  mListInterfaces.push_back(routerInterface);
171  mListLibraryHandles.push_back(tempLibHandle);
172  }
173 }
174 
176 {
177  //unloadLibraries();
178  HandlesMap::iterator it = mlistActiveHandles.begin();
179 
180  //every open handle is assumed to be an error...
181  for (; it != mlistActiveHandles.end(); ++it)
182  {
183  logError(__func__,"The action for the handle",it->first,"is still open");
184  }
185 }
186 
188 {
189  mpRoutingReceiver = iRoutingReceiver;
190  am_Error_e returnError = E_OK;
191 
192  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
193  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
194  for (; iter < iterEnd; ++iter)
195  {
196  am_Error_e error = (*iter).routingInterface->startupInterface(iRoutingReceiver);
197  if (error != E_OK)
198  {
199  returnError = error;
200  }
201  }
202  return (returnError);
203 }
204 
206 {
207  auto iter (mlistActiveHandles.find(handle));
208  if (iter == mlistActiveHandles.end())
209  {
210  logError(__func__,"Could not find handle",handle);
211  return (E_NON_EXISTENT);
212  }
213  logInfo(__func__," handle", handle);
214  return (iter->second->returnInterface()->asyncAbort(handle));
215 }
216 
217 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)
218 {
219  auto iter (mMapSinkInterface.find(sinkID));
220  if (iter == mMapSinkInterface.end())
221  {
222  logError(__func__,"Could not find sink",sinkID);
223  return (E_NON_EXISTENT);
224  }
225 
226  if(handleExists(handle))
227  {
229  {
230  logInfo(__func__,"Resending for handle",handle);
231  }
232  else
233  {
234  logError(__func__,"Handle exists but wrong type",handle);
235  return(E_UNKNOWN);
236  }
237  }
238  else
239  {
240 
241  am_Connection_s tempConnection;
242  tempConnection.sinkID = sinkID;
243  tempConnection.sourceID = sourceID;
244  tempConnection.connectionFormat = connectionFormat;
245  tempConnection.connectionID = 0;
246  tempConnection.delay=-1;
247 
248  am_Error_e connError(mpDatabaseHandler->enterConnectionDB(tempConnection, connectionID));
249  if (connError)
250  {
251  return(connError);
252  }
253  mMapConnectionInterface.insert(std::make_pair(connectionID, iter->second));
254  auto handleData = std::make_shared<handleConnect>(iter->second,connectionID,mpDatabaseHandler);
255  handle = createHandle(handleData, am_Handle_e::H_CONNECT);
256  }
257 
258  logInfo(__func__,"connectionID=",connectionID,"connectionFormat=", connectionFormat, "sourceID=", sourceID, "sinkID=", sinkID,"handle=",handle);
259  am_Error_e syncError(iter->second->asyncConnect(handle, connectionID, sourceID, sinkID, connectionFormat));
260  if (syncError)
261  {
262  removeHandle(handle);
263  logError(__func__,"Error while calling connect connectionID:",connectionID,"sourceID:",sourceID,"sinkID:",sinkID,"connectionFormat:",connectionFormat,"handle",handle);
264  mpDatabaseHandler->removeConnection(connectionID);
265  }
266  return(syncError);
267 }
268 
270 {
271  auto iter(mMapConnectionInterface.find(connectionID));
272  if (iter == mMapConnectionInterface.end())
273  {
274  logError(__func__,"Could not find connection",connectionID);
275  return (E_NON_EXISTENT);
276  }
277 
278  if(handleExists(handle))
279  {
281  {
282  logInfo(__func__,"Resending for handle",handle);
283  }
284  else
285  {
286  logError(__func__,"Handle exists but wrong type",handle);
287  return(E_UNKNOWN);
288  }
289  }
290  else
291  {
292  auto handleData = std::make_shared<handleDisconnect>(iter->second,connectionID,mpDatabaseHandler,this);
293  handle = createHandle(handleData, am_Handle_e::H_DISCONNECT);
294  }
295 
296  logInfo(__func__,"connectionID=", connectionID, "handle=",handle);
297  am_Error_e syncError(iter->second->asyncDisconnect(handle, connectionID));
298  if (syncError)
299  {
300  removeHandle(handle);
301  logError(__func__,"Error while calling disconnect connectionID:",connectionID,"handle",handle);
302  }
303  return(syncError);
304 }
305 
307 {
308  auto iter (mMapSinkInterface.find(sinkID));
309  if (iter == mMapSinkInterface.end())
310  {
311  logError(__func__,"Could not find sink",sinkID);
312  return (E_NON_EXISTENT);
313  }
314 
315  if(handleExists(handle))
316  {
318  {
319  logInfo(__func__,"Resending for handle",handle);
320  }
321  else
322  {
323  logError(__func__,"Handle exists but wrong type",handle);
324  return(E_UNKNOWN);
325  }
326  }
327  else
328  {
329  auto handleData = std::make_shared<handleSinkVolume>(iter->second,sinkID,mpDatabaseHandler,volume);
330  handle = createHandle(handleData, H_SETSINKVOLUME);
331  }
332 
333  logInfo(__func__,"sinkID=", sinkID, "volume=", volume, "ramp=", ramp, "time=", time,"handle=",handle);
334  am_Error_e syncError(iter->second->asyncSetSinkVolume(handle, sinkID, volume, ramp, time));
335  if (syncError)
336  {
337  removeHandle(handle);
338  logError(__func__,"Error while calling asyncSetSinkVolume sinkID:",sinkID,"handle:",handle,"volume:",volume,"ramp:",ramp,"time:",time);
339  }
340  return(syncError);
341 }
342 
344 {
345  auto iter (mMapSourceInterface.find(sourceID));
346  if (iter == mMapSourceInterface.end())
347  {
348  logError(__func__,"Could not find sourceID",sourceID);
349  return (E_NON_EXISTENT);
350  }
351 
352  if(handleExists(handle))
353  {
355  {
356  logInfo(__func__,"Resending for handle",handle);
357  }
358  else
359  {
360  logError(__func__,"Handle exists but wrong type",handle);
361  return(E_UNKNOWN);
362  }
363  }
364  else
365  {
366  auto handleData = std::make_shared<handleSourceVolume>(iter->second,sourceID,mpDatabaseHandler,volume);
367  handle = createHandle(handleData, H_SETSOURCEVOLUME);
368  }
369 
370  logInfo(__func__,"sourceID=", sourceID,"volume=", volume, "ramp=", ramp, "time=", time,"handle=",handle);
371  am_Error_e syncError(iter->second->asyncSetSourceVolume(handle, sourceID, volume, ramp, time));
372  if (syncError)
373  {
374  removeHandle(handle);
375  logError(__func__,"Error while calling asyncSetSourceVolume sourceID:",sourceID,"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(__func__,"Could not find sourceID",sourceID);
386  return (E_NON_EXISTENT);
387  }
388 
389  if(handleExists(handle))
390  {
392  {
393  logInfo(__func__,"Resending for handle",handle);
394  }
395  else
396  {
397  logError(__func__,"Handle exists but wrong type",handle);
398  return(E_UNKNOWN);
399  }
400  }
401  else
402  {
403  auto handleData = std::make_shared<handleSourceState>(iter->second,sourceID,state,mpDatabaseHandler);
404  handle = createHandle(handleData, H_SETSOURCESTATE);
405  }
406  logInfo(__func__,"sourceID=", sourceID, "state=", state,"handle=",handle);
407  am_Error_e syncError(iter->second->asyncSetSourceState(handle, sourceID, state));
408  if (syncError)
409  {
410  removeHandle(handle);
411  logError(__func__,"Error while calling asyncSetSourceState sourceID:",sourceID,"handle:",handle,"state:",state);
412  }
413  return(syncError);
414 }
415 
417 {
418  auto iter (mMapSinkInterface.find(sinkID));
419  if (iter == mMapSinkInterface.end())
420  {
421  logError(__func__,"Could not find sink",sinkID);
422  return (E_NON_EXISTENT);
423  }
424 
425  if(handleExists(handle))
426  {
428  {
429  logInfo(__func__,"Resending for handle",handle);
430  }
431  else
432  {
433  logError(__func__,"Handle exists but wrong type",handle);
434  return(E_UNKNOWN);
435  }
436  }
437  else
438  {
439  auto handleData = std::make_shared<handleSinkSoundProperty>(iter->second,sinkID,soundProperty,mpDatabaseHandler);
440  handle = createHandle(handleData, H_SETSINKSOUNDPROPERTY);
441  }
442 
443  logInfo(__func__,"sinkID=", sinkID, "soundProperty.Type=", soundProperty.type, "soundProperty.value=", soundProperty.value,"handle=",handle);
444  am_Error_e syncError(iter->second->asyncSetSinkSoundProperty(handle, sinkID, soundProperty));
445  if (syncError)
446  {
447  removeHandle(handle);
448  logError(__func__,"Error while calling asyncSetSinkSoundProperty sinkID:",sinkID,"handle:",handle,"soundProperty:",soundProperty.type,soundProperty.value);
449  }
450  return(syncError);
451 }
452 
454 {
455  auto iter (mMapSourceInterface.find(sourceID));
456  if (iter == mMapSourceInterface.end())
457  {
458  logError(__func__,"Could not find sourceID",sourceID);
459  return (E_NON_EXISTENT);
460  }
461 
462  if(handleExists(handle))
463  {
465  {
466  logInfo(__func__,"Resending for handle",handle);
467  }
468  else
469  {
470  logError(__func__,"Handle exists but wrong type",handle);
471  return(E_UNKNOWN);
472  }
473  }
474  else
475  {
476  auto handleData = std::make_shared<handleSourceSoundProperty>(iter->second,sourceID,soundProperty,mpDatabaseHandler);
477  handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTY);
478  }
479  logInfo(__func__,"sourceID=", sourceID, "soundProperty.Type=", soundProperty.type, "soundProperty.value=", soundProperty.value,"handle=",handle);
480  am_Error_e syncError(iter->second->asyncSetSourceSoundProperty(handle, sourceID, soundProperty));
481  if (syncError)
482  {
483  removeHandle(handle);
484  logError(__func__,"Error while calling asyncSetSourceSoundProperty sourceID:",sourceID,"handle:",handle,"soundProperty:",soundProperty.type,soundProperty.value);
485  }
486  return(syncError);
487 }
488 
489 am_Error_e CAmRoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sourceID_t sourceID)
490 {
491  auto iter (mMapSourceInterface.find(sourceID));
492  if (iter == mMapSourceInterface.end())
493  {
494  logError(__func__,"Could not find sourceID",sourceID);
495  return (E_NON_EXISTENT);
496  }
497 
498  if(handleExists(handle))
499  {
501  {
502  logInfo(__func__,"Resending for handle",handle);
503  }
504  else
505  {
506  logError(__func__,"Handle exists but wrong type",handle);
507  return(E_UNKNOWN);
508  }
509  }
510  else
511  {
512  auto handleData = std::make_shared<handleSourceSoundProperties>(iter->second,sourceID,listSoundProperties,mpDatabaseHandler);
513  handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTIES);
514  }
515 
516  logInfo(__func__,"sourceID=", sourceID);
517  am_Error_e syncError(iter->second->asyncSetSourceSoundProperties(handle, sourceID, listSoundProperties));
518  if (syncError)
519  {
520  removeHandle(handle);
521  logError(__func__,"Error while calling asyncSetSourceSoundProperties sourceID:",sourceID,"handle:",handle);
522  }
523  return(syncError);
524 }
525 
526 am_Error_e CAmRoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sinkID_t sinkID)
527 {
528  auto iter (mMapSinkInterface.find(sinkID));
529  if (iter == mMapSinkInterface.end())
530  {
531  logError(__func__,"Could not find sink",sinkID);
532  return (E_NON_EXISTENT);
533  }
534 
535  if(handleExists(handle))
536  {
538  {
539  logInfo(__func__,"Resending for handle",handle);
540  }
541  else
542  {
543  logError(__func__,"Handle exists but wrong type",handle);
544  return(E_UNKNOWN);
545  }
546  }
547  else
548  {
549  auto handleData = std::make_shared<handleSinkSoundProperties>(iter->second,sinkID,listSoundProperties,mpDatabaseHandler);
550  handle = createHandle(handleData, H_SETSINKSOUNDPROPERTIES);
551  }
552 
553  logInfo(__func__,"sinkID=", sinkID,"handle=",handle);
554  am_Error_e syncError(iter->second->asyncSetSinkSoundProperties(handle, sinkID, listSoundProperties));
555  if (syncError)
556  {
557  removeHandle(handle);
558  logError(__func__,"Error while calling asyncSetSinkSoundProperties sinkID:",sinkID,"handle:",handle);
559  }
560  return(syncError);
561 }
562 
563 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)
564 {
565  auto iter (mMapCrossfaderInterface.find(crossfaderID));
566  if (iter == mMapCrossfaderInterface.end())
567  {
568  logError(__func__,"Could not find crossfaderID",crossfaderID);
569  return (E_NON_EXISTENT);
570  }
571 
572  if(handleExists(handle))
573  {
575  {
576  logInfo(__func__,"Resending for handle",handle);
577  }
578  else
579  {
580  logError(__func__,"Handle exists but wrong type",handle);
581  return(E_UNKNOWN);
582  }
583  }
584  else
585  {
586  auto handleData = std::make_shared<handleCrossFader>(iter->second,crossfaderID,hotSink,mpDatabaseHandler);
587  handle = createHandle(handleData, H_CROSSFADE);
588  }
589 
590  logInfo(__func__,"hotSource=", hotSink, "crossfaderID=", crossfaderID, "rampType=", rampType, "rampTime=", time,"handle=",handle);
591  am_Error_e syncError(iter->second->asyncCrossFade(handle, crossfaderID, hotSink, rampType, time));
592  if (syncError)
593  {
594  removeHandle(handle);
595  }
596  return(syncError);
597 }
598 
600 {
601  logInfo(__func__,"domainID=", domainID, "domainState=", domainState);
602  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
603  iter = mMapDomainInterface.find(domainID);
604  if (iter != mMapDomainInterface.end())
605  return (iter->second->setDomainState(domainID, domainState));
606  return (E_NON_EXISTENT);
607 }
608 
615 {
616  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
617  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
618  for (; iter < iterEnd; ++iter)
619  {
620  if ((*iter).busName.compare(domainData.busname) == 0)
621  {
622  mMapDomainInterface.insert(std::make_pair(domainData.domainID, (*iter).routingInterface));
623  return (E_OK);
624  }
625  }
626  logError(__PRETTY_FUNCTION__," Could not find busname for bus",domainData.busname);
627  return (E_UNKNOWN);
628 }
629 
636 {
637  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
638  iter = mMapDomainInterface.find(sourceData.domainID);
639  if (iter != mMapDomainInterface.end())
640  {
641  mMapSourceInterface.insert(std::make_pair(sourceData.sourceID, iter->second));
642  return (E_OK);
643  }
644  logError(__PRETTY_FUNCTION__," Could not find domainInterface for domainID",sourceData.domainID);
645  return (E_UNKNOWN);
646 }
647 
654 {
655  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
656  iter = mMapDomainInterface.find(sinkData.domainID);
657  if (iter != mMapDomainInterface.end())
658  {
659  mMapSinkInterface.insert(std::make_pair(sinkData.sinkID, iter->second));
660  return (E_OK);
661  }
662  logError(__PRETTY_FUNCTION__,"Could not find domainInterface for domainID",sinkData.domainID);
663  return (E_UNKNOWN);
664 }
665 
672 {
673  DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
674  iter = mMapSourceInterface.find(crossfaderData.sourceID);
675  if (iter != mMapSourceInterface.end())
676  {
677  mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID, iter->second));
678  return (E_OK);
679  }
680  logError(__PRETTY_FUNCTION__," Could not find sourceInterface for source",crossfaderData.sourceID);
681  return (E_UNKNOWN);
682 }
683 
689 {
690  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
691  iter = mMapDomainInterface.find(domainID);
692  if (iter != mMapDomainInterface.end())
693  {
694  mMapDomainInterface.erase(iter);
695  return (E_OK);
696  }
697 
698  return (E_NON_EXISTENT);
699 }
700 
706 {
707  SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
708  iter = mMapSourceInterface.find(sourceID);
709  if (iter != mMapSourceInterface.end())
710  {
711  mMapSourceInterface.erase(iter);
712  return (E_OK);
713  }
714 
715  return (E_NON_EXISTENT);
716 }
717 
723 {
724  SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
725  iter = mMapSinkInterface.find(sinkID);
726  if (iter != mMapSinkInterface.end())
727  {
728  mMapSinkInterface.erase(iter);
729  return (E_OK);
730  }
731 
732  return (E_NON_EXISTENT);
733 }
734 
740 {
741  CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
742  iter = mMapCrossfaderInterface.find(crossfaderID);
743  if (iter != mMapCrossfaderInterface.end())
744  {
745  mMapCrossfaderInterface.erase(iter);
746  return (E_OK);
747  }
748 
749  return (E_NON_EXISTENT);
750 }
751 
758 {
759  if (mlistActiveHandles.erase(handle))
760  {
761  return (E_OK);
762  }
763  logError(__func__,"Could not remove handle",handle.handle);
764  return (E_NON_EXISTENT);
765 }
766 
767 am_Error_e CAmRoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
768 {
769  listHandles.clear();
770  HandlesMap::const_iterator it = mlistActiveHandles.begin();
771  for (; it != mlistActiveHandles.end(); ++it)
772  {
773  listHandles.push_back(it->first);
774  }
775  return (E_OK);
776 }
777 
784 am_Handle_s CAmRoutingSender::createHandle(std::shared_ptr<handleDataBase> handleData, const am_Handle_e type)
785 {
786  am_Handle_s handle;
787  if (++mHandleCount>=1024) //defined by 10 bit (out if structure!)
788  mHandleCount=1;
789  handle.handle = mHandleCount;
790  handle.handleType = type;
791  mlistActiveHandles.insert(std::make_pair(handle, handleData));
792  if ((mlistActiveHandles.size()%100) == 0)
793  {
794  logInfo("CAmRoutingSender::createHandle warning: too many open handles, number of handles: ", mlistActiveHandles.size());
795  }
796  logInfo(__func__,handle.handle, handle.handleType);
797  return (handle);
798 }
799 
801 {
802  mpRoutingReceiver->waitOnStartup(false);
803 
804  //create a list of handles
805  std::vector<uint16_t> listStartupHandles;
806  for (size_t i = 0; i < mListInterfaces.size(); i++)
807  {
808  listStartupHandles.push_back(mpRoutingReceiver->getStartupHandle());
809  }
810 
811  //set the receiver ready to wait for replies
812  mpRoutingReceiver->waitOnStartup(true);
813 
814  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
815  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
816  std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
817  for (; iter < iterEnd; ++iter)
818  {
819  (*iter).routingInterface->setRoutingReady(*(handleIter++));
820  }
821 }
822 
824 {
825  mpRoutingReceiver->waitOnRundown(false);
826  //create a list of handles
827  std::vector<uint16_t> listStartupHandles;
828  for (size_t i = 0; i < mListInterfaces.size(); i++)
829  {
830  listStartupHandles.push_back(mpRoutingReceiver->getRundownHandle());
831  }
832 
833  //set the receiver ready to wait for replies
834  mpRoutingReceiver->waitOnRundown(true);
835 
836  std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
837  std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
838  std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
839  for (; iter < iterEnd; ++iter)
840  {
841  (*iter).routingInterface->setRoutingRundown(*(handleIter++));
842  }
843 }
844 
845 am_Error_e CAmRoutingSender::asyncSetVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes)
846 {
847  IAmRoutingSend* pRoutingInterface(NULL);
848  if (listVolumes.empty())
849  return (E_NOT_POSSIBLE);
850 
851  //we need an interface so lets get either the sink or source ID from the first entry in the listVolumes
852  if (listVolumes[0].volumeType==VT_SINK)
853  {
854  am_sinkID_t sinkID=listVolumes[0].volumeID.sink;
855  SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
856  iter = mMapSinkInterface.find(sinkID);
857  if(iter!=mMapSinkInterface.end())
858  pRoutingInterface=iter->second;
859  else
860  return(E_NON_EXISTENT);
861  }
862 
863  else if (listVolumes[0].volumeType==VT_SOURCE)
864  {
865  am_sourceID_t sourceID=listVolumes[0].volumeID.source;
866  SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
867  iter = mMapSourceInterface.find(sourceID);
868  if (iter!=mMapSourceInterface.end())
869  pRoutingInterface=iter->second;
870  else
871  return(E_NON_EXISTENT);
872  }
873  else
874  return (E_NON_EXISTENT);
875 
876  auto handleData = std::make_shared<handleSetVolumes>(pRoutingInterface,listVolumes,mpDatabaseHandler);
877  handle = createHandle(handleData, H_SETVOLUMES);
878 
879  logInfo(__func__, "handle=", handle);
880  am_Error_e syncError(pRoutingInterface->asyncSetVolumes(handle, listVolumes));
881  if (syncError)
882  {
883  removeHandle(handle);
884  }
885  return(syncError);
886 
887 }
888 
890 {
891  auto iter (mMapSinkInterface.find(sinkID));
892  if (iter == mMapSinkInterface.end())
893  {
894  logError(__func__,"Could not find sink",sinkID);
895  return (E_NON_EXISTENT);
896  }
897 
898  if(handleExists(handle))
899  {
901  {
902  logInfo(__func__,"Resending for handle",handle);
903  }
904  else
905  {
906  logError(__func__,"Handle exists but wrong type",handle);
907  return(E_UNKNOWN);
908  }
909  }
910  else
911  {
912  auto handleData = std::make_shared<handleSetSinkNotificationConfiguration>(iter->second,sinkID,notificationConfiguration,mpDatabaseHandler);
913  handle = createHandle(handleData, H_SETSINKNOTIFICATION);
914  }
915 
916  logInfo(__func__,"sinkID=",sinkID,"notificationConfiguration.type=",notificationConfiguration.type,"notificationConfiguration.status",notificationConfiguration.status,"notificationConfiguration.parameter",notificationConfiguration.parameter);
917  am_Error_e syncError(iter->second->asyncSetSinkNotificationConfiguration(handle, sinkID, notificationConfiguration));
918  if (syncError)
919  {
920  removeHandle(handle);
921  logError(__func__,"Error while calling asyncSetSinkNotificationConfiguration sinkID:",sinkID,"handle:",handle);
922  }
923  return(syncError);
924 }
925 
927 {
928  auto iter (mMapSourceInterface.find(sourceID));
929  if (iter == mMapSourceInterface.end())
930  {
931  logError(__func__,"Could not find sourceID",sourceID);
932  return (E_NON_EXISTENT);
933  }
934 
935  if(handleExists(handle))
936  {
938  {
939  logInfo(__func__,"Resending for handle",handle);
940  }
941  else
942  {
943  logError(__func__,"Handle exists but wrong type",handle);
944  return(E_UNKNOWN);
945  }
946  }
947  else
948  {
949  auto handleData = std::make_shared<handleSetSourceNotificationConfiguration>(iter->second,sourceID,notificationConfiguration,mpDatabaseHandler);
950  handle = createHandle(handleData, H_SETSOURCENOTIFICATION);
951  }
952 
953  logInfo(__func__,"sourceID=",sourceID,"notificationConfiguration.type=",notificationConfiguration.type,"notificationConfiguration.status",notificationConfiguration.status,"notificationConfiguration.parameter",notificationConfiguration.parameter);
954  am_Error_e syncError(iter->second->asyncSetSourceNotificationConfiguration(handle, sourceID, notificationConfiguration));
955  if (syncError)
956  {
957  removeHandle(handle);
958  logError(__func__,"Error while calling asyncSetSourceNotificationConfiguration sourceID:",sourceID,"handle:",handle);
959  }
960  return(syncError);
961 }
962 
963 void CAmRoutingSender::unloadLibraries(void)
964 {
965  std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
966  for (; iterator < mListLibraryHandles.end(); ++iterator)
967  {
968  dlclose(*iterator);
969  }
970  mListLibraryHandles.clear();
971 }
972 
973 am_Error_e CAmRoutingSender::getListPlugins(std::vector<std::string>& interfaces) const
974 {
975  std::vector<InterfaceNamePairs>::const_iterator it = mListInterfaces.begin();
976  for (; it != mListInterfaces.end(); ++it)
977  {
978  interfaces.push_back(it->busName);
979  }
980  return (E_OK);
981 }
982 
983 void CAmRoutingSender::getInterfaceVersion(std::string & version) const
984 {
985  version = RoutingVersion;
986 }
987 am_Error_e CAmRoutingSender::resyncConnectionState(const am_domainID_t domainID,std::vector<am_Connection_s>& listOfExistingConnections)
988 {
989  DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
990  iter = mMapDomainInterface.find(domainID);
991  if (iter != mMapDomainInterface.end())
992  return (iter->second->resyncConnectionState(domainID, listOfExistingConnections));
993  return (E_NON_EXISTENT);
994 }
995 
997 {
998  auto it(mlistActiveHandles.find(handle));
999  if (it!=mlistActiveHandles.end())
1000  {
1001  am_Error_e error(it->second->writeDataToDatabase());
1002  mlistActiveHandles.erase(handle);
1003  return (error);
1004  }
1005  logError(__func__,"could not find handle data for handle",handle);
1006  return (am_Error_e::E_NON_EXISTENT);
1007 }
1008 
1010 {
1011  auto it(mlistActiveHandles.find(handle));
1012  if (it!=mlistActiveHandles.end())
1013  {
1014  handleVolumeBase* basePtr = static_cast<handleVolumeBase*>(it->second.get());
1015  if (basePtr->returnVolume()!=volume)
1016  {
1017  logError(__func__,"volume returned for handle does not match: ",volume,"expected:",basePtr->returnVolume());
1018  }
1019  return;
1020  }
1021  logError(__func__,"could not find handle data for handle",handle);
1022 }
1023 
1025 {
1026  auto iter(mlistActiveHandles.find(handle));
1027  if (iter!=mlistActiveHandles.end())
1028  {
1029  return (true);
1030  }
1031  return (false);
1032 }
1033 
1035 {
1036  return (mpDatabaseHandler->changeSinkSoundPropertyDB(mSoundProperty,mSinkID));
1037 }
1038 
1040 {
1041  std::vector<am_SoundProperty_s>::const_iterator it = mlistSoundProperties.begin();
1042  for (; it != mlistSoundProperties.end(); ++it)
1043  {
1044  mpDatabaseHandler->changeSinkSoundPropertyDB(*it, mSinkID);
1045  }
1046  return (am_Error_e::E_OK);
1047 }
1048 
1050 {
1051  return (mpDatabaseHandler->changeSourceSoundPropertyDB(mSoundProperty,mSourceID));
1052 }
1053 
1055 {
1056  std::vector<am_SoundProperty_s>::const_iterator it = mlistSoundProperties.begin();
1057  for (; it != mlistSoundProperties.end(); ++it)
1058  {
1059  mpDatabaseHandler->changeSourceSoundPropertyDB(*it, mSourceID);
1060  }
1061  return (am_Error_e::E_OK);
1062 }
1063 
1065 {
1066  return (mpDatabaseHandler->changeSourceState(mSourceID,mSourceState));
1067 }
1068 
1070 {
1071  return (mpDatabaseHandler->changeSourceVolume(mSourceID,returnVolume()));
1072 }
1073 
1075 {
1076  return (mpDatabaseHandler->changeSinkVolume(mSinkID,returnVolume()));
1077 }
1078 
1080 {
1081  return (mpDatabaseHandler->changeCrossFaderHotSink(mCrossfaderID, mHotSink));
1082 }
1083 
1085 {
1086  mConnectionPending = false;
1087  return (mpDatabaseHandler->changeConnectionFinal(mConnectionID));
1088 }
1089 
1091 {
1092  return E_OK;
1093 }
1094 
1096 {
1097  std::vector<am_Volumes_s>::const_iterator iterator (mlistVolumes.begin());
1098 
1099  for (;iterator!=mlistVolumes.end();++iterator)
1100  {
1101  if (iterator->volumeType==VT_SINK)
1102  {
1103  return (mpDatabaseHandler->changeSinkVolume(iterator->volumeID.sink,iterator->volume));
1104  }
1105  else if (iterator->volumeType==VT_SOURCE)
1106  {
1107  return (mpDatabaseHandler->changeSourceVolume(iterator->volumeID.source,iterator->volume));
1108  }
1109  }
1110  return (am_Error_e::E_WRONG_FORMAT);
1111 }
1112 
1114 {
1115  return (mpDatabaseHandler->changeSinkNotificationConfigurationDB(mSinkID,mNotificationConfiguration));
1116 }
1117 
1119 {
1120  return (mpDatabaseHandler->changeSourceNotificationConfigurationDB(mSourceID,mNotificationConfiguration));
1121 }
1122 
1124 {
1125  ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
1126  iter = mMapConnectionInterface.find(connectionID);
1127  if (iter != mMapConnectionInterface.end())
1128  {
1129  mMapConnectionInterface.erase(iter);
1130  return (E_OK);
1131  }
1132  return (E_UNKNOWN);
1133 }
1134 
1136 {
1137  if (mConnectionPending)
1138  {
1139  mpDatabaseHandler->removeConnection(mConnectionID);
1140  }
1141 }
1142 
1144 {
1145  mpDatabaseHandler->removeConnection(mConnectionID);
1146 }
1147 
1148 }
1149 
am_Error_e writeDataToDatabase()
function to write the handle data to the database
std::string busname
the busname.
This error is returned in case a connect is issued with a connectionFormat that cannot be selected fo...
am_Error_e asyncAbort(const am_Handle_s &handle)
uint16_t am_connectionID_t
a connection ID
am_timeSync_t delay
the delay of the conneciton
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
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
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.
Implements the Receiving side of the RoutingPlugins.
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.
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.
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
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