summaryrefslogtreecommitdiff
path: root/AudioManagerCore/src
diff options
context:
space:
mode:
Diffstat (limited to 'AudioManagerCore/src')
-rw-r--r--AudioManagerCore/src/CAmCommandReceiver.cpp264
-rw-r--r--AudioManagerCore/src/CAmCommandSender.cpp367
-rw-r--r--AudioManagerCore/src/CAmControlReceiver.cpp606
-rw-r--r--AudioManagerCore/src/CAmControlSender.cpp571
-rw-r--r--AudioManagerCore/src/CAmDatabaseHandlerMap.cpp3079
-rw-r--r--AudioManagerCore/src/CAmDatabaseObserver.cpp242
-rw-r--r--AudioManagerCore/src/CAmLog.cpp101
-rw-r--r--AudioManagerCore/src/CAmRouter.cpp884
-rw-r--r--AudioManagerCore/src/CAmRoutingReceiver.cpp620
-rw-r--r--AudioManagerCore/src/CAmRoutingSender.cpp838
-rw-r--r--AudioManagerCore/src/CAmTelnetMenuHelper.cpp1438
-rwxr-xr-xAudioManagerCore/src/CAmTelnetServer.cpp257
12 files changed, 9267 insertions, 0 deletions
diff --git a/AudioManagerCore/src/CAmCommandReceiver.cpp b/AudioManagerCore/src/CAmCommandReceiver.cpp
new file mode 100644
index 0000000..d903384
--- /dev/null
+++ b/AudioManagerCore/src/CAmCommandReceiver.cpp
@@ -0,0 +1,264 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmCommandReceiver.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmCommandReceiver.h"
+#include <cassert>
+#include <algorithm>
+#include "IAmDatabaseHandler.h"
+#include "CAmControlSender.h"
+#include "CAmDltWrapper.h"
+#include "CAmSocketHandler.h"
+
+namespace am
+{
+
+CAmCommandReceiver::CAmCommandReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmControlSender *iControlSender, CAmSocketHandler *iSocketHandler) :
+ mDatabaseHandler(iDatabaseHandler), //
+ mControlSender(iControlSender), //
+ mDBusWrapper(NULL), //
+ mSocketHandler(iSocketHandler), //
+ handleCount(0),//
+ mListStartupHandles(), //
+ mListRundownHandles(), //
+ mWaitStartup(false), //
+ mWaitRundown(false),
+ mLastErrorStartup(E_OK), //
+ mLastErrorRundown(E_OK) //
+
+{
+ assert(mDatabaseHandler!=NULL);
+ assert(mSocketHandler!=NULL);
+ assert(mControlSender!=NULL);
+}
+
+CAmCommandReceiver::CAmCommandReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmControlSender *iControlSender, CAmSocketHandler *iSocketHandler, CAmDbusWrapper *iDBusWrapper) :
+ mDatabaseHandler(iDatabaseHandler), //
+ mControlSender(iControlSender), //
+ mDBusWrapper(iDBusWrapper), //
+ mSocketHandler(iSocketHandler), //
+ handleCount(0),//
+ mListStartupHandles(), //
+ mListRundownHandles(), //
+ mWaitStartup(false), //
+ mWaitRundown(false), //
+ mLastErrorStartup(E_UNKNOWN), //
+ mLastErrorRundown(E_UNKNOWN)
+{
+ assert(mDatabaseHandler!=NULL);
+ assert(mSocketHandler!=NULL);
+ assert(mControlSender!=NULL);
+ assert(mDBusWrapper!=NULL);
+}
+
+CAmCommandReceiver::~CAmCommandReceiver()
+{
+}
+
+am_Error_e CAmCommandReceiver::connect(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t & mainConnectionID)
+{
+ logInfo("CommandReceiver::connect got called, sourceID=", sourceID, "sinkID=", sinkID);
+ return (mControlSender->hookUserConnectionRequest(sourceID, sinkID, mainConnectionID));
+}
+
+am_Error_e CAmCommandReceiver::disconnect(const am_mainConnectionID_t mainConnectionID)
+{
+ logInfo("CommandReceiver::disconnect got called, mainConnectionID=", mainConnectionID);
+ return (mControlSender->hookUserDisconnectionRequest(mainConnectionID));
+}
+
+am_Error_e CAmCommandReceiver::setVolume(const am_sinkID_t sinkID, const am_mainVolume_t volume)
+{
+ logInfo("CommandReceiver::setVolume got called, sinkID=", sinkID, "volume=", volume);
+ return (mControlSender->hookUserVolumeChange(sinkID, volume));
+}
+
+am_Error_e CAmCommandReceiver::volumeStep(const am_sinkID_t sinkID, const int16_t volumeStep)
+{
+ logInfo("CommandReceiver::volumeStep got called, sinkID=", sinkID, "volumeStep=", volumeStep);
+ return (mControlSender->hookUserVolumeStep(sinkID, volumeStep));
+}
+
+am_Error_e CAmCommandReceiver::setSinkMuteState(const am_sinkID_t sinkID, const am_MuteState_e muteState)
+{
+ logInfo("CommandReceiver::setSinkMuteState got called, sinkID=", sinkID, "muteState=", muteState);
+ return (mControlSender->hookUserSetSinkMuteState(sinkID, muteState));
+}
+
+am_Error_e CAmCommandReceiver::setMainSinkSoundProperty(const am_MainSoundProperty_s & soundProperty, const am_sinkID_t sinkID)
+{
+ logInfo("CommandReceiver::setMainSinkSoundProperty got called, sinkID=", sinkID, "soundPropertyType=", soundProperty.type, "soundPropertyValue=", soundProperty.value);
+ return (mControlSender->hookUserSetMainSinkSoundProperty(sinkID, soundProperty));
+}
+
+am_Error_e CAmCommandReceiver::setMainSourceSoundProperty(const am_MainSoundProperty_s & soundProperty, const am_sourceID_t sourceID)
+{
+ logInfo("CommandReceiver::setMainSourceSoundProperty got called, sourceID=", sourceID, "soundPropertyType=", soundProperty.type, "soundPropertyValue=", soundProperty.value);
+ return (mControlSender->hookUserSetMainSourceSoundProperty(sourceID, soundProperty));
+}
+
+am_Error_e CAmCommandReceiver::setSystemProperty(const am_SystemProperty_s & property)
+{
+ logInfo("CommandReceiver::setSystemProperty got called", "type=", property.type, "soundPropertyValue=", property.value);
+ return (mControlSender->hookUserSetSystemProperty(property));
+}
+
+am_Error_e CAmCommandReceiver::getVolume(const am_sinkID_t sinkID, am_mainVolume_t& mainVolume) const
+{
+ return (mDatabaseHandler->getSinkMainVolume(sinkID, mainVolume));
+}
+
+am_Error_e CAmCommandReceiver::getListMainConnections(std::vector<am_MainConnectionType_s> & listConnections) const
+{
+ return (mDatabaseHandler->getListVisibleMainConnections(listConnections));
+
+}
+
+am_Error_e CAmCommandReceiver::getListMainSinks(std::vector<am_SinkType_s>& listMainSinks) const
+{
+ return (mDatabaseHandler->getListMainSinks(listMainSinks));
+}
+
+am_Error_e CAmCommandReceiver::getListMainSources(std::vector<am_SourceType_s>& listMainSources) const
+{
+ return (mDatabaseHandler->getListMainSources(listMainSources));
+}
+
+am_Error_e CAmCommandReceiver::getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s> & listSoundProperties) const
+{
+ return (mDatabaseHandler->getListMainSinkSoundProperties(sinkID, listSoundProperties));
+}
+
+am_Error_e CAmCommandReceiver::getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s> & listSourceProperties) const
+{
+ return (mDatabaseHandler->getListMainSourceSoundProperties(sourceID, listSourceProperties));
+}
+
+am_Error_e CAmCommandReceiver::getListSourceClasses(std::vector<am_SourceClass_s> & listSourceClasses) const
+{
+ return (mDatabaseHandler->getListSourceClasses(listSourceClasses));
+}
+
+am_Error_e CAmCommandReceiver::getListSinkClasses(std::vector<am_SinkClass_s> & listSinkClasses) const
+{
+ return (mDatabaseHandler->getListSinkClasses(listSinkClasses));
+}
+
+am_Error_e CAmCommandReceiver::getListSystemProperties(std::vector<am_SystemProperty_s> & listSystemProperties) const
+{
+ return (mDatabaseHandler->getListSystemProperties(listSystemProperties));
+}
+
+am_Error_e CAmCommandReceiver::getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t & delay) const
+{
+ return (mDatabaseHandler->getTimingInformation(mainConnectionID, delay));
+}
+
+am_Error_e CAmCommandReceiver::getDBusConnectionWrapper(CAmDbusWrapper*& dbusConnectionWrapper) const
+{
+#ifdef WITH_DBUS_WRAPPER
+ dbusConnectionWrapper = mDBusWrapper;
+ return (E_OK);
+#else
+ dbusConnectionWrapper = NULL;
+ return (E_UNKNOWN);
+#endif /*WITH_DBUS_WRAPPER*/
+}
+
+am_Error_e CAmCommandReceiver::getSocketHandler(CAmSocketHandler *& socketHandler) const
+{
+ socketHandler = mSocketHandler;
+ return (E_OK);
+}
+
+void CAmCommandReceiver::getInterfaceVersion(std::string & version) const
+{
+ version = CommandVersion;
+}
+
+void CAmCommandReceiver::confirmCommandReady(const uint16_t handle, const am_Error_e error)
+{
+ if (error !=E_OK)
+ mLastErrorStartup=error;
+ mListStartupHandles.erase(std::remove(mListStartupHandles.begin(), mListStartupHandles.end(), handle), mListStartupHandles.end());
+ if (mWaitStartup && mListStartupHandles.empty())
+ mControlSender->confirmCommandReady(mLastErrorStartup);
+}
+
+void CAmCommandReceiver::confirmCommandRundown(const uint16_t handle, const am_Error_e error)
+{
+ if (error !=E_OK)
+ mLastErrorRundown=error;
+ mListRundownHandles.erase(std::remove(mListRundownHandles.begin(), mListRundownHandles.end(), handle), mListRundownHandles.end());
+ if (mWaitRundown && mListRundownHandles.empty())
+ mControlSender->confirmCommandRundown(mLastErrorRundown);
+}
+
+uint16_t CAmCommandReceiver::getStartupHandle()
+{
+ uint16_t handle = ++handleCount; //todo: handle overflow
+ mListStartupHandles.push_back(handle);
+ return (handle);
+}
+
+uint16_t CAmCommandReceiver::getRundownHandle()
+{
+ uint16_t handle = ++handleCount; //todo: handle overflow
+ mListRundownHandles.push_back(handle);
+ return (handle);
+}
+
+void CAmCommandReceiver::waitOnStartup(bool startup)
+{
+ mWaitStartup = startup;
+ mLastErrorStartup=E_OK;
+}
+
+am_Error_e CAmCommandReceiver::getListMainSinkNotificationConfigurations(const am_sinkID_t sinkID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations) const
+{
+ return (mDatabaseHandler->getListMainSinkNotificationConfigurations(sinkID,listMainNotificationConfigurations));
+}
+
+am_Error_e CAmCommandReceiver::getListMainSourceNotificationConfigurations(const am_sourceID_t sourceID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations) const
+{
+ return (mDatabaseHandler->getListMainSourceNotificationConfigurations(sourceID,listMainNotificationConfigurations));
+}
+
+am_Error_e CAmCommandReceiver::setMainSinkNotificationConfiguration(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration)
+{
+ logInfo("CommandReceiver::setMainSinkNotificationConfiguration got called, sinkID=", sinkID, " type=",mainNotificationConfiguration.type, " parameter=", mainNotificationConfiguration.parameter, "status=",mainNotificationConfiguration.status);
+ return (mControlSender->hookUserSetMainSinkNotificationConfiguration(sinkID,mainNotificationConfiguration));
+}
+
+am_Error_e CAmCommandReceiver::setMainSourceNotificationConfiguration(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration)
+{
+ logInfo("CommandReceiver::setMainSourceNotificationConfiguration got called, sourceID=", sourceID, " type=",mainNotificationConfiguration.type, " parameter=", mainNotificationConfiguration.parameter, "status=",mainNotificationConfiguration.status);
+ return (mControlSender->hookUserSetMainSourceNotificationConfiguration(sourceID,mainNotificationConfiguration));
+}
+
+void CAmCommandReceiver::waitOnRundown(bool rundown)
+{
+ mWaitRundown = rundown;
+ mLastErrorStartup=E_OK;
+}
+
+}
diff --git a/AudioManagerCore/src/CAmCommandSender.cpp b/AudioManagerCore/src/CAmCommandSender.cpp
new file mode 100644
index 0000000..da064cc
--- /dev/null
+++ b/AudioManagerCore/src/CAmCommandSender.cpp
@@ -0,0 +1,367 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmCommandSender.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmCommandSender.h"
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sstream>
+#include <string>
+#include <cstring>
+#include <stdexcept>
+#include "CAmCommandReceiver.h"
+#include "TAmPluginTemplate.h"
+#include "CAmDltWrapper.h"
+#include "audiomanagerconfig.h"
+
+namespace am
+{
+
+/**
+ * macro to call all interfaces
+ */
+#define CALL_ALL_INTERFACES(...) \
+ std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin(); \
+ std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end(); \
+ for (; iter<iterEnd;++iter) \
+ { \
+ (*iter)->__VA_ARGS__; \
+ }
+
+CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories) :
+ mListInterfaces(), //
+ mListLibraryHandles(), //
+ mListLibraryNames(), //
+ mCommandReceiver()
+{
+ if (listOfPluginDirectories.empty())
+ {
+ logError("CAmCommandSender::CAmCommandSender: List of commandplugins is empty");
+ }
+
+ std::vector<std::string> sharedLibraryNameList;
+ std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
+ std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
+
+ // search communicator plugins in configured directories
+ for (; dirIter < dirIterEnd; ++dirIter)
+ {
+ const char* directoryName = dirIter->c_str();
+ logInfo("Searching for CommandPlugins in", *dirIter);
+ DIR *directory = opendir(directoryName);
+
+ if (!directory)
+ {
+ logError("Error opening directory ", *dirIter);
+ continue;
+ }
+
+ // iterate content of directory
+ struct dirent *itemInDirectory = 0;
+ while ((itemInDirectory = readdir(directory)))
+ {
+ unsigned char entryType = itemInDirectory->d_type;
+ std::string entryName = itemInDirectory->d_name;
+ std::string fullName = *dirIter + "/" + entryName;
+
+ bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
+ bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
+
+ // Handle cases where readdir() could not determine the file type
+ if (entryType == DT_UNKNOWN) {
+ struct stat buf;
+
+ if (stat(fullName.c_str(), &buf)) {
+ logInfo(__PRETTY_FUNCTION__,"Failed to stat file: ", entryName, errno);
+ continue;
+ }
+
+ regularFile = S_ISREG(buf.st_mode);
+ }
+
+ if (regularFile && sharedLibExtension)
+ {
+ std::string name(directoryName);
+ sharedLibraryNameList.push_back(name + "/" + entryName);
+ }
+ }
+ closedir(directory);
+ }
+
+ // iterate all communicator plugins and start them
+ std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
+ std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
+
+ for (; iter < iterEnd; ++iter)
+ {
+ logInfo("Loading CommandSender plugin", *iter);
+ IAmCommandSend* (*createFunc)();
+ void* tempLibHandle = NULL;
+ createFunc = getCreateFunction<IAmCommandSend*()>(*iter, tempLibHandle);
+
+ if (!createFunc)
+ {
+ logInfo("Entry point of CommandPlugin not found", *iter);
+ continue;
+ }
+
+ IAmCommandSend* commander = createFunc();
+
+ if (!commander)
+ {
+ logInfo("CommandPlugin initialization failed. Entry Function not callable");
+ dlclose(tempLibHandle);
+ continue;
+ }
+
+ //check libversion
+ std::string version, cVersion(CommandVersion);
+ commander->getInterfaceVersion(version);
+ uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion;
+ std::istringstream(version.substr(0, 1)) >> majorVersion;
+ std::istringstream(version.substr(2, 1)) >> minorVersion;
+ std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion;
+ std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion;
+
+
+
+ if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion)))
+ {
+ logError("CommandInterface initialization failed. Version of Interface to old");
+ dlclose(tempLibHandle);
+ continue;
+ }
+
+ mListInterfaces.push_back(commander);
+ mListLibraryHandles.push_back(tempLibHandle);
+ mListLibraryNames.push_back(iter->c_str());
+ }
+}
+
+CAmCommandSender::~CAmCommandSender()
+{
+ //unloadLibraries();
+}
+
+am_Error_e CAmCommandSender::startupInterfaces(CAmCommandReceiver *iCommandReceiver)
+{
+ mCommandReceiver = iCommandReceiver;
+ am_Error_e returnError = E_OK;
+
+ std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
+ std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
+ for (; iter < iterEnd; ++iter)
+ {
+ am_Error_e error = (*iter)->startupInterface(iCommandReceiver);
+ if (error != E_OK)
+ {
+ returnError = error;
+ }
+ }
+ return (returnError);
+}
+
+void CAmCommandSender::cbNumberOfSinkClassesChanged()
+{
+ CALL_ALL_INTERFACES(cbNumberOfSinkClassesChanged())
+}
+
+void CAmCommandSender::cbNumberOfSourceClassesChanged()
+{
+ CALL_ALL_INTERFACES(cbNumberOfSourceClassesChanged())
+}
+
+void CAmCommandSender::cbMainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState)
+{
+ CALL_ALL_INTERFACES(cbMainConnectionStateChanged(connectionID,connectionState))
+}
+
+void CAmCommandSender::cbMainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty)
+{
+ CALL_ALL_INTERFACES(cbMainSinkSoundPropertyChanged(sinkID,SoundProperty))
+}
+
+void CAmCommandSender::cbMainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty)
+{
+ CALL_ALL_INTERFACES(cbMainSourceSoundPropertyChanged(sourceID,SoundProperty))
+}
+
+void CAmCommandSender::cbSinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s & availability)
+{
+ CALL_ALL_INTERFACES(cbSinkAvailabilityChanged(sinkID,availability))
+}
+
+void CAmCommandSender::cbSourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s & availability)
+{
+ CALL_ALL_INTERFACES(cbSourceAvailabilityChanged(sourceID,availability))
+}
+
+void CAmCommandSender::cbVolumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume)
+{
+ CALL_ALL_INTERFACES(cbVolumeChanged(sinkID,volume))
+}
+
+void CAmCommandSender::cbSinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState)
+{
+ CALL_ALL_INTERFACES(cbSinkMuteStateChanged(sinkID,muteState))
+}
+
+void CAmCommandSender::cbSystemPropertyChanged(const am_SystemProperty_s & SystemProperty)
+{
+ CALL_ALL_INTERFACES(cbSystemPropertyChanged(SystemProperty))
+}
+
+void CAmCommandSender::cbTimingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time)
+{
+ CALL_ALL_INTERFACES(cbTimingInformationChanged(mainConnection,time))
+}
+
+void CAmCommandSender::cbNewMainConnection(const am_MainConnectionType_s mainConnection)
+{
+ CALL_ALL_INTERFACES(cbNewMainConnection(mainConnection))
+}
+
+void CAmCommandSender::cbRemovedMainConnection(const am_mainConnectionID_t mainConnection)
+{
+ CALL_ALL_INTERFACES(cbRemovedMainConnection(mainConnection))
+}
+
+void CAmCommandSender::cbNewSink(const am_SinkType_s sink)
+{
+ CALL_ALL_INTERFACES(cbNewSink(sink))
+}
+
+void CAmCommandSender::cbRemovedSink(const am_sinkID_t sink)
+{
+ CALL_ALL_INTERFACES(cbRemovedSink(sink))
+}
+
+void CAmCommandSender::cbNewSource(const am_SourceType_s source)
+{
+ CALL_ALL_INTERFACES(cbNewSource(source))
+}
+
+void CAmCommandSender::cbRemovedSource(const am_sourceID_t source)
+{
+ CALL_ALL_INTERFACES(cbRemovedSource(source))
+}
+
+void CAmCommandSender::setCommandReady()
+{
+ mCommandReceiver->waitOnStartup(false);
+
+ //create a list of handles
+ std::vector<uint16_t> listStartupHandles;
+ for (size_t i = 0; i < mListInterfaces.size(); i++)
+ {
+ listStartupHandles.push_back(mCommandReceiver->getStartupHandle());
+ }
+
+ //set the receiver ready to wait for replies
+ mCommandReceiver->waitOnStartup(true);
+
+ //now do the calls
+ std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
+ std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
+ std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
+ for (; iter < iterEnd; ++iter)
+ {
+ (*iter)->setCommandReady(*(handleIter++));
+ }
+}
+
+void CAmCommandSender::setCommandRundown()
+{
+ mCommandReceiver->waitOnRundown(false);
+ //create a list of handles
+ std::vector<uint16_t> listStartupHandles;
+ for (size_t i = 0; i < mListInterfaces.size(); i++)
+ {
+ listStartupHandles.push_back(mCommandReceiver->getRundownHandle());
+ }
+
+ //set the receiver ready to wait for replies
+ mCommandReceiver->waitOnRundown(true);
+
+ //now do the calls
+ std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
+ std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
+ std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
+ for (; iter < iterEnd; ++iter)
+ {
+ (*iter)->setCommandRundown(*(handleIter++));
+ }
+}
+
+void CAmCommandSender::getInterfaceVersion(std::string & version) const
+{
+ version = CommandVersion;
+}
+
+am_Error_e am::CAmCommandSender::getListPlugins(std::vector<std::string> & interfaces) const
+{
+ interfaces = mListLibraryNames;
+ return (E_OK);
+}
+
+void CAmCommandSender::cbSinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ CALL_ALL_INTERFACES(cbSinkUpdated(sinkID,sinkClassID,listMainSoundProperties));
+}
+
+void CAmCommandSender::cbSourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ CALL_ALL_INTERFACES(cbSourceUpdated(sourceID,sourceClassID,listMainSoundProperties));
+}
+
+void CAmCommandSender::cbSinkNotification(const am_sinkID_t sinkID, const am_NotificationPayload_s& notification)
+{
+ CALL_ALL_INTERFACES(cbSinkNotification(sinkID,notification));
+}
+
+void CAmCommandSender::cbSourceNotification(const am_sourceID_t sourceID, const am_NotificationPayload_s& notification)
+{
+ CALL_ALL_INTERFACES(cbSourceNotification(sourceID,notification));
+}
+
+void CAmCommandSender::cbSinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration)
+{
+ CALL_ALL_INTERFACES(cbMainSinkNotificationConfigurationChanged(sinkID,mainNotificationConfiguration));
+}
+
+void CAmCommandSender::cbSourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration)
+{
+ CALL_ALL_INTERFACES(cbMainSourceNotificationConfigurationChanged(sourceID,mainNotificationConfiguration));
+}
+
+void CAmCommandSender::unloadLibraries(void)
+{
+ std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
+ for (; iterator < mListLibraryHandles.end(); ++iterator)
+ {
+ dlclose(*iterator);
+ }
+ mListLibraryHandles.clear();
+}
+}
diff --git a/AudioManagerCore/src/CAmControlReceiver.cpp b/AudioManagerCore/src/CAmControlReceiver.cpp
new file mode 100644
index 0000000..c1c161e
--- /dev/null
+++ b/AudioManagerCore/src/CAmControlReceiver.cpp
@@ -0,0 +1,606 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmControlReceiver.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmControlReceiver.h"
+#include <cassert>
+#include <stdlib.h>
+#include <stdexcept>
+#include "audiomanagerconfig.h"
+#include "IAmDatabaseHandler.h"
+#include "CAmRoutingSender.h"
+#include "CAmCommandSender.h"
+#include "CAmRouter.h"
+#include "CAmDltWrapper.h"
+#include "CAmSocketHandler.h"
+
+namespace am {
+
+CAmControlReceiver::CAmControlReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmCommandSender *iCommandSender, CAmSocketHandler *iSocketHandler, CAmRouter* iRouter) :
+ mDatabaseHandler(iDatabaseHandler), //
+ mRoutingSender(iRoutingSender), //
+ mCommandSender(iCommandSender), //
+ mSocketHandler(iSocketHandler), //
+ mRouter(iRouter), //
+ mNodeStateCommunicator(NULL)
+{
+ assert(mDatabaseHandler!=NULL);
+ assert(mRoutingSender!=NULL);
+ assert(mCommandSender!=NULL);
+ assert(mSocketHandler!=NULL);
+ assert(mRouter!=NULL);
+}
+
+CAmControlReceiver::~CAmControlReceiver()
+{
+}
+
+am_Error_e CAmControlReceiver::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s> & returnList)
+{
+ return (mRouter->getRoute(onlyfree, sourceID, sinkID, returnList));
+}
+
+am_Error_e CAmControlReceiver::connect(am_Handle_s & handle, am_connectionID_t & connectionID, const am_CustomConnectionFormat_t format, const am_sourceID_t sourceID, const am_sinkID_t sinkID)
+{
+ logInfo("CAmControlReceiver::connect got called, connectionFormat=", format, "sourceID=", sourceID, "sinkID=", sinkID);
+
+ am_Connection_s tempConnection;
+ tempConnection.sinkID = sinkID;
+ tempConnection.sourceID = sourceID;
+ tempConnection.connectionFormat = format;
+ tempConnection.connectionID = 0;
+ tempConnection.delay=-1;
+
+ mDatabaseHandler->enterConnectionDB(tempConnection, connectionID);
+ am_Error_e syncError(mRoutingSender->asyncConnect(handle, connectionID, sourceID, sinkID, format));
+ if (syncError)
+ {
+ mDatabaseHandler->removeConnection(connectionID);
+ }
+ return(syncError);
+}
+
+am_Error_e CAmControlReceiver::disconnect(am_Handle_s & handle, const am_connectionID_t connectionID)
+{
+ logInfo("CAmControlReceiver::disconnect got called, connectionID=", connectionID);
+ return (mRoutingSender->asyncDisconnect(handle, connectionID));
+}
+
+am_Error_e CAmControlReceiver::crossfade(am_Handle_s & handle, const am_HotSink_e hotSource, const am_crossfaderID_t crossfaderID, const am_CustomRampType_t rampType, const am_time_t rampTime)
+{
+ logInfo("CAmControlReceiver::crossfade got called, hotSource=", hotSource, "crossfaderID=", crossfaderID, "rampType=", rampType, "rampTime=", rampTime);
+ return (mRoutingSender->asyncCrossFade(handle, crossfaderID, hotSource, rampType, rampTime));
+}
+
+am_Error_e CAmControlReceiver::setSourceState(am_Handle_s & handle, const am_sourceID_t sourceID, const am_SourceState_e state)
+{
+ logInfo("CAmControlReceiver::setSourceState got called, sourceID=", sourceID, "state=", state);
+ return (mRoutingSender->asyncSetSourceState(handle, sourceID, state));
+}
+
+am_Error_e CAmControlReceiver::setSinkVolume(am_Handle_s & handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time)
+{
+ logInfo("CAmControlReceiver::setSinkVolume got called, sinkID=", sinkID, "volume=", volume, "ramp=", ramp, "time=", time);
+ return (mRoutingSender->asyncSetSinkVolume(handle, sinkID, volume, ramp, time));
+}
+
+am_Error_e CAmControlReceiver::setSourceVolume(am_Handle_s & handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_CustomRampType_t rampType, const am_time_t time)
+{
+ logInfo("CAmControlReceiver::setSourceVolume got called, sourceID=", sourceID, "volume=", volume, "ramp=", rampType, "time=", time);
+ return (mRoutingSender->asyncSetSourceVolume(handle, sourceID, volume, rampType, time));
+}
+
+am_Error_e CAmControlReceiver::setSinkSoundProperty(am_Handle_s & handle, const am_sinkID_t sinkID, const am_SoundProperty_s & soundProperty)
+{
+ logInfo("CAmControlReceiver::setSinkSoundProperty got called, sinkID=", sinkID, "soundProperty.Type=", soundProperty.type, "soundProperty.value=", soundProperty.value);
+ return (mRoutingSender->asyncSetSinkSoundProperty(handle, sinkID, soundProperty));
+}
+
+am_Error_e CAmControlReceiver::setSinkSoundProperties(am_Handle_s & handle, const am_sinkID_t sinkID, const std::vector<am_SoundProperty_s> & listSoundProperties)
+{
+ logInfo("CAmControlReceiver::setSinkSoundProperties got called, sinkID=", sinkID);
+ return (mRoutingSender->asyncSetSinkSoundProperties(handle, listSoundProperties, sinkID));
+}
+
+am_Error_e CAmControlReceiver::setSourceSoundProperty(am_Handle_s & handle, const am_sourceID_t sourceID, const am_SoundProperty_s & soundProperty)
+{
+ logInfo("CAmControlReceiver::setSourceSoundProperty got called, sourceID=", sourceID, "soundProperty.Type=", soundProperty.type, "soundProperty.value=", soundProperty.value);
+ return (mRoutingSender->asyncSetSourceSoundProperty(handle, sourceID, soundProperty));
+}
+
+am_Error_e CAmControlReceiver::setSourceSoundProperties(am_Handle_s & handle, const am_sourceID_t sourceID, const std::vector<am_SoundProperty_s> & listSoundProperties)
+{
+ logInfo("CAmControlReceiver::setSourceSoundProperties got called, sourceID=", sourceID);
+ return (mRoutingSender->asyncSetSourceSoundProperties(handle, listSoundProperties, sourceID));
+}
+
+am_Error_e CAmControlReceiver::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
+{
+ logInfo("CAmControlReceiver::setDomainState got called, domainID=", domainID, "domainState=", domainState);
+ return (mRoutingSender->setDomainState(domainID, domainState));
+}
+
+am_Error_e CAmControlReceiver::abortAction(const am_Handle_s handle)
+{
+ logInfo("CAmControlReceiver::abortAction got called, handle.type=", handle.handle, "handle.handleType=", handle.handleType);
+ return (mRoutingSender->asyncAbort(handle));
+}
+
+am_Error_e CAmControlReceiver::enterDomainDB(const am_Domain_s & domainData, am_domainID_t & domainID)
+{
+ return (mDatabaseHandler->enterDomainDB(domainData, domainID));
+}
+
+am_Error_e CAmControlReceiver::enterMainConnectionDB(const am_MainConnection_s & mainConnectionData, am_mainConnectionID_t & connectionID)
+{
+ return (mDatabaseHandler->enterMainConnectionDB(mainConnectionData, connectionID));
+}
+
+am_Error_e CAmControlReceiver::enterSinkDB(const am_Sink_s & sinkData, am_sinkID_t & sinkID)
+{
+ return (mDatabaseHandler->enterSinkDB(sinkData, sinkID));
+}
+
+am_Error_e CAmControlReceiver::enterCrossfaderDB(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID)
+{
+ return (mDatabaseHandler->enterCrossfaderDB(crossfaderData, crossfaderID));
+}
+
+am_Error_e CAmControlReceiver::enterGatewayDB(const am_Gateway_s & gatewayData, am_gatewayID_t & gatewayID)
+{
+ return (mDatabaseHandler->enterGatewayDB(gatewayData, gatewayID));
+}
+
+am_Error_e CAmControlReceiver::enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID)
+{
+ return (mDatabaseHandler->enterConverterDB(converterData, converterID));
+}
+
+am_Error_e CAmControlReceiver::enterSourceDB(const am_Source_s & sourceData, am_sourceID_t & sourceID)
+{
+ return (mDatabaseHandler->enterSourceDB(sourceData, sourceID));
+}
+
+am_Error_e CAmControlReceiver::enterSinkClassDB(const am_SinkClass_s & sinkClass, am_sinkClass_t & sinkClassID)
+{
+ return (mDatabaseHandler->enterSinkClassDB(sinkClass, sinkClassID));
+}
+
+am_Error_e CAmControlReceiver::enterSourceClassDB(am_sourceClass_t & sourceClassID, const am_SourceClass_s & sourceClass)
+{
+ return (mDatabaseHandler->enterSourceClassDB(sourceClassID, sourceClass));
+}
+
+am_Error_e CAmControlReceiver::enterSystemPropertiesListDB(const std::vector<am_SystemProperty_s> & listSystemProperties)
+{
+ return (mDatabaseHandler->enterSystemProperties(listSystemProperties));
+}
+
+am_Error_e CAmControlReceiver::changeMainConnectionRouteDB(const am_mainConnectionID_t mainconnectionID, const std::vector<am_connectionID_t>& listConnectionID)
+{
+ return (mDatabaseHandler->changeMainConnectionRouteDB(mainconnectionID, listConnectionID));
+}
+
+am_Error_e CAmControlReceiver::changeMainConnectionStateDB(const am_mainConnectionID_t mainconnectionID, const am_ConnectionState_e connectionState)
+{
+ return (mDatabaseHandler->changeMainConnectionStateDB(mainconnectionID, connectionState));
+}
+
+am_Error_e CAmControlReceiver::changeSinkMainVolumeDB(const am_mainVolume_t mainVolume, const am_sinkID_t sinkID)
+{
+ return (mDatabaseHandler->changeSinkMainVolumeDB(mainVolume, sinkID));
+}
+
+am_Error_e CAmControlReceiver::changeSinkAvailabilityDB(const am_Availability_s & availability, const am_sinkID_t sinkID)
+{
+ return (mDatabaseHandler->changeSinkAvailabilityDB(availability, sinkID));
+}
+
+am_Error_e CAmControlReceiver::changDomainStateDB(const am_DomainState_e domainState, const am_domainID_t domainID)
+{
+ return (mDatabaseHandler->changDomainStateDB(domainState, domainID));
+}
+
+am_Error_e CAmControlReceiver::changeSinkMuteStateDB(const am_MuteState_e muteState, const am_sinkID_t sinkID)
+{
+ return (mDatabaseHandler->changeSinkMuteStateDB(muteState, sinkID));
+}
+
+am_Error_e CAmControlReceiver::changeMainSinkSoundPropertyDB(const am_MainSoundProperty_s & soundProperty, const am_sinkID_t sinkID)
+{
+ return (mDatabaseHandler->changeMainSinkSoundPropertyDB(soundProperty, sinkID));
+}
+
+am_Error_e CAmControlReceiver::changeMainSourceSoundPropertyDB(const am_MainSoundProperty_s & soundProperty, const am_sourceID_t sourceID)
+{
+ return (mDatabaseHandler->changeMainSourceSoundPropertyDB(soundProperty, sourceID));
+}
+
+am_Error_e CAmControlReceiver::changeSourceAvailabilityDB(const am_Availability_s & availability, const am_sourceID_t sourceID)
+{
+ return (mDatabaseHandler->changeSourceAvailabilityDB(availability, sourceID));
+}
+
+am_Error_e CAmControlReceiver::changeSystemPropertyDB(const am_SystemProperty_s & property)
+{
+ return (mDatabaseHandler->changeSystemPropertyDB(property));
+}
+
+am_Error_e CAmControlReceiver::removeMainConnectionDB(const am_mainConnectionID_t mainConnectionID)
+{
+ return (mDatabaseHandler->removeMainConnectionDB(mainConnectionID));
+}
+
+am_Error_e CAmControlReceiver::removeSinkDB(const am_sinkID_t sinkID)
+{
+ return (mDatabaseHandler->removeSinkDB(sinkID));
+}
+
+am_Error_e CAmControlReceiver::removeSourceDB(const am_sourceID_t sourceID)
+{
+ return (mDatabaseHandler->removeSourceDB(sourceID));
+}
+
+am_Error_e CAmControlReceiver::removeGatewayDB(const am_gatewayID_t gatewayID)
+{
+ return (mDatabaseHandler->removeGatewayDB(gatewayID));
+}
+
+am_Error_e CAmControlReceiver::removeConverterDB(const am_converterID_t converterID)
+{
+ return (mDatabaseHandler->removeConverterDB(converterID));
+}
+
+am_Error_e CAmControlReceiver::removeCrossfaderDB(const am_crossfaderID_t crossfaderID)
+{
+ return (mDatabaseHandler->removeCrossfaderDB(crossfaderID));
+}
+
+am_Error_e CAmControlReceiver::removeDomainDB(const am_domainID_t domainID)
+{
+ return (mDatabaseHandler->removeDomainDB(domainID));
+}
+
+am_Error_e CAmControlReceiver::getSourceClassInfoDB(const am_sourceID_t sourceID, am_SourceClass_s & classInfo) const
+{
+ return (mDatabaseHandler->getSourceClassInfoDB(sourceID, classInfo));
+}
+
+am_Error_e CAmControlReceiver::getSinkClassInfoDB(const am_sinkID_t sinkID, am_SinkClass_s & sinkClass) const
+{
+ return (mDatabaseHandler->getSinkClassInfoDB(sinkID, sinkClass));
+}
+
+am_Error_e CAmControlReceiver::getSinkInfoDB(const am_sinkID_t sinkID, am_Sink_s & sinkData) const
+{
+ return (mDatabaseHandler->getSinkInfoDB(sinkID, sinkData));
+}
+
+am_Error_e CAmControlReceiver::getSourceInfoDB(const am_sourceID_t sourceID, am_Source_s & sourceData) const
+{
+ return (mDatabaseHandler->getSourceInfoDB(sourceID, sourceData));
+}
+
+am_Error_e CAmControlReceiver::getMainConnectionInfoDB(const am_mainConnectionID_t mainConnectionID, am_MainConnection_s & mainConnectionData) const
+{
+ return (mDatabaseHandler->getMainConnectionInfoDB(mainConnectionID, mainConnectionData));
+}
+
+am_Error_e CAmControlReceiver::getGatewayInfoDB(const am_gatewayID_t gatewayID, am_Gateway_s & gatewayData) const
+{
+ return (mDatabaseHandler->getGatewayInfoDB(gatewayID, gatewayData));
+}
+
+am_Error_e CAmControlReceiver::getConverterInfoDB(const am_converterID_t converterID, am_Converter_s & converterData) const
+{
+ return (mDatabaseHandler->getConverterInfoDB(converterID, converterData));
+}
+
+
+am_Error_e CAmControlReceiver::getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s & crossfaderData) const
+{
+ return (mDatabaseHandler->getCrossfaderInfoDB(crossfaderID, crossfaderData));
+}
+
+am_Error_e CAmControlReceiver::getListSinksOfDomain(const am_domainID_t domainID, std::vector<am_sinkID_t> & listSinkID) const
+{
+ return (mDatabaseHandler->getListSinksOfDomain(domainID, listSinkID));
+}
+
+am_Error_e CAmControlReceiver::getListSourcesOfDomain(const am_domainID_t domainID, std::vector<am_sourceID_t> & listSourceID) const
+{
+ return (mDatabaseHandler->getListSourcesOfDomain(domainID, listSourceID));
+}
+
+am_Error_e CAmControlReceiver::getListCrossfadersOfDomain(const am_domainID_t domainID, std::vector<am_crossfaderID_t> & listGatewaysID) const
+{
+ return (mDatabaseHandler->getListCrossfadersOfDomain(domainID, listGatewaysID));
+}
+
+am_Error_e CAmControlReceiver::getListGatewaysOfDomain(const am_domainID_t domainID, std::vector<am_gatewayID_t> & listGatewaysID) const
+{
+ return (mDatabaseHandler->getListGatewaysOfDomain(domainID, listGatewaysID));
+}
+
+am_Error_e CAmControlReceiver::getListConvertersOfDomain(const am_domainID_t domainID,std::vector<am_converterID_t>& listConverterID) const
+{
+ return (mDatabaseHandler->getListConvertersOfDomain(domainID,listConverterID));
+}
+
+am_Error_e CAmControlReceiver::getListMainConnections(std::vector<am_MainConnection_s> & listMainConnections) const
+{
+ return (mDatabaseHandler->getListMainConnections(listMainConnections));
+}
+
+am_Error_e CAmControlReceiver::getListDomains(std::vector<am_Domain_s> & listDomains) const
+{
+ return (mDatabaseHandler->getListDomains(listDomains));
+}
+
+am_Error_e CAmControlReceiver::getListConnections(std::vector<am_Connection_s> & listConnections) const
+{
+ return (mDatabaseHandler->getListConnections(listConnections));
+}
+
+am_Error_e CAmControlReceiver::getListSinks(std::vector<am_Sink_s> & listSinks) const
+{
+ return (mDatabaseHandler->getListSinks(listSinks));
+}
+
+am_Error_e CAmControlReceiver::getListSources(std::vector<am_Source_s> & listSources) const
+{
+ return (mDatabaseHandler->getListSources(listSources));
+}
+
+am_Error_e CAmControlReceiver::getListSourceClasses(std::vector<am_SourceClass_s> & listSourceClasses) const
+{
+ return (mDatabaseHandler->getListSourceClasses(listSourceClasses));
+}
+
+am_Error_e CAmControlReceiver::getListHandles(std::vector<am_Handle_s> & listHandles) const
+{
+ return (mRoutingSender->getListHandles(listHandles));
+}
+
+am_Error_e CAmControlReceiver::getListCrossfaders(std::vector<am_Crossfader_s> & listCrossfaders) const
+{
+ return (mDatabaseHandler->getListCrossfaders(listCrossfaders));
+}
+
+am_Error_e CAmControlReceiver::getListGateways(std::vector<am_Gateway_s> & listGateways) const
+{
+ return (mDatabaseHandler->getListGateways(listGateways));
+}
+
+am_Error_e CAmControlReceiver::getListConverters(std::vector<am_Converter_s>& listConverters) const
+{
+ return (mDatabaseHandler->getListConverters(listConverters));
+}
+
+am_Error_e CAmControlReceiver::getListSinkClasses(std::vector<am_SinkClass_s> & listSinkClasses) const
+{
+ return (mDatabaseHandler->getListSinkClasses(listSinkClasses));
+}
+
+am_Error_e CAmControlReceiver::getListSystemProperties(std::vector<am_SystemProperty_s> & listSystemProperties) const
+{
+ return (mDatabaseHandler->getListSystemProperties(listSystemProperties));
+}
+
+am_Error_e CAmControlReceiver::changeSinkClassInfoDB(const am_SinkClass_s & classInfo)
+{
+ return (mDatabaseHandler->changeSinkClassInfoDB(classInfo));
+}
+
+am_Error_e CAmControlReceiver::changeSourceClassInfoDB(const am_SourceClass_s & classInfo)
+{
+ return(mDatabaseHandler->changeSourceClassInfoDB(classInfo));
+}
+
+am_Error_e CAmControlReceiver::removeSinkClassDB(const am_sinkClass_t sinkClassID)
+{
+ return (mDatabaseHandler->removeSinkClassDB(sinkClassID));
+}
+
+am_Error_e CAmControlReceiver::removeSourceClassDB(const am_sourceClass_t sourceClassID)
+{
+ return (mDatabaseHandler->removeSourceClassDB(sourceClassID));
+}
+
+void CAmControlReceiver::setCommandReady()
+{
+ logInfo("CAmControlReceiver::setCommandReady got called");
+ mCommandSender->setCommandReady();
+}
+
+void CAmControlReceiver::setRoutingReady()
+{
+ logInfo("CAmControlReceiver::setRoutingReady got called");
+ mRoutingSender->setRoutingReady();
+}
+
+void CAmControlReceiver::confirmControllerReady(const am_Error_e error)
+{
+ if (error!=E_OK)
+ logError("CAmControlReceiver::confirmControllerReady controller reported error", error);
+}
+
+void CAmControlReceiver::confirmControllerRundown(const am_Error_e error)
+{
+ if (error!=E_OK)
+ {
+ logError("CAmControlReceiver::confirmControllerRundown() exited with error ",error);
+ //we might be blocked here -> so lets better exit right away
+ throw std::runtime_error("controller Confirmed with error");
+ }
+
+ logInfo ("CAmControlReceiver::confirmControllerRundown(), will exit now");
+
+ //end the mainloop here...
+ mSocketHandler->exit_mainloop();
+}
+
+am_Error_e CAmControlReceiver::getSocketHandler(CAmSocketHandler *& socketHandler)
+{
+ socketHandler = mSocketHandler;
+ return (E_OK);
+}
+
+void CAmControlReceiver::setCommandRundown()
+{
+ logInfo("CAmControlReceiver::setCommandRundown got called");
+ mCommandSender->setCommandRundown();
+}
+
+void CAmControlReceiver::setRoutingRundown()
+{
+ logInfo("CAmControlReceiver::setRoutingRundown got called");
+ mRoutingSender->setRoutingRundown();
+}
+
+void CAmControlReceiver::getInterfaceVersion(std::string & version) const
+{
+ version = ControlVersion;
+}
+
+am_Error_e CAmControlReceiver::changeSourceDB(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ logInfo("CAmControlReceiver::changeSourceDB was called, sourceID", sourceID);
+ return (mDatabaseHandler->changeSourceDB(sourceID,sourceClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
+}
+
+am_Error_e CAmControlReceiver::changeSinkDB(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ logInfo("CAmControlReceiver::changeSinkDB was called with sinkID", sinkID);
+ return (mDatabaseHandler->changeSinkDB(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
+}
+
+am_Error_e CAmControlReceiver::changeGatewayDB(const am_gatewayID_t gatewayID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ logInfo("CAmControlReceiver::changeGatewayDB was called with gatewayID", gatewayID);
+ return (mDatabaseHandler->changeGatewayDB(gatewayID,listSourceConnectionFormats,listSinkConnectionFormats,convertionMatrix));
+}
+
+am_Error_e CAmControlReceiver::changeConverterDB(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ logInfo("CAmControlReceiver::changeConverterDB was called with converterID", converterID);
+ return (mDatabaseHandler->changeConverterDB(converterID,listSourceConnectionFormats,listSinkConnectionFormats,convertionMatrix));
+}
+
+am_Error_e CAmControlReceiver::setVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes)
+{
+ logInfo("CAmControlReceiver::setVolumes got called");
+ return (mRoutingSender->asyncSetVolumes(handle,listVolumes));
+}
+
+am_Error_e CAmControlReceiver::setSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration)
+{
+ logInfo("CAmControlReceiver::setSinkNotificationConfiguration called, sinkID=",sinkID,"notificationConfiguration.type=",notificationConfiguration.type,"notificationConfiguration.status",notificationConfiguration.status,"notificationConfiguration.parameter",notificationConfiguration.parameter);
+ return (mRoutingSender->asyncSetSinkNotificationConfiguration(handle,sinkID,notificationConfiguration));
+}
+
+am_Error_e CAmControlReceiver::setSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration)
+{
+ logInfo("CAmControlReceiver::setSourceNotificationConfiguration called, sourceID=",sourceID,"notificationConfiguration.type=",notificationConfiguration.type,"notificationConfiguration.status",notificationConfiguration.status,"notificationConfiguration.parameter",notificationConfiguration.parameter);
+ return (mRoutingSender->asyncSetSourceNotificationConfiguration(handle,sourceID,notificationConfiguration));
+}
+
+void CAmControlReceiver::sendMainSinkNotificationPayload(const am_sinkID_t sinkID, const am_NotificationPayload_s& notificationPayload)
+{
+ logInfo("CAmControlReceiver::sendSinkMainNotificationPayload called, sinkID=",sinkID,"type=",notificationPayload.type,"value=",notificationPayload.value);
+ mCommandSender->cbSinkNotification(sinkID,notificationPayload);
+}
+
+void CAmControlReceiver::sendMainSourceNotificationPayload(const am_sourceID_t sourceID, const am_NotificationPayload_s& notificationPayload)
+{
+ logInfo("CAmControlReceiver::sendSourceMainNotificationPayload called, sourceID=",sourceID,"type=",notificationPayload.type,"value=",notificationPayload.value);
+ mCommandSender->cbSourceNotification(sourceID,notificationPayload);
+}
+
+am_Error_e CAmControlReceiver::changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration)
+{
+ logInfo("CAmControlReceiver::changeMainSinkNotificationConfigurationDB was called with sinkID", sinkID);
+ return (mDatabaseHandler->changeMainSinkNotificationConfigurationDB(sinkID,mainNotificationConfiguration));
+}
+
+am_Error_e CAmControlReceiver::changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration)
+{
+ logInfo("CAmControlReceiver::changeMainSourceNotificationConfigurationDB was called with sourceID", sourceID);
+ return (mDatabaseHandler->changeMainSourceNotificationConfigurationDB(sourceID,mainNotificationConfiguration));
+}
+
+am_Error_e CAmControlReceiver::getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s>& listSoundproperties) const
+{
+ logInfo("CAmControlReceiver::getListMainSinkSoundProperties was called, sinkID", sinkID);
+ return (mDatabaseHandler->getListMainSinkSoundProperties(sinkID,listSoundproperties));
+}
+
+am_Error_e CAmControlReceiver::getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s>& listSoundproperties) const
+{
+ logInfo("CAmControlReceiver::getListMainSourceSoundProperties was called, sourceID", sourceID);
+ return (mDatabaseHandler->getListMainSourceSoundProperties(sourceID, listSoundproperties));
+}
+
+am_Error_e CAmControlReceiver::getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const
+{
+ logInfo("CAmControlReceiver::getListSinkSoundProperties was called, sinkID", sinkID);
+ return (mDatabaseHandler->getListSinkSoundProperties(sinkID,listSoundproperties));
+}
+
+am_Error_e CAmControlReceiver::getListSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_SoundProperty_s>& listSoundproperties) const
+{
+ logInfo("CAmControlReceiver::getListSourceSoundProperties was called, sourceID", sourceID);
+ return (mDatabaseHandler->getListSourceSoundProperties(sourceID, listSoundproperties));
+}
+
+am_Error_e CAmControlReceiver::getMainSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const
+{
+ logInfo("CAmControlReceiver::getMainSinkSoundPropertyValue was called, sinkID", sinkID);
+ return (mDatabaseHandler->getMainSinkSoundPropertyValue(sinkID,propertyType,value));
+}
+
+am_Error_e CAmControlReceiver::getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const
+{
+ logInfo("CAmControlReceiver::getSinkSoundPropertyValue was called, sinkID", sinkID);
+ return (mDatabaseHandler->getSinkSoundPropertyValue(sinkID,propertyType,value));
+}
+
+am_Error_e CAmControlReceiver::getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const
+{
+ logInfo("CAmControlReceiver::getMainSourceSoundPropertyValue was called, sourceID", sourceID);
+ return (mDatabaseHandler->getMainSourceSoundPropertyValue(sourceID,propertyType,value));
+}
+
+am_Error_e CAmControlReceiver::getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const
+{
+ logInfo("CAmControlReceiver::getSourceSoundPropertyValue was called, sourceID", sourceID);
+ return (mDatabaseHandler->getSourceSoundPropertyValue(sourceID,propertyType,value));
+}
+
+am_Error_e CAmControlReceiver::resyncConnectionState(const am_domainID_t domainID,std::vector<am_Connection_s>& listOfExistingConnections)
+{
+ logInfo("CAmControlReceiver::resyncConnectionState was called, domainID", domainID);
+ return (mRoutingSender->resyncConnectionState(domainID,listOfExistingConnections));
+}
+
+}
+
diff --git a/AudioManagerCore/src/CAmControlSender.cpp b/AudioManagerCore/src/CAmControlSender.cpp
new file mode 100644
index 0000000..10125d5
--- /dev/null
+++ b/AudioManagerCore/src/CAmControlSender.cpp
@@ -0,0 +1,571 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmControlSender.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmControlSender.h"
+#include <cassert>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include "TAmPluginTemplate.h"
+#include "CAmDltWrapper.h"
+
+namespace am
+{
+
+#define REQUIRED_INTERFACE_VERSION_MAJOR 1 //!< major interface version. All versions smaller than this will be rejected
+#define REQUIRED_INTERFACE_VERSION_MINOR 0 //!< minor interface version. All versions smaller than this will be rejected
+
+CAmControlSender* CAmControlSender::mInstance=NULL;
+
+CAmControlSender::CAmControlSender(std::string controlPluginFile,CAmSocketHandler* sockethandler) :
+ receiverCallbackT(this, &CAmControlSender::receiverCallback),//
+ checkerCallbackT(this, &CAmControlSender::checkerCallback),//
+ dispatcherCallbackT(this, &CAmControlSender::dispatcherCallback), //
+ mPipe(), //
+ mlibHandle(NULL), //
+ mController(NULL), //
+ mSignal(0)
+{
+ assert(sockethandler);
+
+ //Check if a folder is given, then select the first plugin
+ struct stat buf;
+ const char* conFile(controlPluginFile.c_str());
+ stat(conFile, &buf);
+ if (S_ISDIR(buf.st_mode))
+ {
+ std::string directoryName(controlPluginFile);
+ logInfo("Searching for ControlPlugin in", directoryName);
+ DIR *directory = opendir(directoryName.c_str());
+
+ if (!directory)
+ {
+ logError("Error opening directory ", directoryName);
+ throw std::runtime_error("Controller directory could not be openend");
+ }
+
+ // iterate content of directory
+ struct dirent *itemInDirectory = 0;
+ while ((itemInDirectory = readdir(directory)))
+ {
+ unsigned char entryType = itemInDirectory->d_type;
+ std::string entryName = itemInDirectory->d_name;
+ std::string fullName = directoryName + "/" + entryName;
+
+ bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
+ bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
+
+ // Handle cases where readdir() could not determine the file type
+ if (entryType == DT_UNKNOWN) {
+ struct stat buf;
+
+ if (stat(fullName.c_str(), &buf)) {
+ logInfo(__PRETTY_FUNCTION__,"Failed to stat file: ", entryName, errno);
+ continue;
+ }
+
+ regularFile = S_ISREG(buf.st_mode);
+ }
+
+ if (regularFile && sharedLibExtension)
+ {
+ controlPluginFile=directoryName + "/" + entryName;
+ logInfo("Found ControlPlugin:", controlPluginFile);
+ break;
+ }
+ }
+ closedir(directory);
+
+ }
+
+ std::ifstream isfile(controlPluginFile.c_str());
+ if (!isfile)
+ {
+ logError("ControlSender::ControlSender: Controller plugin not found:", controlPluginFile);
+ throw std::runtime_error("Could not find controller plugin!");
+ }
+ else if (!controlPluginFile.empty())
+ {
+ mInstance=this;
+ IAmControlSend* (*createFunc)();
+ createFunc = getCreateFunction<IAmControlSend*()>(controlPluginFile, mlibHandle);
+ assert(createFunc!=NULL);
+ mController = createFunc();
+
+ //check libversion
+ std::string version, cVersion(ControlVersion);
+ mController->getInterfaceVersion(version);
+ uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion;
+ std::istringstream(version.substr(0, 1)) >> majorVersion;
+ std::istringstream(version.substr(2, 1)) >> minorVersion;
+ std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion;
+ std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion;
+
+
+
+ if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion)))
+ {
+ logError("ControlSender::ControlSender: Interface Version of Controller too old, exiting now");
+ throw std::runtime_error("Interface Version of Controller too old");
+ }
+ }
+ else
+ {
+ logError("ControlSender::ControlSender: No controller loaded !");
+ }
+
+ //here we need a pipe to be able to call the rundown function out of the mainloop
+ if (pipe(mPipe) == -1)
+ {
+ logError("CAmControlSender could not create pipe!");
+ }
+
+ //add the pipe to the poll - nothing needs to be proccessed here we just need the pipe to trigger the ppoll
+ short event = 0;
+ sh_pollHandle_t handle;
+ event |= POLLIN;
+ sockethandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, handle);
+}
+
+CAmControlSender::~CAmControlSender()
+{
+ //if (mlibHandle)
+ // dlclose(mlibHandle);
+}
+
+am_Error_e CAmControlSender::hookUserConnectionRequest(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t & mainConnectionID)
+{
+ assert(mController);
+ return (mController->hookUserConnectionRequest(sourceID, sinkID, mainConnectionID));
+}
+
+am_Error_e CAmControlSender::hookUserDisconnectionRequest(const am_mainConnectionID_t connectionID)
+{
+ assert(mController);
+ return (mController->hookUserDisconnectionRequest(connectionID));
+}
+
+am_Error_e CAmControlSender::hookUserSetMainSinkSoundProperty(const am_sinkID_t sinkID, const am_MainSoundProperty_s & soundProperty)
+{
+ assert(mController);
+ return (mController->hookUserSetMainSinkSoundProperty(sinkID, soundProperty));
+}
+
+am_Error_e CAmControlSender::hookUserSetMainSourceSoundProperty(const am_sourceID_t sourceID, const am_MainSoundProperty_s & soundProperty)
+{
+ assert(mController);
+ return (mController->hookUserSetMainSourceSoundProperty(sourceID, soundProperty));
+}
+
+am_Error_e CAmControlSender::hookUserSetSystemProperty(const am_SystemProperty_s & property)
+{
+ assert(mController);
+ return (mController->hookUserSetSystemProperty(property));
+}
+
+am_Error_e CAmControlSender::hookUserVolumeChange(const am_sinkID_t sinkID, const am_mainVolume_t newVolume)
+{
+ assert(mController);
+ return (mController->hookUserVolumeChange(sinkID, newVolume));
+}
+
+am_Error_e CAmControlSender::hookUserVolumeStep(const am_sinkID_t sinkID, const int16_t increment)
+{
+ assert(mController);
+ return (mController->hookUserVolumeStep(sinkID, increment));
+}
+
+am_Error_e CAmControlSender::hookUserSetSinkMuteState(const am_sinkID_t sinkID, const am_MuteState_e muteState)
+{
+ assert(mController);
+ return (mController->hookUserSetSinkMuteState(sinkID, muteState));
+}
+
+am_Error_e CAmControlSender::hookSystemRegisterDomain(const am_Domain_s & domainData, am_domainID_t & domainID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterDomain(domainData, domainID));
+}
+
+am_Error_e CAmControlSender::hookSystemDeregisterDomain(const am_domainID_t domainID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterDomain(domainID));
+}
+
+void CAmControlSender::hookSystemDomainRegistrationComplete(const am_domainID_t domainID)
+{
+ assert(mController);
+ return (mController->hookSystemDomainRegistrationComplete(domainID));
+}
+
+am_Error_e CAmControlSender::hookSystemRegisterSink(const am_Sink_s & sinkData, am_sinkID_t & sinkID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterSink(sinkData, sinkID));
+}
+
+am_Error_e CAmControlSender::hookSystemDeregisterSink(const am_sinkID_t sinkID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterSink(sinkID));
+}
+
+am_Error_e CAmControlSender::hookSystemRegisterSource(const am_Source_s & sourceData, am_sourceID_t & sourceID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterSource(sourceData, sourceID));
+}
+
+am_Error_e CAmControlSender::hookSystemDeregisterSource(const am_sourceID_t sourceID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterSource(sourceID));
+}
+
+am_Error_e CAmControlSender::hookSystemRegisterGateway(const am_Gateway_s & gatewayData, am_gatewayID_t & gatewayID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterGateway(gatewayData, gatewayID));
+}
+
+am_Error_e CAmControlSender::hookSystemRegisterConverter(const am_Converter_s& converterData, am_converterID_t& converterID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterConverter(converterData, converterID));
+}
+
+am_Error_e CAmControlSender::hookSystemDeregisterGateway(const am_gatewayID_t gatewayID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterGateway(gatewayID));
+}
+
+am_Error_e CAmControlSender::hookSystemDeregisterConverter(const am_converterID_t converterID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterConverter(converterID));
+}
+
+am_Error_e CAmControlSender::hookSystemRegisterCrossfader(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterCrossfader(crossfaderData, crossfaderID));
+}
+
+am_Error_e CAmControlSender::hookSystemDeregisterCrossfader(const am_crossfaderID_t crossfaderID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterCrossfader(crossfaderID));
+}
+
+void CAmControlSender::hookSystemSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume)
+{
+ assert(mController);
+ mController->hookSystemSinkVolumeTick(handle, sinkID, volume);
+}
+
+void CAmControlSender::hookSystemSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume)
+{
+ assert(mController);
+ mController->hookSystemSourceVolumeTick(handle, sourceID, volume);
+}
+
+void CAmControlSender::hookSystemInterruptStateChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState)
+{
+ assert(mController);
+ mController->hookSystemInterruptStateChange(sourceID, interruptState);
+}
+
+void CAmControlSender::hookSystemSinkAvailablityStateChange(const am_sinkID_t sinkID, const am_Availability_s & availability)
+{
+ assert(mController);
+ mController->hookSystemSinkAvailablityStateChange(sinkID, availability);
+}
+
+void CAmControlSender::hookSystemSourceAvailablityStateChange(const am_sourceID_t sourceID, const am_Availability_s & availability)
+{
+ assert(mController);
+ mController->hookSystemSourceAvailablityStateChange(sourceID, availability);
+}
+
+void CAmControlSender::hookSystemDomainStateChange(const am_domainID_t domainID, const am_DomainState_e state)
+{
+ assert(mController);
+ mController->hookSystemDomainStateChange(domainID, state);
+}
+
+void CAmControlSender::hookSystemReceiveEarlyData(const std::vector<am_EarlyData_s> & data)
+{
+ assert(mController);
+ mController->hookSystemReceiveEarlyData(data);
+}
+
+void CAmControlSender::hookSystemSpeedChange(const am_speed_t speed)
+{
+ assert(mController);
+ mController->hookSystemSpeedChange(speed);
+}
+
+void CAmControlSender::hookSystemTimingInformationChanged(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time)
+{
+ assert(mController);
+ mController->hookSystemTimingInformationChanged(mainConnectionID, time);
+}
+
+void CAmControlSender::cbAckConnect(const am_Handle_s handle, const am_Error_e errorID)
+{
+ assert(mController);
+ mController->cbAckConnect(handle, errorID);
+}
+
+void CAmControlSender::cbAckDisconnect(const am_Handle_s handle, const am_Error_e errorID)
+{
+ assert(mController);
+ mController->cbAckDisconnect(handle, errorID);
+}
+
+void CAmControlSender::cbAckCrossFade(const am_Handle_s handle, const am_HotSink_e hostsink, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckCrossFade(handle, hostsink, error);
+}
+
+void CAmControlSender::cbAckSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSinkVolumeChange(handle, volume, error);
+}
+
+void CAmControlSender::cbAckSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSourceVolumeChange(handle, volume, error);
+}
+
+void CAmControlSender::cbAckSetSourceState(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSourceState(handle, error);
+}
+
+void CAmControlSender::cbAckSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSourceSoundProperty(handle, error);
+}
+
+am_Error_e CAmControlSender::startupController(IAmControlReceive *controlreceiveinterface)
+{
+ if (!mController)
+ {
+ logError("ControlSender::startupController: no Controller to startup!");
+ throw std::runtime_error("ControlSender::startupController: no Controller to startup! Exiting now ...");
+ return (E_NON_EXISTENT);
+ }
+ return (mController->startupController(controlreceiveinterface));
+}
+
+void CAmControlSender::cbAckSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSinkSoundProperty(handle, error);
+}
+
+void CAmControlSender::cbAckSetSinkSoundProperties(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSinkSoundProperties(handle, error);
+}
+
+void CAmControlSender::cbAckSetSourceSoundProperties(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSourceSoundProperties(handle, error);
+}
+
+void CAmControlSender::setControllerReady()
+{
+ assert(mController);
+ mController->setControllerReady();
+}
+
+void CAmControlSender::setControllerRundown(const int16_t signal)
+{
+ assert(mController);
+ logInfo("CAmControlSender::setControllerRundown received, signal=",signal);
+ mController->setControllerRundown(signal);
+}
+
+am_Error_e am::CAmControlSender::getConnectionFormatChoice(const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_Route_s listRoute, const std::vector<am_CustomConnectionFormat_t> listPossibleConnectionFormats, std::vector<am_CustomConnectionFormat_t> & listPrioConnectionFormats)
+{
+ assert(mController);
+ return (mController->getConnectionFormatChoice(sourceID, sinkID, listRoute, listPossibleConnectionFormats, listPrioConnectionFormats));
+}
+
+void CAmControlSender::getInterfaceVersion(std::string & version) const
+{
+ version = ControlVersion;
+}
+
+void CAmControlSender::confirmCommandReady(const am_Error_e error)
+{
+ assert(mController);
+ mController->confirmCommandReady(error);
+}
+
+void CAmControlSender::confirmRoutingReady(const am_Error_e error)
+{
+ assert(mController);
+ mController->confirmRoutingReady(error);
+}
+
+void CAmControlSender::confirmCommandRundown(const am_Error_e error)
+{
+ assert(mController);
+ mController->confirmCommandRundown(error);
+}
+
+void CAmControlSender::confirmRoutingRundown(const am_Error_e error)
+{
+ assert(mController);
+ mController->confirmRoutingRundown(error);
+}
+
+am_Error_e CAmControlSender::hookSystemUpdateSink(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ assert(mController);
+ return (mController->hookSystemUpdateSink(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
+}
+
+am_Error_e CAmControlSender::hookSystemUpdateSource(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ assert(mController);
+ return (mController->hookSystemUpdateSource(sourceID,sourceClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
+}
+
+am_Error_e CAmControlSender::hookSystemUpdateGateway(const am_gatewayID_t gatewayID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFromats, const std::vector<bool>& convertionMatrix)
+{
+ assert(mController);
+ return (mController->hookSystemUpdateGateway(gatewayID,listSourceConnectionFormats,listSinkConnectionFromats,convertionMatrix));
+}
+
+am_Error_e CAmControlSender::hookSystemUpdateConverter(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFromats, const std::vector<bool>& convertionMatrix)
+{
+ assert(mController);
+ return (mController->hookSystemUpdateConverter(converterID,listSourceConnectionFormats,listSinkConnectionFromats,convertionMatrix));
+}
+
+void CAmControlSender::cbAckSetVolume(const am_Handle_s handle, const std::vector<am_Volumes_s>& listVolumes, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetVolumes(handle,listVolumes,error);
+}
+
+void CAmControlSender::cbAckSetSinkNotificationConfiguration(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSinkNotificationConfiguration(handle,error);
+}
+
+void CAmControlSender::cbAckSetSourceNotificationConfiguration(const am_Handle_s handle, const am_Error_e error)
+{
+ assert(mController);
+ mController->cbAckSetSourceNotificationConfiguration(handle,error);
+}
+
+void CAmControlSender::hookSinkNotificationDataChanged(const am_sinkID_t sinkID, const am_NotificationPayload_s& payload)
+{
+ assert(mController);
+ mController->hookSinkNotificationDataChanged(sinkID,payload);
+}
+
+void CAmControlSender::hookSourceNotificationDataChanged(const am_sourceID_t sourceID, const am_NotificationPayload_s& payload)
+{
+ assert(mController);
+ mController->hookSourceNotificationDataChanged(sourceID,payload);
+}
+
+am_Error_e CAmControlSender::hookUserSetMainSinkNotificationConfiguration(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration)
+{
+ assert(mController);
+ return (mController->hookUserSetMainSinkNotificationConfiguration(sinkID,notificationConfiguration));
+}
+
+am_Error_e CAmControlSender::hookUserSetMainSourceNotificationConfiguration(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration)
+{
+ assert(mController);
+ return (mController->hookUserSetMainSourceNotificationConfiguration(sourceID,notificationConfiguration));
+}
+
+void CAmControlSender::receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
+{
+ (void) handle;
+ (void) userData;
+ //get the signal number from the socket
+ ssize_t result = read(pollfd.fd, &mSignal, sizeof(mSignal));
+}
+
+bool CAmControlSender::checkerCallback(const sh_pollHandle_t handle, void* userData)
+{
+ (void) handle;
+ (void) userData;
+ return (true);
+}
+
+void CAmControlSender::hookSystemSingleTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t time)
+{
+ assert(mController);
+ mController->hookSystemSingleTimingInformationChanged(connectionID,time);
+}
+
+/**for testing only contructor - do not use !
+ *
+ */
+CAmControlSender::CAmControlSender() :
+ receiverCallbackT(this, &CAmControlSender::receiverCallback),//
+ checkerCallbackT(this, &CAmControlSender::checkerCallback),//
+ dispatcherCallbackT(this, &CAmControlSender::dispatcherCallback), //
+ mPipe(), //
+ mlibHandle(NULL), //
+ mController(NULL), //
+ mSignal(0)
+{
+ logInfo("CAmControlSender was loaded in test mode!");
+}
+
+bool CAmControlSender::dispatcherCallback(const sh_pollHandle_t handle, void* userData)
+{
+ (void)handle;
+ (void)userData;
+ setControllerRundown(mSignal);
+ return (false);
+}
+
+}
+
+
diff --git a/AudioManagerCore/src/CAmDatabaseHandlerMap.cpp b/AudioManagerCore/src/CAmDatabaseHandlerMap.cpp
new file mode 100644
index 0000000..929c8d5
--- /dev/null
+++ b/AudioManagerCore/src/CAmDatabaseHandlerMap.cpp
@@ -0,0 +1,3079 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Aleksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2013
+ *
+ * \file CAmDatabaseHandlerMap.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <iostream>
+#include <cassert>
+#include <stdexcept>
+#include <vector>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <limits>
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmDatabaseObserver.h"
+#include "CAmRouter.h"
+#include "CAmDltWrapper.h"
+
+
+#ifdef WITH_DATABASE_CHANGE_CHECK
+# define DB_COND_UPDATE_RIE(x,y) \
+ if (isDataEqual(x,y)) return (E_NO_CHANGE); else x = y
+# define DB_COND_UPDATE_INIT \
+ bool modified = false
+# define DB_COND_UPDATE(x,y) \
+ if (!isDataEqual(x,y)) { x = y; modified = true; }
+# define DB_COND_ISMODIFIED \
+ (modified == true)
+#else
+# define DB_COND_UPDATE_RIE(x,y) \
+ x = y
+# define DB_COND_UPDATE_INIT
+# define DB_COND_UPDATE(x,y) \
+ x = y
+# define DB_COND_ISMODIFIED \
+ (true)
+#endif
+
+
+namespace am
+{
+
+/*
+ * Checks if content of data is equal
+ */
+template <typename T> bool isDataEqual(const T & left, const T & right)
+{
+ return static_cast<bool>(!std::memcmp(&left, &right, sizeof(T)));
+}
+
+template <typename T, typename L = std::vector<T> > bool isDataEqual(const L & left, const L & right)
+{
+ return std::equal(left.begin(), left.end(), right.begin(), isDataEqual);
+}
+
+
+/*
+ * Returns an object for given key
+ */
+template <typename TMapKeyType, class TMapObjectType> TMapObjectType const * objectForKeyIfExistsInMap(const TMapKeyType & key, const std::unordered_map<TMapKeyType,TMapObjectType> & map)
+{
+ typename std::unordered_map<TMapKeyType,TMapObjectType>::const_iterator iter = map.find(key);
+ if( iter!=map.end() )
+ return &iter->second;
+ return NULL;
+}
+
+/*
+ * Checks whether any object with key exists in a given map
+ */
+template <typename TMapKeyType, class TMapObjectType> bool existsObjectWithKeyInMap(const TMapKeyType & key, const std::unordered_map<TMapKeyType,TMapObjectType> & map)
+{
+ return objectForKeyIfExistsInMap(key, map)!=NULL;
+}
+
+/**
+ * \brief Returns an object matching predicate.
+ *
+ * Convenient method for searching in a given map.
+ *
+ * @param map Map reference.
+ * @param comparator Search predicate.
+ * @return NULL or pointer to the found object.
+ */
+template <class TReturn, typename TIdentifier> const TReturn * objectMatchingPredicate(const std::unordered_map<TIdentifier, TReturn> & map,
+ std::function<bool(const TReturn & refObject)> comparator)
+{
+ typename std::unordered_map<TIdentifier, TReturn>::const_iterator elementIterator = map.begin();
+ for (;elementIterator != map.end(); ++elementIterator)
+ {
+ if( comparator(elementIterator->second) )
+ return &elementIterator->second;
+ }
+ return NULL;
+}
+
+
+/* Domain */
+
+void CAmDatabaseHandlerMap::CAmDomain::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Domain(" << name.c_str() << ") id(" << domainID << ")" << std::endl <<
+ "bus name(" << busname.c_str() <<
+ ") node name(" << nodename.c_str() <<
+ ") early(" << early <<
+ ") domainID(" << domainID <<
+ ") complete(" << complete <<
+ ") state(" << state <<
+ ") reserved(" << reserved << ")" << std::endl;
+ outString = fmt.str();
+}
+
+/* Source */
+
+void CAmDatabaseHandlerMap::CAmSource::getSourceType(am_SourceType_s & sourceType) const
+{
+ sourceType.name = name;
+ sourceType.sourceClassID = sourceClassID;
+ sourceType.availability = available;
+ sourceType.sourceID = sourceID;
+}
+
+void CAmDatabaseHandlerMap::CAmSource::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Source(" << name.c_str() << ") id(" << sourceID << ")" << std::endl <<
+ "sourceClassID(" << sourceClassID <<
+ ") domainID(" << domainID <<
+ ") visible(" << visible <<
+ ") volume(" << volume <<
+ ") interruptState(" << interruptState <<
+ ") sourceState(" << sourceState <<
+ ") reserved(" << reserved << ")" <<
+ ") available([availability:" << available.availability << " availabilityReason:" << available.availabilityReason << "]"
+ ") listSoundProperties (";
+ std::for_each(listSoundProperties.begin(), listSoundProperties.end(), [&](const am_SoundProperty_s & ref) {
+ fmt << "[type:" << ref.type << " value:" << ref.value <<"]";
+ });
+ fmt << ") listConnectionFormats (";
+ std::for_each(listConnectionFormats.begin(), listConnectionFormats.end(), [&](const am_CustomConnectionFormat_t & ref) {
+ fmt << "[" << ref << "]";
+ });
+ fmt << ") listMainSoundProperties (";
+ std::for_each(listMainSoundProperties.begin(), listMainSoundProperties.end(), [&](const am_MainSoundProperty_s & ref) {
+ fmt << "[type:" << ref.type << " value:" << ref.value <<"]";
+ });
+ fmt << ") listMainNotificationConfigurations (";
+ std::for_each(listMainNotificationConfigurations.begin(), listMainNotificationConfigurations.end(), [&](const am_NotificationConfiguration_s & ref) {
+ fmt << "[type:" << ref.type << " status:" << ref.status << " parameter:" << ref.parameter <<"]";
+ });
+ fmt << ") listNotificationConfigurations (";
+ std::for_each(listNotificationConfigurations.begin(), listNotificationConfigurations.end(), [&](const am_NotificationConfiguration_s & ref) {
+ fmt << "[type:" << ref.type << " status:" << ref.status << " parameter:" << ref.parameter <<"]";
+ });
+ fmt << ")" << std::endl;
+ outString = fmt.str();
+}
+
+/* Sink */
+
+void CAmDatabaseHandlerMap::CAmSink::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Sink(" << name.c_str() << ") id(" << sinkID << ")" << std::endl <<
+ "sinkClassID(" << sinkClassID <<
+ ") domainID(" << domainID <<
+ ") visible(" << visible <<
+ ") volume(" << volume <<
+ ") muteState(" << muteState <<
+ ") mainVolume(" << mainVolume <<
+ ") reserved(" << reserved << ")" <<
+ ") available([availability:" << available.availability << " availabilityReason:" << available.availabilityReason << "]"
+ ") listSoundProperties (";
+ std::for_each(listSoundProperties.begin(), listSoundProperties.end(), [&](const am_SoundProperty_s & ref) {
+ fmt << "[type:" << ref.type << " value:" << ref.value <<"]";
+ });
+ fmt << ") listConnectionFormats (";
+ std::for_each(listConnectionFormats.begin(), listConnectionFormats.end(), [&](const am_CustomConnectionFormat_t & ref) {
+ fmt << "[" << ref << "]";
+ });
+ fmt << ") listMainSoundProperties (";
+ std::for_each(listMainSoundProperties.begin(), listMainSoundProperties.end(), [&](const am_MainSoundProperty_s & ref) {
+ fmt << "[type:" << ref.type << " value:" << ref.value <<"]";
+ });
+ fmt << ") listMainNotificationConfigurations (";
+ std::for_each(listMainNotificationConfigurations.begin(), listMainNotificationConfigurations.end(), [&](const am_NotificationConfiguration_s & ref) {
+ fmt << "[type:" << ref.type << " status:" << ref.status << " parameter:" << ref.parameter <<"]";
+ });
+ fmt << ") listNotificationConfigurations (";
+ std::for_each(listNotificationConfigurations.begin(), listNotificationConfigurations.end(), [&](const am_NotificationConfiguration_s & ref) {
+ fmt << "[type:" << ref.type << " status:" << ref.status << " parameter:" << ref.parameter <<"]";
+ });
+ fmt << ")" << std::endl;
+ outString = fmt.str();
+}
+
+void CAmDatabaseHandlerMap::CAmSink::getSinkType(am_SinkType_s & sinkType) const
+{
+ sinkType.name = name;
+ sinkType.sinkID = sinkID;
+ sinkType.availability = available;
+ sinkType.muteState = muteState;
+ sinkType.volume = mainVolume;
+ sinkType.sinkClassID = sinkClassID;
+}
+
+/* Connection */
+
+void CAmDatabaseHandlerMap::CAmConnection::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Connection id(" << connectionID << ") " << std::endl <<
+ "sourceID(" << sourceID <<
+ ") sinkID(" << sinkID <<
+ ") delay(" << delay <<
+ ") connectionFormat(" << connectionFormat <<
+ ") reserved(" << reserved << ")" << std::endl;
+ outString = fmt.str();
+}
+
+/* Main Connection */
+
+void CAmDatabaseHandlerMap::CAmMainConnection::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "MainConnection id(" << mainConnectionID << ") " << std::endl <<
+ "connectionState(" << connectionState <<
+ ") sinkID(" << sinkID <<
+ ") sourceID(" << sourceID <<
+ ") delay(" << delay <<
+ ") listConnectionID (";
+ std::for_each(listConnectionID.begin(), listConnectionID.end(), [&](const am_connectionID_t & connID) {
+ fmt << "["<< connID << "]";
+ });
+ fmt << ")" << std::endl;
+ outString = fmt.str();
+}
+
+void CAmDatabaseHandlerMap::am_MainConnection_Database_s::getMainConnectionType(am_MainConnectionType_s & connectionType) const
+{
+ connectionType.mainConnectionID = mainConnectionID;
+ connectionType.sourceID = sourceID;
+ connectionType.sinkID = sinkID;
+ connectionType.connectionState = connectionState;
+ connectionType.delay = delay;
+}
+
+/* Source Class */
+
+void CAmDatabaseHandlerMap::CAmSourceClass::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Source class(" << name.c_str() << ") id(" << sourceClassID << ")\n" <<
+ ") listClassProperties (";
+ std::for_each(listClassProperties.begin(), listClassProperties.end(), [&](const am_ClassProperty_s & ref) {
+ fmt << "[classProperty:" << ref.classProperty << " value:" << ref.value << "]";
+ });
+ fmt << ")" << std::endl;
+ outString = fmt.str();
+}
+
+/* Sink Class */
+
+void CAmDatabaseHandlerMap::CAmSinkClass::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Sink class(" << name.c_str() << ") id(" << sinkClassID << ")\n" <<
+ ") listClassProperties (";
+ std::for_each(listClassProperties.begin(), listClassProperties.end(), [&](const am_ClassProperty_s & ref) {
+ fmt << "[classProperty:" << ref.classProperty << " value:" << ref.value << "]";
+ });
+ fmt << ")" << std::endl;
+ outString = fmt.str();
+}
+
+
+/* Gateway */
+
+void CAmDatabaseHandlerMap::CAmGateway::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Gateway(" << name.c_str() << ") id(" << gatewayID << ")\n" <<
+ "sinkID(" << sinkID <<
+ ") sourceID(" << sourceID <<
+ ") domainSinkID(" << domainSinkID <<
+ ") domainSourceID(" << domainSourceID <<
+ ") controlDomainID(" << controlDomainID <<
+ ") listSourceFormats (";
+ std::for_each(listSourceFormats.begin(), listSourceFormats.end(), [&](const am_CustomConnectionFormat_t & ref) {
+ fmt << "[" << ref << "]";
+ });
+ fmt << ") listSinkFormats (";
+ std::for_each(listSinkFormats.begin(), listSinkFormats.end(), [&](const am_CustomConnectionFormat_t & ref) {
+ fmt << "[" << ref << "]";
+ });
+ fmt << ") convertionMatrix (";
+ std::for_each(convertionMatrix.begin(), convertionMatrix.end(), [&](const bool & ref) {
+ fmt << "[" << ref << "]";
+ });
+ fmt << ")" << std::endl;
+ outString = fmt.str();
+}
+
+/* Crossfader */
+
+void CAmDatabaseHandlerMap::CAmCrossfader::getDescription (std::string & outString) const
+{
+ std::ostringstream fmt;
+ fmt << "Crossfader(" << name.c_str() << ") id(" << crossfaderID << ")\n" <<
+ "sinkID_A(" << sinkID_A <<
+ ") sinkID_B(" << sinkID_B <<
+ ") sourceID(" << sourceID <<
+ ") hotSink(" << hotSink <<
+ ")" << std::endl;
+ outString = fmt.str();
+}
+
+bool CAmDatabaseHandlerMap::CAmMappedData::increaseID(int16_t & resultID, am_Identifier_s & sourceID,
+ int16_t const desiredStaticID = 0)
+{
+ if( desiredStaticID > 0 && desiredStaticID < sourceID.mMin )
+ {
+ resultID = desiredStaticID;
+ return true;
+ }
+ else if( sourceID.mCurrentValue < sourceID.mMax ) //The last used value is 'limit' - 1. e.g. SHRT_MAX - 1, SHRT_MAX is reserved.
+ {
+ resultID = sourceID.mCurrentValue++;
+ return true;
+ }
+ else
+ {
+ resultID = -1;
+ return false;
+ }
+ }
+
+template <typename TMapKey,class TMapObject> bool CAmDatabaseHandlerMap::CAmMappedData::getNextConnectionID(int16_t & resultID, am_Identifier_s & sourceID,
+ const std::unordered_map<TMapKey, TMapObject> & map)
+{
+ TMapKey nextID;
+ int16_t const lastID = sourceID.mCurrentValue;
+ if( sourceID.mCurrentValue < sourceID.mMax )
+ nextID = sourceID.mCurrentValue++;
+ else
+ nextID = sourceID.mCurrentValue = sourceID.mMin;
+
+ bool notFreeIDs = false;
+ while( existsObjectWithKeyInMap(nextID, map) )
+ {
+
+ if( sourceID.mCurrentValue < sourceID.mMax )
+ nextID = sourceID.mCurrentValue++;
+ else
+ {
+ sourceID.mCurrentValue = sourceID.mMin;
+ nextID = sourceID.mCurrentValue++;
+ }
+
+ if( sourceID.mCurrentValue == lastID )
+ {
+ notFreeIDs = true;
+ break;
+ }
+ }
+ if(notFreeIDs)
+ {
+ resultID = -1;
+ return false;
+ }
+ resultID = nextID;
+ return true;
+}
+
+bool CAmDatabaseHandlerMap::CAmMappedData::increaseMainConnectionID(int16_t & resultID)
+{
+ return getNextConnectionID(resultID, mCurrentMainConnectionID, mMainConnectionMap);
+}
+
+bool CAmDatabaseHandlerMap::CAmMappedData::increaseConnectionID(int16_t & resultID)
+{
+ return getNextConnectionID(resultID, mCurrentConnectionID, mConnectionMap);
+}
+
+
+CAmDatabaseHandlerMap::CAmDatabaseHandlerMap(): mFirstStaticSink(true), //
+ mFirstStaticSource(true), //
+ mFirstStaticGateway(true), //
+ mFirstStaticConverter(true), //
+ mFirstStaticSinkClass(true), //
+ mFirstStaticSourceClass(true), //
+ mFirstStaticCrossfader(true), //
+ mpDatabaseObserver(NULL), //
+ mListConnectionFormat(), //
+ mMappedData()
+{
+ logInfo(__PRETTY_FUNCTION__,"Init ");
+}
+
+CAmDatabaseHandlerMap::~CAmDatabaseHandlerMap()
+{
+ logInfo(__PRETTY_FUNCTION__,"Destroy");
+ mpDatabaseObserver = NULL;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterDomainDB(const am_Domain_s & domainData, am_domainID_t & domainID)
+{
+ assert(!domainData.name.empty());
+ assert(!domainData.busname.empty());
+ assert(domainData.state>=DS_UNKNOWN && domainData.state<=DS_MAX);
+ //first check for a reserved domain
+ am_Domain_s const *reservedDomain = objectMatchingPredicate<CAmDomain, am_domainID_t>(mMappedData.mDomainMap, [&](const CAmDomain & obj){
+ return domainData.name.compare(obj.name)==0;
+ });
+
+ int16_t nextID = 0;
+
+ if( NULL != reservedDomain )
+ {
+ nextID = reservedDomain->domainID;
+ domainID = nextID;
+ mMappedData.mDomainMap[nextID] = domainData;
+ mMappedData.mDomainMap[nextID].domainID = nextID;
+ mMappedData.mDomainMap[nextID].reserved = 0;
+ logInfo("DatabaseHandler::enterDomainDB entered reserved domain with name=", domainData.name, "busname=", domainData.busname, "nodename=", domainData.nodename, "reserved ID:", domainID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newDomain(mMappedData.mDomainMap[nextID]);
+ return (E_OK);
+ }
+ else
+ {
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentDomainID, domainData.domainID))
+ {
+ domainID = nextID;
+ mMappedData.mDomainMap[nextID] = domainData;
+ mMappedData.mDomainMap[nextID].domainID = nextID;
+ logInfo("DatabaseHandler::enterDomainDB entered new domain with name=", domainData.name, "busname=", domainData.busname, "nodename=", domainData.nodename, "assigned ID:", domainID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newDomain(mMappedData.mDomainMap[nextID]);
+ return (E_OK);
+ }
+ else
+ {
+ domainID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (E_UNKNOWN);
+ }
+ }
+}
+
+int16_t CAmDatabaseHandlerMap::calculateDelayForRoute(const std::vector<am_connectionID_t>& listConnectionID)
+{
+ int16_t delay = 0;
+ std::vector<am_connectionID_t>::const_iterator elementIterator = listConnectionID.begin();
+ for (; elementIterator < listConnectionID.end(); ++elementIterator)
+ {
+ am_connectionID_t key = *elementIterator;
+ std::unordered_map<am_connectionID_t, am_Connection_Database_s>::const_iterator it = mMappedData.mConnectionMap.find(key);
+ if (it!=mMappedData.mConnectionMap.end())
+ {
+ int16_t temp_delay = it->second.delay;
+ if (temp_delay != -1 && delay != -1)
+ delay += temp_delay;
+ else
+ delay = -1;
+ }
+ }
+ return delay;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterMainConnectionDB(const am_MainConnection_s & mainConnectionData, am_mainConnectionID_t & connectionID)
+{
+ assert(mainConnectionData.mainConnectionID==0);
+ assert(mainConnectionData.connectionState>=CS_UNKNOWN && mainConnectionData.connectionState<=CS_MAX);
+ assert(mainConnectionData.sinkID!=0);
+ assert(mainConnectionData.sourceID!=0);
+
+ int16_t delay = 0;
+ int16_t nextID = 0;
+ if(mMappedData.increaseMainConnectionID(nextID))
+ {
+ connectionID = nextID;
+ mMappedData.mMainConnectionMap[nextID] = mainConnectionData;
+ mMappedData.mMainConnectionMap[nextID].mainConnectionID = nextID;
+ }
+ else
+ {
+ connectionID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (E_UNKNOWN);
+ }
+
+ //now check the connectionTable for all connections in the route. IF connectionID exist
+ delay = calculateDelayForRoute(mainConnectionData.listConnectionID);
+ logInfo("DatabaseHandler::enterMainConnectionDB entered new mainConnection with sourceID", mainConnectionData.sourceID, "sinkID:", mainConnectionData.sinkID, "delay:", delay, "assigned ID:", connectionID);
+
+ if (mpDatabaseObserver)
+ {
+ am_MainConnectionType_s mainConnection;
+ mMappedData.mMainConnectionMap[nextID].getMainConnectionType(mainConnection);
+ mpDatabaseObserver->newMainConnection(mainConnection);
+ mpDatabaseObserver->mainConnectionStateChanged(connectionID, mMappedData.mMainConnectionMap[nextID].connectionState);
+ }
+
+ //finally, we update the delay value for the maintable
+ if (delay == 0)
+ delay = -1;
+ (void)changeDelayMainConnection(delay, connectionID);
+
+ return (E_OK);
+}
+
+/**
+ * Helper method, that inserts a new struct in the map and copies the given into it.
+ * This method uses the increaseID function to secure the global id is properly increased.
+ **/
+bool CAmDatabaseHandlerMap::insertSinkDB(const am_Sink_s & sinkData, am_sinkID_t & sinkID)
+{
+ int16_t nextID = 0;
+ if( mMappedData.increaseID(nextID, mMappedData.mCurrentSinkID, sinkData.sinkID) )
+ {
+ sinkID = nextID;
+ mMappedData.mSinkMap[nextID] = sinkData;
+ mMappedData.mSinkMap[nextID].sinkID = nextID;
+ filterDuplicateNotificationConfigurationTypes(mMappedData.mSinkMap[nextID].listNotificationConfigurations);
+ filterDuplicateNotificationConfigurationTypes(mMappedData.mSinkMap[nextID].listMainNotificationConfigurations);
+ return (true);
+ }
+ else
+ {
+ sinkID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached!");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterSinkDB(const am_Sink_s & sinkData, am_sinkID_t & sinkID)
+{
+ assert(sinkData.sinkID<DYNAMIC_ID_BOUNDARY);
+ assert(sinkData.domainID!=0);
+ assert(!sinkData.name.empty());
+ assert(sinkData.sinkClassID!=0);
+ assert(sinkData.muteState>=MS_UNKNOWN && sinkData.muteState<=MS_MAX);
+
+ am_sinkID_t temp_SinkID = 0;
+ am_sinkID_t temp_SinkIndex = 0;
+ //if sinkID is zero and the first Static Sink was already entered, the ID is created
+ am_Sink_s const *reservedDomain = objectMatchingPredicate<CAmSink, am_sinkID_t>(mMappedData.mSinkMap, [&](const CAmSink & obj){
+ return true==obj.reserved && obj.name.compare(sinkData.name)==0;
+ });
+ if( NULL!=reservedDomain )
+ {
+ am_sinkID_t oldSinkID = reservedDomain->sinkID;
+ mMappedData.mSinkMap[oldSinkID] = sinkData;
+ mMappedData.mSinkMap[oldSinkID].reserved = 0;
+ temp_SinkID = oldSinkID;
+ temp_SinkIndex = oldSinkID;
+ }
+ else
+ {
+ bool result;
+ if ( sinkData.sinkID != 0 || mFirstStaticSink )
+ {
+ //check if the ID already exists
+ if (existSinkNameOrID(sinkData.sinkID, sinkData.name))
+ {
+ sinkID = sinkData.sinkID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertSinkDB(sinkData, temp_SinkID);
+ if( false == result )
+ return (E_UNKNOWN);
+ temp_SinkIndex = temp_SinkID;
+ }
+ //if the first static sink is entered, we need to set it onto the boundary
+ if (sinkData.sinkID == 0 && mFirstStaticSink)
+ {
+ mFirstStaticSink = false;
+ }
+ mMappedData.mSinkMap[temp_SinkIndex].sinkID = temp_SinkID;
+ sinkID = temp_SinkID;
+
+ am_Sink_s & sink = mMappedData.mSinkMap[temp_SinkID];
+ logInfo("DatabaseHandler::enterSinkDB entered new sink with name", sink.name, "domainID:", sink.domainID, "classID:", sink.sinkClassID, "volume:", sink.volume, "assigned ID:", sink.sinkID);
+
+ if (mpDatabaseObserver != NULL)
+ {
+ sink.sinkID=sinkID;
+ mpDatabaseObserver->newSink(sink);
+ }
+ return (E_OK);
+}
+
+bool CAmDatabaseHandlerMap::insertCrossfaderDB(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentCrossfaderID, crossfaderData.crossfaderID))
+ {
+ crossfaderID = nextID;
+ mMappedData.mCrossfaderMap[nextID] = crossfaderData;
+ mMappedData.mCrossfaderMap[nextID].crossfaderID = nextID;
+ return (true);
+ }
+ else
+ {
+ crossfaderID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterCrossfaderDB(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID)
+{
+ assert(crossfaderData.crossfaderID<DYNAMIC_ID_BOUNDARY);
+ assert(crossfaderData.hotSink>=HS_UNKNOWN && crossfaderData.hotSink<=HS_MAX);
+ assert(!crossfaderData.name.empty());
+ assert(existSink(crossfaderData.sinkID_A));
+ assert(existSink(crossfaderData.sinkID_B));
+ assert(existSource(crossfaderData.sourceID));
+
+ am_crossfaderID_t temp_CrossfaderID = 0;
+ am_crossfaderID_t temp_CrossfaderIndex = 0;
+
+ bool result;
+ //if gatewayData is zero and the first Static Sink was already entered, the ID is created
+ if (crossfaderData.crossfaderID != 0 || mFirstStaticCrossfader)
+ {
+ //check if the ID already exists
+ if (existCrossFader(crossfaderData.crossfaderID))
+ {
+ crossfaderID = crossfaderData.crossfaderID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertCrossfaderDB(crossfaderData, temp_CrossfaderID);
+ if( false == result )
+ return (E_UNKNOWN);
+ temp_CrossfaderIndex = temp_CrossfaderID;
+
+ //if the first static sink is entered, we need to set it onto the boundary
+ if ( 0==crossfaderData.crossfaderID && mFirstStaticCrossfader)
+ {
+ mFirstStaticCrossfader = false;
+ }
+
+ mMappedData.mCrossfaderMap[temp_CrossfaderIndex].crossfaderID = temp_CrossfaderID;
+ crossfaderID = temp_CrossfaderID;
+ logInfo("DatabaseHandler::enterCrossfaderDB entered new crossfader with name=", crossfaderData.name, "sinkA= ", crossfaderData.sinkID_A, "sinkB=", crossfaderData.sinkID_B, "source=", crossfaderData.sourceID, "assigned ID:", crossfaderID);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newCrossfader(mMappedData.mCrossfaderMap[temp_CrossfaderIndex]);
+ return (E_OK);
+}
+
+bool CAmDatabaseHandlerMap::insertGatewayDB(const am_Gateway_s & gatewayData, am_gatewayID_t & gatewayID)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentGatewayID, gatewayData.gatewayID))
+ {
+ gatewayID = nextID;
+ mMappedData.mGatewayMap[nextID] = gatewayData;
+ mMappedData.mGatewayMap[nextID].gatewayID = nextID;
+ return (true);
+ }
+ else
+ {
+ gatewayID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterGatewayDB(const am_Gateway_s & gatewayData, am_gatewayID_t & gatewayID)
+{
+ assert(gatewayData.gatewayID<DYNAMIC_ID_BOUNDARY);
+ assert(gatewayData.sinkID!=0);
+ assert(gatewayData.sourceID!=0);
+ assert(gatewayData.controlDomainID!=0);
+ assert(gatewayData.domainSinkID!=0);
+ assert(gatewayData.domainSourceID!=0);
+ assert(!gatewayData.name.empty());
+
+ //might be that the sinks and sources are not there during registration time
+ //assert(existSink(gatewayData.sinkID));
+ //assert(existSource(gatewayData.sourceID));
+
+ am_gatewayID_t temp_GatewayID = 0;
+ am_gatewayID_t temp_GatewayIndex = 0;
+ //if gatewayData is zero and the first Static Sink was already entered, the ID is created
+ bool result;
+ if (gatewayData.gatewayID != 0 || mFirstStaticGateway)
+ {
+ //check if the ID already exists
+ if (existGateway(gatewayData.gatewayID))
+ {
+ gatewayID = gatewayData.gatewayID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertGatewayDB(gatewayData, temp_GatewayID);
+ if( false == result )
+ return (E_UNKNOWN);
+
+ temp_GatewayIndex = temp_GatewayID;
+ //if the ID is not created, we add it to the query
+ if (gatewayData.gatewayID == 0 && mFirstStaticGateway)
+ {
+ mFirstStaticGateway = false;
+ }
+ mMappedData.mGatewayMap[temp_GatewayIndex].gatewayID = temp_GatewayID;
+ gatewayID = temp_GatewayID;
+
+ logInfo("DatabaseHandler::enterGatewayDB entered new gateway with name", gatewayData.name, "sourceID:", gatewayData.sourceID, "sinkID:", gatewayData.sinkID, "assigned ID:", gatewayID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newGateway(mMappedData.mGatewayMap[temp_GatewayIndex]);
+ return (E_OK);
+}
+
+bool CAmDatabaseHandlerMap::insertConverterDB(const am_Converter_s & converteData, am_converterID_t & converterID)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentConverterID, converteData.converterID))
+ {
+ converterID = nextID;
+ mMappedData.mConverterMap[nextID] = converteData;
+ mMappedData.mConverterMap[nextID].converterID = nextID;
+ return (true);
+ }
+ else
+ {
+ converterID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID)
+{
+ assert(converterData.converterID<DYNAMIC_ID_BOUNDARY);
+ assert(converterData.sinkID!=0);
+ assert(converterData.sourceID!=0);
+ assert(converterData.domainID!=0);
+ assert(!converterData.name.empty());
+
+ //might be that the sinks and sources are not there during registration time
+ //assert(existSink(gatewayData.sinkID));
+ //assert(existSource(gatewayData.sourceID));
+
+ am_converterID_t tempID = 0;
+ am_converterID_t tempIndex = 0;
+ //if gatewayData is zero and the first Static Sink was already entered, the ID is created
+ bool result;
+ if (converterData.converterID != 0 || mFirstStaticConverter)
+ {
+ //check if the ID already exists
+ if (existConverter(converterData.converterID))
+ {
+ converterID = converterData.converterID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertConverterDB(converterData, tempID);
+ if( false == result )
+ return (E_UNKNOWN);
+
+ tempIndex = tempID;
+ //if the ID is not created, we add it to the query
+ if (converterData.converterID == 0 && mFirstStaticConverter)
+ {
+ mFirstStaticConverter = false;
+ }
+ mMappedData.mConverterMap[tempIndex].converterID = tempID;
+ converterID = tempID;
+
+ logInfo("DatabaseHandler::enterConverterDB entered new converter with name", converterData.name, "sourceID:", converterData.sourceID, "sinkID:", converterData.sinkID, "assigned ID:", converterID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newConverter(mMappedData.mConverterMap[tempIndex]);
+ return (E_OK);
+}
+
+void CAmDatabaseHandlerMap::dump( std::ostream & output ) const
+{
+ output << std::endl << "****************** DUMP START ******************" << std::endl;
+ CAmMappedData::printMap(mMappedData.mDomainMap, output);
+ CAmMappedData::printMap(mMappedData.mSourceMap, output);
+ CAmMappedData::printMap(mMappedData.mSinkMap, output);
+ CAmMappedData::printMap(mMappedData.mSourceClassesMap, output);
+ CAmMappedData::printMap(mMappedData.mSinkClassesMap, output);
+ CAmMappedData::printMap(mMappedData.mConnectionMap, output);
+ CAmMappedData::printMap(mMappedData.mMainConnectionMap, output);
+ CAmMappedData::printMap(mMappedData.mCrossfaderMap, output);
+ CAmMappedData::printMap(mMappedData.mGatewayMap, output);
+ CAmVectorSystemProperties::const_iterator iter = mMappedData.mSystemProperties.begin();
+ output << "System properties" << "\n";
+ for(; iter!=mMappedData.mSystemProperties.end(); iter++)
+ output << "[type:" << iter->type << " value:" << iter->value << "]";
+ output << std::endl << "****************** DUMP END ******************" << std::endl;
+}
+
+bool CAmDatabaseHandlerMap::insertSourceDB(const am_Source_s & sourceData, am_sourceID_t & sourceID)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentSourceID, sourceData.sourceID))
+ {
+ sourceID = nextID;
+ mMappedData.mSourceMap[nextID] = sourceData;
+ mMappedData.mSourceMap[nextID].sourceID = nextID;
+ filterDuplicateNotificationConfigurationTypes(mMappedData.mSourceMap[nextID].listNotificationConfigurations);
+ filterDuplicateNotificationConfigurationTypes(mMappedData.mSourceMap[nextID].listMainNotificationConfigurations);
+ return (true);
+ }
+ else
+ {
+ sourceID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterSourceDB(const am_Source_s & sourceData, am_sourceID_t & sourceID)
+{
+ assert(sourceData.sourceID<DYNAMIC_ID_BOUNDARY);
+ assert(sourceData.domainID!=0);
+ assert(!sourceData.name.empty());
+ assert(sourceData.sourceClassID!=0);
+ assert(sourceData.sourceState>=SS_UNKNNOWN && sourceData.sourceState<=SS_MAX);
+
+ bool isFirstStatic = sourceData.sourceID == 0 && mFirstStaticSource;
+ am_sourceID_t temp_SourceID = 0;
+ am_sourceID_t temp_SourceIndex = 0;
+ CAmSource const *reservedSource = objectMatchingPredicate<CAmSource, am_sourceID_t>(mMappedData.mSourceMap, [&](const CAmSource & obj){
+ return true==obj.reserved && obj.name.compare(sourceData.name)==0;
+ });
+ if( NULL != reservedSource )
+ {
+ am_sourceID_t oldSourceID = reservedSource->sourceID;
+ mMappedData.mSourceMap[oldSourceID] = sourceData;
+ mMappedData.mSourceMap[oldSourceID].reserved = 0;
+ temp_SourceID = oldSourceID;
+ temp_SourceIndex = oldSourceID;
+ }
+ else
+ {
+ bool result;
+ if ( !isFirstStatic )
+ {
+ //check if the ID already exists
+ if (existSourceNameOrID(sourceData.sourceID, sourceData.name))
+ {
+ sourceID = sourceData.sourceID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertSourceDB(sourceData, temp_SourceID);
+ if( false == result )
+ return (E_UNKNOWN);
+ temp_SourceIndex = temp_SourceID;
+ }
+
+ if ( isFirstStatic )
+ {
+ //if the first static sink is entered, we need to set it onto the boundary if needed
+ mFirstStaticSource = false;
+ }
+ mMappedData.mSourceMap[temp_SourceIndex].sourceID = temp_SourceID;
+ sourceID = temp_SourceID;
+
+ logInfo("DatabaseHandler::enterSourceDB entered new source with name", sourceData.name, "domainID:", sourceData.domainID, "classID:", sourceData.sourceClassID, "visible:", sourceData.visible, "assigned ID:", sourceID);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newSource(mMappedData.mSourceMap[temp_SourceIndex]);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterConnectionDB(const am_Connection_s& connection, am_connectionID_t& connectionID)
+{
+ assert(connection.connectionID==0);
+ assert(connection.sinkID!=0);
+ assert(connection.sourceID!=0);
+ //connection format is not checked, because it's project specific
+ int16_t nextID = 0;
+ if(mMappedData.increaseConnectionID(nextID))
+ {
+ connectionID = nextID;
+ mMappedData.mConnectionMap[nextID] = connection;
+ mMappedData.mConnectionMap[nextID].connectionID = nextID;
+ mMappedData.mConnectionMap[nextID].reserved = true;
+ }
+ else
+ {
+ connectionID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (E_UNKNOWN);
+ }
+
+ logInfo("DatabaseHandler::enterConnectionDB entered new connection sourceID=", connection.sourceID, "sinkID=", connection.sinkID, "sourceID=", connection.sourceID, "connectionFormat=", connection.connectionFormat, "assigned ID=", connectionID);
+ return (E_OK);
+}
+
+bool CAmDatabaseHandlerMap::insertSinkClassDB(const am_SinkClass_s & sinkClass, am_sinkClass_t & sinkClassID)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentSinkClassesID, sinkClass.sinkClassID))
+ {
+ sinkClassID = nextID;
+ mMappedData.mSinkClassesMap[nextID] = sinkClass;
+ mMappedData.mSinkClassesMap[nextID].sinkClassID = nextID;
+ return (true);
+ }
+ else
+ {
+ sinkClassID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterSinkClassDB(const am_SinkClass_s & sinkClass, am_sinkClass_t & sinkClassID)
+{
+ assert(sinkClass.sinkClassID<DYNAMIC_ID_BOUNDARY);
+ assert(!sinkClass.name.empty());
+
+ am_sinkClass_t temp_SinkClassID = 0;
+ am_sinkClass_t temp_SinkClassIndex = 0;
+
+ bool result;
+ if (sinkClass.sinkClassID != 0 || mFirstStaticSinkClass)
+ {
+ //check if the ID already exists
+ if (existSinkClass(sinkClass.sinkClassID))
+ {
+ sinkClassID = sinkClass.sinkClassID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertSinkClassDB(sinkClass, temp_SinkClassID);
+ if( false == result )
+ return (E_UNKNOWN);
+
+ temp_SinkClassIndex = temp_SinkClassID;
+ //if the ID is not created, we add it to the query
+ if (sinkClass.sinkClassID == 0 && mFirstStaticSinkClass)
+ {
+ mFirstStaticSinkClass = false;
+ }
+ mMappedData.mSinkClassesMap[temp_SinkClassIndex].sinkClassID = temp_SinkClassID;
+ sinkClassID = temp_SinkClassID;
+
+ //todo:change last_insert implementations for multithreaded usage...
+ logInfo("DatabaseHandler::enterSinkClassDB entered new sinkClass");
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->numberOfSinkClassesChanged();
+ return (E_OK);
+}
+
+bool CAmDatabaseHandlerMap::insertSourceClassDB(am_sourceClass_t & sourceClassID, const am_SourceClass_s & sourceClass)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentSourceClassesID, sourceClass.sourceClassID))
+ {
+ sourceClassID = nextID;
+ mMappedData.mSourceClassesMap[nextID] = sourceClass;
+ mMappedData.mSourceClassesMap[nextID].sourceClassID = nextID;
+ return (true);
+ }
+ else
+ {
+ sourceClassID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterSourceClassDB(am_sourceClass_t & sourceClassID, const am_SourceClass_s & sourceClass)
+{
+ assert(sourceClass.sourceClassID<DYNAMIC_ID_BOUNDARY);
+ assert(!sourceClass.name.empty());
+
+ am_sourceClass_t temp_SourceClassID = 0;
+ am_sourceClass_t temp_SourceClassIndex = 0;
+
+ bool result;
+ if (sourceClass.sourceClassID != 0 || mFirstStaticSourceClass)
+ {
+ //check if the ID already exists
+ if (existSourceClass(sourceClass.sourceClassID))
+ {
+ sourceClassID = sourceClass.sourceClassID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertSourceClassDB(temp_SourceClassID, sourceClass);
+ if( false == result )
+ return (E_UNKNOWN);
+
+ temp_SourceClassIndex = temp_SourceClassID;
+ //if the ID is not created, we add it to the query
+ if (sourceClass.sourceClassID == 0 && mFirstStaticSourceClass)
+ {
+ mFirstStaticSinkClass = false;
+ }
+ mMappedData.mSourceClassesMap[temp_SourceClassIndex].sourceClassID = temp_SourceClassID;
+ sourceClassID = temp_SourceClassID;
+
+ //todo:change last_insert implementations for multithread usage...
+
+ logInfo("DatabaseHandler::enterSourceClassDB entered new sourceClass");
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->numberOfSourceClassesChanged();
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterSystemProperties(const std::vector<am_SystemProperty_s> & listSystemProperties)
+{
+ assert(!listSystemProperties.empty());
+
+ mMappedData.mSystemProperties = listSystemProperties;
+
+ logInfo("DatabaseHandler::enterSystemProperties entered system properties");
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeMainConnectionRouteDB(const am_mainConnectionID_t mainconnectionID, const std::vector<am_connectionID_t>& listConnectionID)
+{
+ assert(mainconnectionID!=0);
+ if (!existMainConnection(mainconnectionID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ int16_t delay = calculateDelayForRoute(listConnectionID);
+
+ //now we replace the data in the main connection object with the new one
+ mMappedData.mMainConnectionMap[mainconnectionID].listConnectionID = listConnectionID;
+
+ if (changeDelayMainConnection(delay,mainconnectionID) == E_NO_CHANGE)
+ logError("DatabaseHandler::changeMainConnectionRouteDB error while changing mainConnectionDelay to ", delay);
+
+ logInfo("DatabaseHandler::changeMainConnectionRouteDB entered new route:", mainconnectionID);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeMainConnectionStateDB(const am_mainConnectionID_t mainconnectionID, const am_ConnectionState_e connectionState)
+{
+ assert(mainconnectionID!=0);
+ assert(connectionState>=CS_UNKNOWN && connectionState<=CS_MAX);
+
+ if (!existMainConnection(mainconnectionID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_RIE(mMappedData.mMainConnectionMap[mainconnectionID].connectionState, connectionState);
+
+ logInfo("DatabaseHandler::changeMainConnectionStateDB changed mainConnectionState of MainConnection:", mainconnectionID, "to:", connectionState);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->mainConnectionStateChanged(mainconnectionID, connectionState);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkMainVolumeDB(const am_mainVolume_t mainVolume, const am_sinkID_t sinkID)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_RIE(mMappedData.mSinkMap[sinkID].mainVolume, mainVolume);
+
+ logInfo("DatabaseHandler::changeSinkMainVolumeDB changed mainVolume of sink:", sinkID, "to:", mainVolume);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->volumeChanged(sinkID, mainVolume);
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkAvailabilityDB(const am_Availability_s & availability, const am_sinkID_t sinkID)
+{
+ assert(sinkID!=0);
+ assert(availability.availability>=A_UNKNOWN && availability.availability<=A_MAX);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_RIE(mMappedData.mSinkMap[sinkID].available, availability);
+
+ logInfo("DatabaseHandler::changeSinkAvailabilityDB changed sinkAvailability of sink:", sinkID, "to:", availability.availability, "Reason:", availability.availabilityReason);
+
+ if (mpDatabaseObserver && sinkVisible(sinkID))
+ mpDatabaseObserver->sinkAvailabilityChanged(sinkID, availability);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changDomainStateDB(const am_DomainState_e domainState, const am_domainID_t domainID)
+{
+ assert(domainID!=0);
+ assert(domainState>=DS_UNKNOWN && domainState<=DS_MAX);
+
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_RIE(mMappedData.mDomainMap[domainID].state, domainState);
+
+ logInfo("DatabaseHandler::changDomainStateDB changed domainState of domain:", domainID, "to:", domainState);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkMuteStateDB(const am_MuteState_e muteState, const am_sinkID_t sinkID)
+{
+ assert(sinkID!=0);
+ assert(muteState>=MS_UNKNOWN && muteState<=MS_MAX);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_RIE(mMappedData.mSinkMap[sinkID].muteState, muteState);
+
+ logInfo("DatabaseHandler::changeSinkMuteStateDB changed sinkMuteState of sink:", sinkID, "to:", muteState);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->sinkMuteStateChanged(sinkID, muteState);
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeMainSinkSoundPropertyDB(const am_MainSoundProperty_s & soundProperty, const am_sinkID_t sinkID)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_Sink_Database_s & sink = mMappedData.mSinkMap[sinkID];
+ std::vector<am_MainSoundProperty_s>::iterator elementIterator = sink.listMainSoundProperties.begin();
+ for (;elementIterator != sink.listMainSoundProperties.end(); ++elementIterator)
+ {
+ if (elementIterator->type == soundProperty.type)
+ {
+ DB_COND_UPDATE_RIE(elementIterator->value, soundProperty.value);
+ if(sink.cacheMainSoundProperties.size())
+ sink.cacheMainSoundProperties[soundProperty.type] = soundProperty.value;
+ break;
+ }
+ }
+
+ logInfo("DatabaseHandler::changeMainSinkSoundPropertyDB changed MainSinkSoundProperty of sink:", sinkID, "type:", soundProperty.type, "to:", soundProperty.value);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->mainSinkSoundPropertyChanged(sinkID, soundProperty);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeMainSourceSoundPropertyDB(const am_MainSoundProperty_s & soundProperty, const am_sourceID_t sourceID)
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_Source_Database_s & source = mMappedData.mSourceMap.at(sourceID);
+ std::vector<am_MainSoundProperty_s>::iterator elementIterator = source.listMainSoundProperties.begin();
+ for (;elementIterator != source.listMainSoundProperties.end(); ++elementIterator)
+ {
+ if (elementIterator->type == soundProperty.type)
+ {
+ DB_COND_UPDATE_RIE(elementIterator->value, soundProperty.value);
+ if(source.cacheMainSoundProperties.size())
+ source.cacheMainSoundProperties[soundProperty.type] = soundProperty.value;
+ break;
+ }
+ }
+
+ logInfo("DatabaseHandler::changeMainSourceSoundPropertyDB changed MainSinkSoundProperty of source:", sourceID, "type:", soundProperty.type, "to:", soundProperty.value);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->mainSourceSoundPropertyChanged(sourceID, soundProperty);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceAvailabilityDB(const am_Availability_s & availability, const am_sourceID_t sourceID)
+{
+ assert(sourceID!=0);
+ assert(availability.availability>=A_UNKNOWN && availability.availability<=A_MAX);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_RIE(mMappedData.mSourceMap[sourceID].available, availability);
+
+ logInfo("DatabaseHandler::changeSourceAvailabilityDB changed changeSourceAvailabilityDB of source:", sourceID, "to:", availability.availability, "Reason:", availability.availabilityReason);
+
+ if (mpDatabaseObserver && sourceVisible(sourceID))
+ mpDatabaseObserver->sourceAvailabilityChanged(sourceID, availability);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSystemPropertyDB(const am_SystemProperty_s & property)
+{
+ std::vector<am_SystemProperty_s>::iterator elementIterator = mMappedData.mSystemProperties.begin();
+ for (;elementIterator != mMappedData.mSystemProperties.end(); ++elementIterator)
+ {
+ if (elementIterator->type == property.type)
+ DB_COND_UPDATE_RIE(elementIterator->value, property.value);
+ }
+
+ logInfo("DatabaseHandler::changeSystemPropertyDB changed system property");
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->systemPropertyChanged(property);
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeMainConnectionDB(const am_mainConnectionID_t mainConnectionID)
+{
+ assert(mainConnectionID!=0);
+
+ if (!existMainConnection(mainConnectionID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mMainConnectionMap.erase(mainConnectionID);
+
+ logInfo("DatabaseHandler::removeMainConnectionDB removed:", mainConnectionID);
+ if (mpDatabaseObserver)
+ {
+ mpDatabaseObserver->mainConnectionStateChanged(mainConnectionID, CS_DISCONNECTED);
+ mpDatabaseObserver->removedMainConnection(mainConnectionID);
+ }
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeSinkDB(const am_sinkID_t sinkID)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ bool visible = sinkVisible(sinkID);
+
+ mMappedData.mSinkMap.erase(sinkID);
+ // todo: Check the tables SinkMainSoundProperty and SinkMainNotificationConfiguration with 'visible' set to true
+ //if visible is true then delete SinkMainSoundProperty and SinkMainNotificationConfiguration ????
+ logInfo("DatabaseHandler::removeSinkDB removed:", sinkID);
+
+ if (mpDatabaseObserver != NULL)
+ mpDatabaseObserver->removedSink(sinkID, visible);
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeSourceDB(const am_sourceID_t sourceID)
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ bool visible = sourceVisible(sourceID);
+
+ mMappedData.mSourceMap.erase(sourceID);
+
+ // todo: Check the tables SourceMainSoundProperty and SourceMainNotificationConfiguration with 'visible' set to true
+ //if visible is true then delete SourceMainSoundProperty and SourceMainNotificationConfiguration ????
+
+ logInfo("DatabaseHandler::removeSourceDB removed:", sourceID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removedSource(sourceID, visible);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeGatewayDB(const am_gatewayID_t gatewayID)
+{
+ assert(gatewayID!=0);
+
+ if (!existGateway(gatewayID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mGatewayMap.erase(gatewayID);
+
+ logInfo("DatabaseHandler::removeGatewayDB removed:", gatewayID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removeGateway(gatewayID);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeConverterDB(const am_converterID_t converterID)
+{
+ assert(converterID!=0);
+
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mConverterMap.erase(converterID);
+
+ logInfo("DatabaseHandler::removeConverterDB removed:", converterID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removeConverter(converterID);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeCrossfaderDB(const am_crossfaderID_t crossfaderID)
+{
+ assert(crossfaderID!=0);
+
+ if (!existCrossFader(crossfaderID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ mMappedData.mCrossfaderMap.erase(crossfaderID);
+
+ logInfo("DatabaseHandler::removeCrossfaderDB removed:", crossfaderID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removeCrossfader(crossfaderID);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeDomainDB(const am_domainID_t domainID)
+{
+ assert(domainID!=0);
+
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ mMappedData.mDomainMap.erase(domainID);
+
+ logInfo("DatabaseHandler::removeDomainDB removed:", domainID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removeDomain(domainID);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeSinkClassDB(const am_sinkClass_t sinkClassID)
+{
+ assert(sinkClassID!=0);
+
+ if (!existSinkClass(sinkClassID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mSinkClassesMap.erase(sinkClassID);
+
+ logInfo("DatabaseHandler::removeSinkClassDB removed:", sinkClassID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->numberOfSinkClassesChanged();
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeSourceClassDB(const am_sourceClass_t sourceClassID)
+{
+ assert(sourceClassID!=0);
+
+ if (!existSourceClass(sourceClassID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mSourceClassesMap.erase(sourceClassID);
+ logInfo("DatabaseHandler::removeSourceClassDB removed:", sourceClassID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->numberOfSourceClassesChanged();
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::removeConnection(const am_connectionID_t connectionID)
+{
+ assert(connectionID!=0);
+
+ mMappedData.mConnectionMap.erase(connectionID);
+
+ logInfo("DatabaseHandler::removeConnection removed:", connectionID);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSourceClassInfoDB(const am_sourceID_t sourceID, am_SourceClass_s & classInfo) const
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_Source_Database_s source = mMappedData.mSourceMap.at(sourceID);
+ classInfo.sourceClassID = source.sourceClassID;
+
+ if (!existSourceClass(classInfo.sourceClassID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_SourceClass_s tmpClass = mMappedData.mSourceClassesMap.at(classInfo.sourceClassID);
+ classInfo = tmpClass;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSinkInfoDB(const am_sinkID_t sinkID, am_Sink_s & sinkData) const
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ return (E_NON_EXISTENT);
+
+ am_Sink_Database_s mappedSink = mMappedData.mSinkMap.at(sinkID);
+ if( true == mappedSink.reserved )
+ return (E_NON_EXISTENT);
+ sinkData = mappedSink;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSourceInfoDB(const am_sourceID_t sourceID, am_Source_s & sourceData) const
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ return (E_NON_EXISTENT);
+
+ am_Source_Database_s mappedSource = mMappedData.mSourceMap.at(sourceID);
+ if( true == mappedSource.reserved )
+ return (E_NON_EXISTENT);
+
+ sourceData = mappedSource;
+
+ return (E_OK);
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::getMainConnectionInfoDB(const am_mainConnectionID_t mainConnectionID, am_MainConnection_s & mainConnectionData) const
+{
+ assert(mainConnectionID!=0);
+ if (!existMainConnection(mainConnectionID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_MainConnection_s temp = mMappedData.mMainConnectionMap.at(mainConnectionID);
+ mainConnectionData = temp;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkClassInfoDB(const am_SinkClass_s& sinkClass)
+{
+ assert(sinkClass.sinkClassID!=0);
+ assert(!sinkClass.listClassProperties.empty());
+
+ //check if the ID already exists
+ if (!existSinkClass(sinkClass.sinkClassID))
+ return (E_NON_EXISTENT);
+
+ DB_COND_UPDATE_RIE(mMappedData.mSinkClassesMap[sinkClass.sinkClassID].listClassProperties, sinkClass.listClassProperties);
+
+ logInfo("DatabaseHandler::setSinkClassInfoDB set setSinkClassInfo");
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceClassInfoDB(const am_SourceClass_s& sourceClass)
+{
+ assert(sourceClass.sourceClassID!=0);
+ assert(!sourceClass.listClassProperties.empty());
+
+ //check if the ID already exists
+ if (!existSourceClass(sourceClass.sourceClassID))
+ return (E_NON_EXISTENT);
+
+ DB_COND_UPDATE_RIE(mMappedData.mSourceClassesMap[sourceClass.sourceClassID].listClassProperties, sourceClass.listClassProperties);
+
+ logInfo("DatabaseHandler::setSinkClassInfoDB set setSinkClassInfo");
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSinkClassInfoDB(const am_sinkID_t sinkID, am_SinkClass_s & sinkClass) const
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_Sink_Database_s sink = mMappedData.mSinkMap.at(sinkID);
+ sinkClass.sinkClassID = sink.sinkClassID;
+
+ if (!existSinkClass(sinkClass.sinkClassID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_SinkClass_s tmpSinkClass = mMappedData.mSinkClassesMap.at(sinkClass.sinkClassID);
+ sinkClass = tmpSinkClass;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getGatewayInfoDB(const am_gatewayID_t gatewayID, am_Gateway_s & gatewayData) const
+{
+ assert(gatewayID!=0);
+ if (!existGateway(gatewayID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ gatewayData = mMappedData.mGatewayMap.at(gatewayID);
+
+ return (E_OK);
+
+}
+
+am_Error_e CAmDatabaseHandlerMap::getConverterInfoDB(const am_converterID_t converterID, am_Converter_s& converterData) const
+{
+ assert(converterID!=0);
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ converterData = mMappedData.mConverterMap.at(converterID);
+
+ return (E_OK);
+
+}
+
+am_Error_e CAmDatabaseHandlerMap::getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s & crossfaderData) const
+{
+ assert(crossfaderID!=0);
+ if (!existCrossFader(crossfaderID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ crossfaderData = mMappedData.mCrossfaderMap.at(crossfaderID);
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSinksOfDomain(const am_domainID_t domainID, std::vector<am_sinkID_t> & listSinkID) const
+{
+ assert(domainID!=0);
+ listSinkID.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ std::unordered_map<am_sinkID_t, am_Sink_Database_s>::const_iterator elementIterator = mMappedData.mSinkMap.begin();
+ for (;elementIterator != mMappedData.mSinkMap.end(); ++elementIterator)
+ {
+ if (0==elementIterator->second.reserved && domainID==elementIterator->second.domainID)
+ listSinkID.push_back(elementIterator->second.sinkID);
+ }
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSourcesOfDomain(const am_domainID_t domainID, std::vector<am_sourceID_t> & listSourceID) const
+{
+ assert(domainID!=0);
+ listSourceID.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ CAmMapSource::const_iterator elementIterator = mMappedData.mSourceMap.begin();
+ for (;elementIterator != mMappedData.mSourceMap.end(); ++elementIterator)
+ {
+ if (0==elementIterator->second.reserved && domainID==elementIterator->second.domainID)
+ listSourceID.push_back(elementIterator->second.sourceID);
+ }
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListCrossfadersOfDomain(const am_domainID_t domainID, std::vector<am_crossfaderID_t> & listCrossfader) const
+{
+ assert(domainID!=0);
+ listCrossfader.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ CAmMapSource::const_iterator sourceIterator = mMappedData.mSourceMap.begin();
+ for (;sourceIterator != mMappedData.mSourceMap.end(); ++sourceIterator)
+ {
+ if (domainID==sourceIterator->second.domainID)
+ {
+ CAmMapCrossfader::const_iterator elementIterator = mMappedData.mCrossfaderMap.begin();
+ for (;elementIterator != mMappedData.mCrossfaderMap.end(); ++elementIterator)
+ {
+ if ( sourceIterator->second.sourceID==elementIterator->second.sourceID )
+ listCrossfader.push_back(elementIterator->second.crossfaderID);
+ }
+ }
+ }
+
+ return (E_OK);
+
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListGatewaysOfDomain(const am_domainID_t domainID, std::vector<am_gatewayID_t> & listGatewaysID) const
+{
+ assert(domainID!=0);
+ listGatewaysID.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ CAmMapGateway::const_iterator elementIterator = mMappedData.mGatewayMap.begin();
+ for (;elementIterator != mMappedData.mGatewayMap.end(); ++elementIterator)
+ {
+ if (domainID==elementIterator->second.controlDomainID)
+ listGatewaysID.push_back(elementIterator->second.gatewayID);
+ }
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListConvertersOfDomain(const am_domainID_t domainID, std::vector<am_converterID_t>& listConvertersID) const
+{
+ assert(domainID!=0);
+ listConvertersID.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ CAmMapConverter::const_iterator elementIterator = mMappedData.mConverterMap.begin();
+ for (;elementIterator != mMappedData.mConverterMap.end(); ++elementIterator)
+ {
+ if (domainID==elementIterator->second.domainID)
+ listConvertersID.push_back(elementIterator->second.converterID);
+ }
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainConnections(std::vector<am_MainConnection_s> & listMainConnections) const
+{
+ listMainConnections.clear();
+
+ CAmMapMainConnection::const_iterator elementIterator = mMappedData.mMainConnectionMap.begin();
+ for (;elementIterator != mMappedData.mMainConnectionMap.end(); ++elementIterator)
+ {
+ listMainConnections.push_back(elementIterator->second);
+ }
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListDomains(std::vector<am_Domain_s> & listDomains) const
+{
+ listDomains.clear();
+
+ CAmMapDomain::const_iterator elementIterator = mMappedData.mDomainMap.begin();
+ for (;elementIterator != mMappedData.mDomainMap.end(); ++elementIterator)
+ {
+ if( 0==elementIterator->second.reserved )
+ listDomains.push_back(elementIterator->second);
+ }
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListConnections(std::vector<am_Connection_s> & listConnections) const
+{
+ listConnections.clear();
+
+ CAmMapConnection::const_iterator elementIterator = mMappedData.mConnectionMap.begin();
+ for (;elementIterator != mMappedData.mConnectionMap.end(); ++elementIterator)
+ {
+ if( 0==elementIterator->second.reserved )
+ listConnections.push_back(elementIterator->second);
+ }
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSinks(std::vector<am_Sink_s> & listSinks) const
+{
+ listSinks.clear();
+
+ std::for_each(mMappedData.mSinkMap.begin(), mMappedData.mSinkMap.end(), [&](const std::pair<am_sinkID_t, am_Sink_Database_s>& ref) {
+ if( 0==ref.second.reserved )
+ listSinks.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSources(std::vector<am_Source_s> & listSources) const
+{
+ listSources.clear();
+
+ std::for_each(mMappedData.mSourceMap.begin(), mMappedData.mSourceMap.end(), [&](const std::pair<am_sourceID_t, am_Source_Database_s>& ref) {
+ if( 0==ref.second.reserved )
+ {
+ listSources.push_back(ref.second);
+ }
+ });
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSourceClasses(std::vector<am_SourceClass_s> & listSourceClasses) const
+{
+ listSourceClasses.clear();
+
+ std::for_each(mMappedData.mSourceClassesMap.begin(), mMappedData.mSourceClassesMap.end(), [&](const std::pair<am_sourceClass_t, am_SourceClass_s>& ref) {
+ listSourceClasses.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListCrossfaders(std::vector<am_Crossfader_s> & listCrossfaders) const
+{
+ listCrossfaders.clear();
+
+ std::for_each(mMappedData.mCrossfaderMap.begin(), mMappedData.mCrossfaderMap.end(), [&](const std::pair<am_crossfaderID_t, am_Crossfader_s>& ref) {
+ listCrossfaders.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListGateways(std::vector<am_Gateway_s> & listGateways) const
+{
+ listGateways.clear();
+
+ std::for_each(mMappedData.mGatewayMap.begin(), mMappedData.mGatewayMap.end(), [&](const std::pair<am_gatewayID_t, am_Gateway_s>& ref) {
+ listGateways.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListConverters(std::vector<am_Converter_s> & listConverters) const
+{
+ listConverters.clear();
+
+ std::for_each(mMappedData.mConverterMap.begin(), mMappedData.mConverterMap.end(), [&](const std::pair<am_converterID_t, am_Converter_s>& ref) {
+ listConverters.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSinkClasses(std::vector<am_SinkClass_s> & listSinkClasses) const
+{
+ listSinkClasses.clear();
+
+ std::for_each(mMappedData.mSinkClassesMap.begin(), mMappedData.mSinkClassesMap.end(), [&](const std::pair<am_gatewayID_t, am_SinkClass_s>& ref) {
+ listSinkClasses.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListVisibleMainConnections(std::vector<am_MainConnectionType_s> & listConnections) const
+{
+ listConnections.clear();
+ std::for_each(mMappedData.mMainConnectionMap.begin(), mMappedData.mMainConnectionMap.end(), [&](const std::pair<am_mainConnectionID_t, am_MainConnection_Database_s>& ref) {
+ listConnections.emplace_back();
+ ref.second.getMainConnectionType(listConnections.back());
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainSinks(std::vector<am_SinkType_s> & listMainSinks) const
+{
+ listMainSinks.clear();
+ std::for_each(mMappedData.mSinkMap.begin(), mMappedData.mSinkMap.end(), [&](const std::pair<am_sinkID_t, am_Sink_Database_s>& ref) {
+ if( 0==ref.second.reserved && 1==ref.second.visible )
+ {
+ listMainSinks.emplace_back();
+ ref.second.getSinkType(listMainSinks.back());
+ }
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainSources(std::vector<am_SourceType_s> & listMainSources) const
+{
+ listMainSources.clear();
+ std::for_each(mMappedData.mSourceMap.begin(), mMappedData.mSourceMap.end(), [&](const std::pair<am_sourceID_t, am_Source_Database_s>& ref) {
+ if( 0==ref.second.reserved && 1==ref.second.visible )
+ {
+ listMainSources.emplace_back();
+ ref.second.getSourceType(listMainSources.back());
+ }
+ });
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s> & listSoundProperties) const
+{
+ assert(sinkID!=0);
+ if (!existSink(sinkID))
+ return E_NON_EXISTENT;
+
+ const am_Sink_s & sink = mMappedData.mSinkMap.at(sinkID);
+ listSoundProperties = sink.listMainSoundProperties;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s> & listSourceProperties) const
+{
+ assert(sourceID!=0);
+ if (!existSource(sourceID))
+ return E_NON_EXISTENT;
+
+ const am_Source_s & source = mMappedData.mSourceMap.at(sourceID);
+ listSourceProperties = source.listMainSoundProperties;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const
+{
+ assert(sinkID!=0);
+ if (!existSink(sinkID))
+ return E_NON_EXISTENT;
+
+ const am_Sink_Database_s & sink = mMappedData.mSinkMap.at(sinkID);
+ listSoundproperties = sink.listSoundProperties;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_SoundProperty_s>& listSoundproperties) const
+{
+ assert(sourceID!=0);
+ if (!existSource(sourceID))
+ return E_NON_EXISTENT;
+
+ const am_Source_Database_s & source = mMappedData.mSourceMap.at(sourceID);
+ listSoundproperties = source.listSoundProperties;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListSystemProperties(std::vector<am_SystemProperty_s> & listSystemProperties) const
+{
+ listSystemProperties = mMappedData.mSystemProperties;
+ return (E_OK);
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::getListSinkConnectionFormats(const am_sinkID_t sinkID, std::vector<am_CustomConnectionFormat_t> & listConnectionFormats) const
+{
+ if (!existSink(sinkID))
+ return E_NON_EXISTENT;
+ const am_Sink_s & sink = mMappedData.mSinkMap.at(sinkID);
+ listConnectionFormats = sink.listConnectionFormats;
+
+ return (E_OK);
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::getListSourceConnectionFormats(const am_sourceID_t sourceID, std::vector<am_CustomConnectionFormat_t> & listConnectionFormats) const
+{
+ if (!existSource(sourceID))
+ return E_NON_EXISTENT;
+ const am_Source_s & source = mMappedData.mSourceMap.at(sourceID);
+ listConnectionFormats = source.listConnectionFormats;
+
+ return (E_OK);
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::getListGatewayConnectionFormats(const am_gatewayID_t gatewayID, std::vector<bool> & listConnectionFormat) const
+{
+ ListConnectionFormat::const_iterator iter = mListConnectionFormat.begin();
+ iter = mListConnectionFormat.find(gatewayID);
+ if (iter == mListConnectionFormat.end())
+ {
+ logError("DatabaseHandler::getListGatewayConnectionFormats database error with convertionFormat");
+
+ return E_NON_EXISTENT;
+ }
+ listConnectionFormat = iter->second;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t & delay) const
+{
+ assert(mainConnectionID!=0);
+ if (!existMainConnection(mainConnectionID))
+ return E_NON_EXISTENT;
+ delay = -1;
+
+ const am_MainConnection_s & mainConnection = mMappedData.mMainConnectionMap.at(mainConnectionID);
+ delay = mainConnection.delay;
+
+ if (delay == -1)
+ return (E_NOT_POSSIBLE);
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeDelayMainConnection(const am_timeSync_t & delay, const am_mainConnectionID_t & connectionID)
+{
+ assert(connectionID!=0);
+ if (!existMainConnection(connectionID))
+ return (E_NON_EXISTENT);
+ DB_COND_UPDATE_RIE(mMappedData.mMainConnectionMap[connectionID].delay, delay);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->timingInformationChanged(connectionID, delay);
+ return (E_OK);
+}
+
+/**
+ * checks for a certain mainConnection
+ * @param mainConnectionID to be checked for
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existMainConnection(const am_mainConnectionID_t mainConnectionID) const
+{
+ return existsObjectWithKeyInMap(mainConnectionID, mMappedData.mMainConnectionMap);
+}
+
+/**
+ * checks for a certain Source
+ * @param sourceID to be checked for
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existSource(const am_sourceID_t sourceID) const
+{
+ am_Source_Database_s const * source = objectForKeyIfExistsInMap(sourceID, mMappedData.mSourceMap);
+ if( NULL!=source )
+ return (0==source->reserved);
+
+ return false;
+}
+
+/**
+ * checks if a source name or ID exists
+ * @param sourceID the sourceID
+ * @param name the name
+ * @return true if it exits
+ */
+bool CAmDatabaseHandlerMap::existSourceNameOrID(const am_sourceID_t sourceID, const std::string & name) const
+{
+ return sourceWithNameOrID(sourceID, name);
+}
+
+/**
+ * checks if a name exits
+ * @param name the name
+ * @return true if it exits
+ */
+bool CAmDatabaseHandlerMap::existSourceName(const std::string & name) const
+{
+ return existSourceNameOrID(mMappedData.mCurrentSourceID.mMax, name);
+}
+
+/**
+ * checks for a certain Sink
+ * @param sinkID to be checked for
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existSink(const am_sinkID_t sinkID) const
+{
+ bool returnVal = false;
+ CAmMapSink::const_iterator elementIterator = mMappedData.mSinkMap.begin();
+ for (;elementIterator != mMappedData.mSinkMap.end(); ++elementIterator)
+ {
+ if( 0==elementIterator->second.reserved &&
+ sinkID==elementIterator->second.sinkID)
+ {
+ returnVal = true;
+ break;
+ }
+ }
+ return (returnVal);
+}
+
+/**
+ * returns source with given ID or the name if exists
+ * @param sourceID the ID
+ * @param name the name
+ * @return source structure if exists.
+ */
+const CAmDatabaseHandlerMap::am_Source_Database_s * CAmDatabaseHandlerMap::sourceWithNameOrID(const am_sourceID_t sourceID, const std::string & name) const
+{
+ std::function<bool(const CAmDatabaseHandlerMap::am_Source_Database_s & refObject)> comparator = [&](const CAmDatabaseHandlerMap::am_Source_Database_s & source)->bool{
+ return ( 0==source.reserved &&
+ (sourceID==source.sourceID || name.compare(source.name)==0));
+ };
+ return objectMatchingPredicate(mMappedData.mSourceMap, comparator);
+}
+
+/**
+ * returns sink with given ID or the name if exists
+ * @param sinkID the ID
+ * @param name the name
+ * @return sink structure if exists.
+ */
+const CAmDatabaseHandlerMap::am_Sink_Database_s * CAmDatabaseHandlerMap::sinkWithNameOrID(const am_sinkID_t sinkID, const std::string & name) const
+{
+ std::function<bool(const CAmDatabaseHandlerMap::am_Sink_Database_s & refObject)> comparator = [&](const CAmDatabaseHandlerMap::am_Sink_Database_s & sink)->bool{
+ return ( 0==sink.reserved &&
+ (sinkID==sink.sinkID || name.compare(sink.name)==0));
+ };
+ return objectMatchingPredicate(mMappedData.mSinkMap, comparator);
+}
+
+/**
+ * checks if a sink with the ID or the name exists
+ * @param sinkID the ID
+ * @param name the name
+ * @return true if it exists.
+ */
+bool CAmDatabaseHandlerMap::existSinkNameOrID(const am_sinkID_t sinkID, const std::string & name) const
+{
+ return sinkWithNameOrID( sinkID, name)!=NULL;
+}
+
+/**
+ * checks if a sink with the name exists
+ * @param name the name
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existSinkName(const std::string & name) const
+{
+ return existSinkNameOrID(mMappedData.mCurrentSinkID.mMax, name);
+}
+
+/**
+ * checks for a certain domain
+ * @param domainID to be checked for
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existDomain(const am_domainID_t domainID) const
+{
+ am_Domain_Database_s const * source = objectForKeyIfExistsInMap(domainID, mMappedData.mDomainMap);
+ if( NULL!=source )
+ return (0==source->reserved);
+
+ return false;
+}
+
+/**
+ * checks for certain gateway
+ * @param gatewayID to be checked for
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existGateway(const am_gatewayID_t gatewayID) const
+{
+ return existsObjectWithKeyInMap(gatewayID, mMappedData.mGatewayMap);
+}
+
+bool CAmDatabaseHandlerMap::existConverter(const am_converterID_t converterID) const
+{
+ return existsObjectWithKeyInMap(converterID, mMappedData.mConverterMap);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t & domainID) const
+{
+ assert(sourceID!=0);
+ domainID=0;
+
+ am_Source_Database_s const * source = objectForKeyIfExistsInMap(sourceID, mMappedData.mSourceMap);
+ if( NULL!=source )
+ {
+ domainID = source->domainID;
+ return E_OK;
+ }
+ return E_NON_EXISTENT;
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t & domainID) const
+{
+ assert(sinkID!=0);
+ domainID=0;
+
+ am_Sink_Database_s const * source = objectForKeyIfExistsInMap(sinkID, mMappedData.mSinkMap);
+ if( NULL!=source )
+ {
+ domainID = source->domainID;
+ return E_OK;
+ }
+ return E_NON_EXISTENT;
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::getDomainOfCrossfader(const am_converterID_t crossfader, am_domainID_t & domainID) const
+{
+ assert(crossfader!=0);
+ domainID=0;
+
+ am_Crossfader_Database_s const * cross = objectForKeyIfExistsInMap(crossfader, mMappedData.mCrossfaderMap);
+ if( NULL!=cross )
+ {
+ getDomainOfSource(cross->sinkID_A,domainID);
+ return E_OK;
+ }
+ return E_NON_EXISTENT;
+}
+
+/**
+ * checks for certain SinkClass
+ * @param sinkClassID
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existSinkClass(const am_sinkClass_t sinkClassID) const
+{
+ return existsObjectWithKeyInMap(sinkClassID, mMappedData.mSinkClassesMap);
+}
+
+/**
+ * checks for certain sourceClass
+ * @param sourceClassID
+ * @return true if it exists
+ */
+bool CAmDatabaseHandlerMap::existSourceClass(const am_sourceClass_t sourceClassID) const
+{
+ return existsObjectWithKeyInMap(sourceClassID, mMappedData.mSourceClassesMap);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeConnectionTimingInformation(const am_connectionID_t connectionID, const am_timeSync_t delay)
+{
+ assert(connectionID!=0);
+ if(!existConnectionID(connectionID))
+ return E_NON_EXISTENT;
+
+ mMappedData.mConnectionMap[connectionID].delay = delay;
+
+ //now we need to find all mainConnections that use the changed connection and update their timing
+
+ //first get all route tables for all mainconnections
+ am_Error_e error = E_OK;
+ CAmMapMainConnection::const_iterator iter = mMappedData.mMainConnectionMap.begin();
+ for(; iter != mMappedData.mMainConnectionMap.end(); ++iter)
+ {
+ const am_MainConnection_s & mainConnection = iter->second;
+ if (std::find(mainConnection.listConnectionID.begin(), mainConnection.listConnectionID.end(), connectionID) != mainConnection.listConnectionID.end())
+ {
+ // Got it.
+ error = changeDelayMainConnection(calculateMainConnectionDelay(mainConnection.mainConnectionID), mainConnection.mainConnectionID);
+ }
+ }
+
+ return error;
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeConnectionFinal(const am_connectionID_t connectionID)
+{
+ assert(connectionID!=0);
+ am_Connection_Database_s const * connection = objectForKeyIfExistsInMap(connectionID, mMappedData.mConnectionMap);
+ if( NULL!=connection )
+ {
+ mMappedData.mConnectionMap.at(connectionID).reserved = false;
+ return E_OK;
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_timeSync_t CAmDatabaseHandlerMap::calculateMainConnectionDelay(const am_mainConnectionID_t mainConnectionID) const
+{
+ assert(mainConnectionID!=0);
+ if (!existMainConnection(mainConnectionID))
+ return -1;
+ const am_MainConnection_s & mainConnection = mMappedData.mMainConnectionMap.at(mainConnectionID);
+ am_timeSync_t delay = 0;
+ std::vector<am_connectionID_t>::const_iterator iter = mainConnection.listConnectionID.begin();
+ for(;iter<mainConnection.listConnectionID.end(); ++iter)
+ {
+ am_Connection_Database_s const * source = objectForKeyIfExistsInMap(*iter, mMappedData.mConnectionMap);
+ if( NULL!=source )
+ {
+ delay += std::max(source->delay, static_cast<am_timeSync_t>(0));
+ }
+ }
+ return (delay == 0 ? -1 : std::min(delay, static_cast<am_timeSync_t>(SHRT_MAX)));
+}
+
+/**
+ * registers the Observer at the Database
+ * @param iObserver pointer to the observer
+ */
+void CAmDatabaseHandlerMap::registerObserver(CAmDatabaseObserver *iObserver)
+{
+ assert(iObserver!=NULL);
+ mpDatabaseObserver = iObserver;
+}
+
+/**
+ * gives information about the visibility of a source
+ * @param sourceID the sourceID
+ * @return true if source is visible
+ */
+bool CAmDatabaseHandlerMap::sourceVisible(const am_sourceID_t sourceID) const
+{
+ assert(sourceID!=0);
+ if (!existSource(sourceID))
+ return false;
+ am_Source_Database_s source = mMappedData.mSourceMap.at(sourceID);
+ return source.visible;
+}
+
+/**
+ * gives information about the visibility of a sink
+ * @param sinkID the sinkID
+ * @return true if source is visible
+ */
+bool CAmDatabaseHandlerMap::sinkVisible(const am_sinkID_t sinkID) const
+{
+ am_Sink_Database_s const * source = objectForKeyIfExistsInMap(sinkID, mMappedData.mSinkMap);
+ if( NULL!=source )
+ {
+ if(0==source->reserved)
+ return source->visible;
+ }
+ return false;
+}
+
+/**
+ * checks if a connection already exists.
+ * Only takes sink, source and format information for search!
+ * @param connection the connection to be checked
+ * @return true if connections exists
+ */
+bool CAmDatabaseHandlerMap::existConnection(const am_Connection_s & connection) const
+{
+ am_Connection_Database_s const * connectionObject = objectMatchingPredicate<am_Connection_Database_s, am_connectionID_t>(mMappedData.mConnectionMap, [&](const am_Connection_Database_s & obj){
+ return false==obj.reserved &&
+ connection.sinkID == obj.sinkID &&
+ connection.sourceID == obj.sourceID &&
+ connection.connectionFormat == obj.connectionFormat;
+ });
+ return ( NULL!=connectionObject );
+}
+
+/**
+ * checks if a connection with the given ID exists
+ * @param connectionID
+ * @return true if connection exits
+ */
+bool CAmDatabaseHandlerMap::existConnectionID(const am_connectionID_t connectionID) const
+{
+ am_Connection_Database_s const * connection = objectForKeyIfExistsInMap(connectionID, mMappedData.mConnectionMap);
+ if( NULL!=connection )
+ {
+ return (0==connection->reserved);
+ }
+ return false;
+}
+
+/**
+ * checks if a CrossFader exists
+ * @param crossfaderID the ID of the crossfader to be checked
+ * @return true if exists
+ */
+bool CAmDatabaseHandlerMap::existCrossFader(const am_crossfaderID_t crossfaderID) const
+{
+ return existsObjectWithKeyInMap(crossfaderID, mMappedData.mCrossfaderMap);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSoureState(const am_sourceID_t sourceID, am_SourceState_e & sourceState) const
+{
+ am_Source_Database_s const * source = objectForKeyIfExistsInMap(sourceID, mMappedData.mSourceMap);
+ if( NULL!=source )
+ {
+ sourceState = source->sourceState;
+ return (E_OK);
+ }
+ else
+ {
+ sourceState = SS_UNKNNOWN;
+ return (E_NON_EXISTENT);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceState(const am_sourceID_t sourceID, const am_SourceState_e sourceState)
+{
+ assert(sourceID!=0);
+ assert(sourceState>=SS_UNKNNOWN && sourceState<=SS_MAX);
+ if(existSource(sourceID))
+ {
+ mMappedData.mSourceMap.at(sourceID).sourceState = sourceState;
+ return (E_OK);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSinkMainVolume(const am_sinkID_t sinkID, am_mainVolume_t& mainVolume) const {
+ assert(sinkID!=0);
+
+ am_Sink_Database_s const * source = objectForKeyIfExistsInMap(sinkID, mMappedData.mSinkMap);
+ if( NULL!=source )
+ {
+ mainVolume = source->mainVolume;
+ return (E_OK);
+ }
+ mainVolume = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSinkVolume(const am_sinkID_t sinkID, am_volume_t & volume) const
+{
+ assert(sinkID!=0);
+
+ am_Sink_Database_s const * source = objectForKeyIfExistsInMap(sinkID, mMappedData.mSinkMap);
+ if( NULL!=source )
+ {
+ volume = source->volume;
+ return (E_OK);
+ }
+ volume = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSourceVolume(const am_sourceID_t sourceID, am_volume_t & volume) const
+{
+ assert(sourceID!=0);
+ am_Source_Database_s const * source = objectForKeyIfExistsInMap(sourceID, mMappedData.mSourceMap);
+ if( NULL!=source )
+ {
+ volume = source->volume;
+ return (E_OK);
+ }
+ volume = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t & value) const
+{
+ assert(sinkID!=0);
+
+ am_Sink_Database_s * pObject = (am_Sink_Database_s *)objectForKeyIfExistsInMap(sinkID, mMappedData.mSinkMap);
+ if( NULL!=pObject )
+ {
+ if(pObject->listSoundProperties.size()>0 && 0==pObject->cacheSoundProperties.size())
+ {
+ std::vector<am_SoundProperty_s>::const_iterator iter = pObject->listSoundProperties.begin();
+ for(; iter<pObject->listSoundProperties.end(); ++iter)
+ pObject->cacheSoundProperties[iter->type] = iter->value;
+ }
+ auto it = pObject->cacheSoundProperties.find(propertyType);
+ if(it!=pObject->cacheSoundProperties.end())
+ {
+ value = it->second;
+ return (E_OK);
+ }
+ }
+ value = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t & value) const
+{
+ assert(sourceID!=0);
+
+ am_Source_Database_s * pObject = (am_Source_Database_s *)objectForKeyIfExistsInMap(sourceID, mMappedData.mSourceMap);
+ if( NULL!=pObject )
+ {
+ if(pObject->listSoundProperties.size()>0 && 0==pObject->cacheSoundProperties.size())
+ {
+ std::vector<am_SoundProperty_s>::const_iterator iter = pObject->listSoundProperties.begin();
+ for(; iter<pObject->listSoundProperties.end(); ++iter)
+ pObject->cacheSoundProperties[iter->type] = iter->value;
+ }
+ auto it = pObject->cacheSoundProperties.find(propertyType);
+ if(it!=pObject->cacheSoundProperties.end())
+ {
+ value = it->second;
+ return (E_OK);
+ }
+ }
+ value = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getMainSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const
+{
+ assert(sinkID!=0);
+
+ am_Sink_Database_s * pObject = (am_Sink_Database_s *)objectForKeyIfExistsInMap(sinkID, mMappedData.mSinkMap);
+ if( NULL!=pObject )
+ {
+ if(pObject->listMainSoundProperties.size()>0 && 0==pObject->cacheMainSoundProperties.size())
+ {
+ std::vector<am_MainSoundProperty_s>::const_iterator iter = pObject->listMainSoundProperties.begin();
+ for(; iter<pObject->listMainSoundProperties.end(); ++iter)
+ pObject->cacheMainSoundProperties[iter->type] = iter->value;
+ }
+ auto it = pObject->cacheMainSoundProperties.find(propertyType);
+ if(it!=pObject->cacheMainSoundProperties.end())
+ {
+ value = it->second;
+ return (E_OK);
+ }
+ }
+ value = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const
+{
+ assert(sourceID!=0);
+
+ am_Source_Database_s * pObject = (am_Source_Database_s *)objectForKeyIfExistsInMap(sourceID, mMappedData.mSourceMap);
+ if( NULL!=pObject )
+ {
+ if(pObject->listMainSoundProperties.size()>0 && 0==pObject->cacheMainSoundProperties.size())
+ {
+ std::vector<am_MainSoundProperty_s>::const_iterator iter = pObject->listMainSoundProperties.begin();
+ for(; iter<pObject->listMainSoundProperties.end(); ++iter)
+ pObject->cacheMainSoundProperties[iter->type] = iter->value;
+ }
+ auto it = pObject->cacheMainSoundProperties.find(propertyType);
+ if(it!=pObject->cacheMainSoundProperties.end())
+ {
+ value = it->second;
+ return (E_OK);
+ }
+ }
+
+ value = -1;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getDomainState(const am_domainID_t domainID, am_DomainState_e& state) const
+{
+ assert(domainID!=0);
+
+ am_Domain_Database_s const * source = objectForKeyIfExistsInMap(domainID, mMappedData.mDomainMap);
+ if( NULL!=source )
+ {
+ state = source->state;
+ return (E_OK);
+ }
+ state = DS_UNKNOWN;
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::peekDomain(const std::string & name, am_domainID_t & domainID)
+{
+ domainID=0;
+
+ am_Domain_Database_s const *reservedDomain = objectMatchingPredicate<am_Domain_Database_s, am_domainID_t>(mMappedData.mDomainMap, [&](const am_Domain_Database_s & obj){
+ return name.compare(obj.name)==0;
+ });
+
+ if( NULL != reservedDomain )
+ {
+ domainID = reservedDomain->domainID;
+ return E_OK;
+ }
+ else
+ {
+ int16_t nextID = 0;
+ if( mMappedData.increaseID( nextID, mMappedData.mCurrentDomainID) )
+ {
+ domainID = nextID;
+ am_Domain_Database_s domain;
+ domain.domainID = nextID;
+ domain.name = name;
+ domain.reserved = 1;
+ mMappedData.mDomainMap[nextID] = domain;
+ return E_OK;
+ }
+ return E_UNKNOWN;
+ }
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::peekSink(const std::string & name, am_sinkID_t & sinkID)
+{
+ am_Sink_Database_s const *reservedSink = objectMatchingPredicate<am_Sink_Database_s, am_sinkID_t>(mMappedData.mSinkMap, [&](const am_Sink_Database_s & obj){
+ return name.compare(obj.name)==0;
+ });
+ if( NULL!=reservedSink )
+ {
+ sinkID = reservedSink->sinkID;
+ return E_OK;
+ }
+ else
+ {
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentSinkID))
+ {
+ if(mFirstStaticSink)
+ {
+ nextID = DYNAMIC_ID_BOUNDARY;
+ mFirstStaticSink = false;
+ }
+ sinkID = nextID;
+ am_Sink_Database_s object;
+ object.sinkID = nextID;
+ object.name = name;
+ object.reserved = 1;
+ mMappedData.mSinkMap[nextID] = object;
+ return E_OK;
+ }
+ return E_UNKNOWN;
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::peekSource(const std::string & name, am_sourceID_t & sourceID)
+{
+ am_Source_Database_s const *reservedSrc = objectMatchingPredicate<am_Source_Database_s, am_sourceID_t>(mMappedData.mSourceMap, [&](const am_Source_Database_s & obj){
+ return name.compare(obj.name)==0;
+ });
+ if( NULL!=reservedSrc )
+ {
+ sourceID = reservedSrc->sourceID;
+ return E_OK;
+ }
+ else
+ {
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentSourceID))
+ {
+ if(mFirstStaticSource)
+ {
+// nextID = DYNAMIC_ID_BOUNDARY;
+ mFirstStaticSource = false;
+ }
+ sourceID = nextID;
+ am_Source_Database_s object;
+ object.sourceID = nextID;
+ object.name = name;
+ object.reserved = 1;
+ mMappedData.mSourceMap[nextID] = object;
+ return E_OK;
+ }
+ else
+ return E_UNKNOWN;
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkVolume(const am_sinkID_t sinkID, const am_volume_t volume)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mSinkMap[sinkID].volume = volume;
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceVolume(const am_sourceID_t sourceID, const am_volume_t volume)
+{
+ assert(sourceID!=0);
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ mMappedData.mSourceMap[sourceID].volume = volume;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceSoundPropertyDB(const am_SoundProperty_s & soundProperty, const am_sourceID_t sourceID)
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ am_Source_Database_s & source = mMappedData.mSourceMap[sourceID];
+ std::vector<am_SoundProperty_s>::iterator iter = source.listSoundProperties.begin();
+ for(; iter<source.listSoundProperties.end(); ++iter)
+ {
+ if( soundProperty.type == iter->type )
+ {
+ iter->value = soundProperty.value;
+ if(source.cacheSoundProperties.size())
+ source.cacheSoundProperties[soundProperty.type] = soundProperty.value;
+ return (E_OK);
+ }
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkSoundPropertyDB(const am_SoundProperty_s & soundProperty, const am_sinkID_t sinkID)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ am_Sink_Database_s & sink = mMappedData.mSinkMap[sinkID];
+ std::vector<am_SoundProperty_s>::iterator iter = sink.listSoundProperties.begin();
+ for(; iter<sink.listSoundProperties.end(); ++iter)
+ {
+ if( soundProperty.type == iter->type )
+ {
+ iter->value = soundProperty.value;
+ if(sink.cacheSoundProperties.size())
+ sink.cacheSoundProperties[soundProperty.type] = soundProperty.value;
+ return (E_OK);
+ }
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeCrossFaderHotSink(const am_crossfaderID_t crossfaderID, const am_HotSink_e hotsink)
+{
+ assert(crossfaderID!=0);
+ assert(hotsink!=HS_UNKNOWN);
+
+ if (!existCrossFader(crossfaderID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mCrossfaderMap[crossfaderID].hotSink = hotsink;
+ return (E_OK);
+}
+
+bool CAmDatabaseHandlerMap::isComponentConnected(const am_Gateway_s & gateway) const
+{
+ bool ret = isConnected(gateway);
+ return ret;
+}
+
+bool CAmDatabaseHandlerMap::isComponentConnected(const am_Converter_s & converter) const
+{
+ bool ret = isConnected(converter);
+ return ret;
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::peekSinkClassID(const std::string & name, am_sinkClass_t & sinkClassID)
+{
+ if (name.empty())
+ return (E_NON_EXISTENT);
+ am_SinkClass_Database_s const *reserved = objectMatchingPredicate<am_SinkClass_Database_s, am_sinkClass_t>(mMappedData.mSinkClassesMap, [&](const am_SinkClass_Database_s & obj){
+ return name.compare(obj.name)==0;
+ });
+ if( NULL!=reserved )
+ {
+ sinkClassID = reserved->sinkClassID;
+ return E_OK;
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e am::CAmDatabaseHandlerMap::peekSourceClassID(const std::string & name, am_sourceClass_t & sourceClassID)
+{
+ if (name.empty())
+ return (E_NON_EXISTENT);
+ am_SourceClass_Database_s const *ptrSource = objectMatchingPredicate<am_SourceClass_Database_s, am_sourceClass_t>(mMappedData.mSourceClassesMap, [&](const am_SourceClass_Database_s & obj){
+ return name.compare(obj.name)==0;
+ });
+ if( NULL!=ptrSource )
+ {
+ sourceClassID = ptrSource->sourceClassID;
+ return E_OK;
+ }
+ return (E_NON_EXISTENT);
+}
+
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceDB(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ DB_COND_UPDATE_INIT;
+ am_sourceClass_t sourceClassOut(sourceClassID);
+ std::vector<am_MainSoundProperty_s> listMainSoundPropertiesOut(listMainSoundProperties);
+ //check if sinkClass needs to be changed
+
+ std::unordered_map<am_sourceID_t, am_Source_Database_s>::iterator iter = mMappedData.mSourceMap.begin();
+ for(; iter!=mMappedData.mSourceMap.end(); ++iter)
+ {
+ if( iter->second.sourceID == sourceID )
+ {
+ if (sourceClassID != 0)
+ {
+ DB_COND_UPDATE(iter->second.sourceClassID, sourceClassID);
+ }
+ else if (0 == iter->second.reserved)
+ {
+ sourceClassOut = iter->second.sourceClassID;
+ }
+ break;
+ }
+ }
+
+ //check if soundProperties need to be updated
+ if (!listSoundProperties.empty())
+ {
+ mMappedData.mSourceMap.at(sourceID).listSoundProperties = listSoundProperties;
+ mMappedData.mSourceMap.at(sourceID).cacheSoundProperties.clear();
+ }
+
+ //check if we have to update the list of connectionformats
+ if (!listConnectionFormats.empty())
+ {
+ mMappedData.mSourceMap.at(sourceID).listConnectionFormats = listConnectionFormats;
+ }
+
+ //then we need to check if we need to update the listMainSoundProperties
+ if (sourceVisible(sourceID))
+ {
+ if (!listMainSoundProperties.empty())
+ {
+ DB_COND_UPDATE(mMappedData.mSourceMap.at(sourceID).listMainSoundProperties, listMainSoundProperties);
+ mMappedData.mSourceMap.at(sourceID).cacheMainSoundProperties.clear();
+ }
+ else
+ {
+ getListMainSourceSoundProperties(sourceID,listMainSoundPropertiesOut);
+ }
+ }
+
+ if (DB_COND_ISMODIFIED)
+ {
+ logInfo("DatabaseHandler::changeSource changed changeSource of source:", sourceID);
+
+ if (mpDatabaseObserver != NULL)
+ {
+ mpDatabaseObserver->sourceUpdated(sourceID,sourceClassOut,listMainSoundPropertiesOut,sourceVisible(sourceID));
+ }
+ }
+
+ return (E_OK);
+
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkDB(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ assert(sinkID!=0);
+
+ DB_COND_UPDATE_INIT;
+ am_sinkClass_t sinkClassOut(sinkClassID);
+ std::vector<am_MainSoundProperty_s> listMainSoundPropertiesOut(listMainSoundProperties);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ std::unordered_map<am_sinkID_t, am_Sink_Database_s>::iterator iter = mMappedData.mSinkMap.begin();
+ for(; iter!=mMappedData.mSinkMap.end(); ++iter)
+ {
+ if (iter->second.sinkID == sinkID)
+ {
+ if (sinkClassID != 0)
+ {
+ DB_COND_UPDATE(iter->second.sinkClassID, sinkClassID);
+ }
+ else if (0 == iter->second.reserved)
+ {
+ sinkClassOut = iter->second.sinkClassID;
+ }
+ break;
+ }
+ }
+
+ //check if soundProperties need to be updated
+ if (!listSoundProperties.empty())
+ {
+ mMappedData.mSinkMap.at(sinkID).listSoundProperties = listSoundProperties;
+ mMappedData.mSinkMap.at(sinkID).cacheSoundProperties.clear();
+ }
+
+ //check if we have to update the list of connectionformats
+ if (!listConnectionFormats.empty())
+ {
+ mMappedData.mSinkMap.at(sinkID).listConnectionFormats = listConnectionFormats;
+ }
+
+ //then we need to check if we need to update the listMainSoundProperties
+ if (sinkVisible(sinkID))
+ {
+ if (!listMainSoundProperties.empty())
+ {
+ DB_COND_UPDATE(mMappedData.mSinkMap.at(sinkID).listMainSoundProperties, listMainSoundProperties);
+ mMappedData.mSinkMap.at(sinkID).cacheMainSoundProperties.clear();
+ }
+ else //read out the properties
+ {
+ getListMainSinkSoundProperties(sinkID,listMainSoundPropertiesOut);
+ }
+ }
+
+ if (DB_COND_ISMODIFIED)
+ {
+ logInfo("DatabaseHandler::changeSink changed changeSink of sink:", sinkID);
+
+ if (mpDatabaseObserver != NULL)
+ {
+ mpDatabaseObserver->sinkUpdated(sinkID,sinkClassOut,listMainSoundPropertiesOut,sinkVisible(sinkID));
+ }
+ }
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainSinkNotificationConfigurations(const am_sinkID_t sinkID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations)
+{
+ assert(sinkID!=0);
+ if (!existSink(sinkID))
+ return (E_DATABASE_ERROR); // todo: here we could change to non existen, but not shown in sequences
+ listMainNotificationConfigurations.clear();
+
+ listMainNotificationConfigurations = mMappedData.mSinkMap.at(sinkID).listMainNotificationConfigurations;
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::getListMainSourceNotificationConfigurations(const am_sourceID_t sourceID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations)
+{
+ assert(sourceID!=0);
+ if (!existSource(sourceID))
+ return (E_DATABASE_ERROR); // todo: here we could change to non existen, but not shown in sequences
+
+ listMainNotificationConfigurations = mMappedData.mSourceMap.at(sourceID).listMainNotificationConfigurations;
+
+ return (E_OK);
+}
+
+bool changeMainNotificationConfiguration(std::vector<am_NotificationConfiguration_s> & listMainNotificationConfigurations,
+ const am_NotificationConfiguration_s & mainNotificationConfiguration)
+{
+ std::vector<am_NotificationConfiguration_s>::iterator iter = listMainNotificationConfigurations.begin();
+ for(; iter<listMainNotificationConfigurations.end(); ++iter)
+ {
+ if( mainNotificationConfiguration.type == iter->type )
+ {
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ if( iter->status == mainNotificationConfiguration.status && iter->parameter == mainNotificationConfiguration.parameter )
+ return false;
+#endif
+ *iter = mainNotificationConfiguration;
+ return true;
+ }
+ }
+ return false;
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ if(!changeMainNotificationConfiguration(mMappedData.mSinkMap.at(sinkID).listMainNotificationConfigurations, mainNotificationConfiguration))
+ return (E_NO_CHANGE);
+
+ logInfo("DatabaseHandler::changeMainSinkNotificationConfigurationDB changed MainNotificationConfiguration of source:", sinkID, "type:", mainNotificationConfiguration.type, "to status=", mainNotificationConfiguration.status, "and parameter=",mainNotificationConfiguration.parameter);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->sinkMainNotificationConfigurationChanged(sinkID, mainNotificationConfiguration);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration)
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ if(!changeMainNotificationConfiguration(mMappedData.mSourceMap.at(sourceID).listMainNotificationConfigurations, mainNotificationConfiguration))
+ return (E_NO_CHANGE);
+
+ logInfo("DatabaseHandler::changeMainSourceNotificationConfigurationDB changed MainNotificationConfiguration of source:", sourceID, "type:", mainNotificationConfiguration.type, "to status=", mainNotificationConfiguration.status, "and parameter=",mainNotificationConfiguration.parameter);
+
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->sourceMainNotificationConfigurationChanged(sourceID, mainNotificationConfiguration);
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeGatewayDB(const am_gatewayID_t gatewayID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ assert(gatewayID!=0);
+
+ if (!existGateway(gatewayID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ if (!listSourceConnectionFormats.empty())
+ {
+ mMappedData.mGatewayMap.at(gatewayID).listSourceFormats = listSourceConnectionFormats;
+ }
+
+ if (!listSinkConnectionFormats.empty())
+ {
+ mMappedData.mGatewayMap.at(gatewayID).listSinkFormats = listSinkConnectionFormats;
+ }
+
+ if (!convertionMatrix.empty())
+ {
+ mListConnectionFormat.clear();
+ mListConnectionFormat.insert(std::make_pair(gatewayID, convertionMatrix));
+ }
+
+ logInfo("DatabaseHandler::changeGatewayDB changed Gateway with ID", gatewayID);
+
+ //todo: check if observer needs to be adopted.
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeConverterDB(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ assert(converterID!=0);
+
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ if (!listSourceConnectionFormats.empty())
+ {
+ mMappedData.mConverterMap.at(converterID).listSourceFormats = listSourceConnectionFormats;
+ }
+
+ if (!listSinkConnectionFormats.empty())
+ {
+ mMappedData.mConverterMap.at(converterID).listSinkFormats = listSinkConnectionFormats;
+ }
+
+ if (!convertionMatrix.empty())
+ {
+ mListConnectionFormat.clear();
+ mListConnectionFormat.insert(std::make_pair(converterID, convertionMatrix));
+ }
+
+ logInfo("DatabaseHandler::changeConverterDB changed Gateway with ID", converterID);
+
+ //todo: check if observer needs to be adopted.
+ return (E_OK);
+}
+
+bool changeNotificationConfiguration(std::vector<am_NotificationConfiguration_s> & listNotificationConfigurations, const am_NotificationConfiguration_s & notificationConfiguration)
+{
+ bool changed = false;
+ std::vector<am_NotificationConfiguration_s>::iterator iter = listNotificationConfigurations.begin();
+ for(; iter<listNotificationConfigurations.end(); ++iter)
+ {
+ if( notificationConfiguration.type == iter->type )
+ {
+ iter->status = notificationConfiguration.status;
+ iter->parameter = notificationConfiguration.parameter;
+ changed |= true;
+ }
+ }
+ return changed;
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s notificationConfiguration)
+{
+ assert(sinkID!=0);
+
+ if (!existSink(sinkID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ if(!changeNotificationConfiguration(mMappedData.mSinkMap.at(sinkID).listNotificationConfigurations, notificationConfiguration))
+ return (E_NO_CHANGE);
+
+ logInfo("DatabaseHandler::changeMainSinkNotificationConfigurationDB changed MainNotificationConfiguration of source:", sinkID, "type:", notificationConfiguration.type, "to status=", notificationConfiguration.status, "and parameter=",notificationConfiguration.parameter);
+
+ //todo:: inform obsever here...
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::changeSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s notificationConfiguration)
+{
+ assert(sourceID!=0);
+
+ if (!existSource(sourceID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ if(!changeNotificationConfiguration(mMappedData.mSourceMap.at(sourceID).listNotificationConfigurations, notificationConfiguration))
+ return (E_NO_CHANGE);
+
+ logInfo("DatabaseHandler::changeSourceNotificationConfigurationDB changed MainNotificationConfiguration of source:", sourceID, "type:", notificationConfiguration.type, "to status=", notificationConfiguration.status, "and parameter=",notificationConfiguration.parameter);
+
+ //todo:: implement observer function
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateSources(std::function<void(const am_Source_s & element)> cb) const
+{
+ for(auto it = mMappedData.mSourceMap.begin(); it!=mMappedData.mSourceMap.end(); it++)
+ {
+ const am_Source_Database_s *pObject = &it->second;
+ if( 0==pObject->reserved )
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const
+{
+ for(auto it = mMappedData.mSinkMap.begin(); it!=mMappedData.mSinkMap.end(); it++)
+ {
+ const am_Sink_Database_s *pObject = &it->second;
+ if( 0==pObject->reserved )
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const
+{
+ for(auto it = mMappedData.mGatewayMap.begin(); it!=mMappedData.mGatewayMap.end(); it++)
+ {
+ const am_Gateway_s *pObject = &it->second;
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const
+{
+ for(auto it = mMappedData.mConverterMap.begin(); it!=mMappedData.mConverterMap.end(); it++)
+ {
+ const am_Converter_s *pObject = &it->second;
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+}
diff --git a/AudioManagerCore/src/CAmDatabaseObserver.cpp b/AudioManagerCore/src/CAmDatabaseObserver.cpp
new file mode 100644
index 0000000..acac639
--- /dev/null
+++ b/AudioManagerCore/src/CAmDatabaseObserver.cpp
@@ -0,0 +1,242 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmDatabaseObserver.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmDatabaseObserver.h"
+#include <string.h>
+#include <cassert>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include "CAmCommandSender.h"
+#include "CAmRoutingSender.h"
+#include "CAmTelnetServer.h"
+#include "CAmDltWrapper.h"
+#include "CAmSerializer.h"
+
+namespace am {
+
+CAmDatabaseObserver::CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler) :
+ mCommandSender(iCommandSender), //
+ mRoutingSender(iRoutingSender), //
+ mTelnetServer(NULL), //
+ mSerializer(iSocketHandler) //
+{
+ assert(mCommandSender!=0);
+ assert(mRoutingSender!=0);
+ assert(iSocketHandler!=0);
+}
+
+CAmDatabaseObserver::CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler, CAmTelnetServer *iTelnetServer) :
+ mCommandSender(iCommandSender), //
+ mRoutingSender(iRoutingSender), //
+ mTelnetServer(iTelnetServer), //
+ mSerializer(iSocketHandler) //
+{
+ assert(mTelnetServer!=0);
+ assert(mCommandSender!=0);
+ assert(mRoutingSender!=0);
+ assert(iSocketHandler!=0);
+}
+
+CAmDatabaseObserver::~CAmDatabaseObserver()
+{
+}
+
+void CAmDatabaseObserver::newMainConnection(const am_MainConnectionType_s& mainConnection)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_MainConnectionType_s>(mCommandSender, &CAmCommandSender::cbNewMainConnection, mainConnection);
+}
+
+void CAmDatabaseObserver::removedMainConnection(const am_mainConnectionID_t mainConnection)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_mainConnectionID_t>(mCommandSender, &CAmCommandSender::cbRemovedMainConnection, mainConnection);
+}
+
+void CAmDatabaseObserver::newSink(const am_Sink_s& sink)
+{
+ mRoutingSender->addSinkLookup(sink);
+ if (sink.visible)
+ {
+ am_SinkType_s s;
+ s.availability = sink.available;
+ s.muteState = sink.muteState;
+ s.name = sink.name;
+ s.sinkClassID = sink.sinkClassID;
+ s.sinkID = sink.sinkID;
+ s.volume = sink.mainVolume;
+ mSerializer.asyncCall<CAmCommandSender, const am_SinkType_s>(mCommandSender, &CAmCommandSender::cbNewSink, s);
+ }
+}
+
+void CAmDatabaseObserver::newSource(const am_Source_s& source)
+{
+ mRoutingSender->addSourceLookup(source);
+ if (source.visible)
+ {
+ am_SourceType_s s;
+ s.availability = source.available;
+ s.name = source.name;
+ s.sourceClassID = source.sourceClassID;
+ s.sourceID = source.sourceID;
+ mSerializer.asyncCall<CAmCommandSender, const am_SourceType_s>(mCommandSender, &CAmCommandSender::cbNewSource, s);
+ }
+}
+
+void CAmDatabaseObserver::newDomain(const am_Domain_s& domain)
+{
+ mRoutingSender->addDomainLookup(domain);
+}
+
+void CAmDatabaseObserver::newGateway(const am_Gateway_s& gateway)
+{
+ (void) gateway;
+ //todo: implement something
+}
+
+void CAmDatabaseObserver::newConverter(const am_Converter_s& coverter)
+{
+ (void) coverter;
+ //todo: implement something
+}
+
+void CAmDatabaseObserver::newCrossfader(const am_Crossfader_s& crossfader)
+{
+ mRoutingSender->addCrossfaderLookup(crossfader);
+}
+
+void CAmDatabaseObserver::removedSink(const am_sinkID_t sinkID, const bool visible)
+{
+ mRoutingSender->removeSinkLookup(sinkID);
+
+ if (visible)
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t>(mCommandSender, &CAmCommandSender::cbRemovedSink, sinkID);
+}
+
+void CAmDatabaseObserver::removedSource(const am_sourceID_t sourceID, const bool visible)
+{
+ mRoutingSender->removeSourceLookup(sourceID);
+
+ if (visible)
+ mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t>(mCommandSender, &CAmCommandSender::cbRemovedSource, sourceID);
+}
+
+void CAmDatabaseObserver::removeDomain(const am_domainID_t domainID)
+{
+ mRoutingSender->removeDomainLookup(domainID);
+}
+
+void CAmDatabaseObserver::removeGateway(const am_gatewayID_t gatewayID)
+{
+ (void) gatewayID;
+ //todo: implement something?
+}
+
+void CAmDatabaseObserver::removeConverter(const am_converterID_t converterID)
+{
+ (void) converterID;
+ //todo: implement something?
+}
+
+void CAmDatabaseObserver::removeCrossfader(const am_crossfaderID_t crossfaderID)
+{
+ mRoutingSender->removeCrossfaderLookup(crossfaderID);
+}
+
+void CAmDatabaseObserver::numberOfSinkClassesChanged()
+{
+ mSerializer.asyncCall<CAmCommandSender>(mCommandSender, &CAmCommandSender::cbNumberOfSinkClassesChanged);
+}
+
+void CAmDatabaseObserver::numberOfSourceClassesChanged()
+{
+ mSerializer.asyncCall<CAmCommandSender>(mCommandSender, &CAmCommandSender::cbNumberOfSourceClassesChanged);
+}
+
+void CAmDatabaseObserver::mainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_connectionID_t, const am_ConnectionState_e>(mCommandSender, &CAmCommandSender::cbMainConnectionStateChanged, connectionID, connectionState);
+}
+
+void CAmDatabaseObserver::mainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_MainSoundProperty_s>(mCommandSender, &CAmCommandSender::cbMainSinkSoundPropertyChanged, sinkID, SoundProperty);
+}
+
+void CAmDatabaseObserver::mainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s & SoundProperty)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_MainSoundProperty_s>(mCommandSender, &CAmCommandSender::cbMainSourceSoundPropertyChanged, sourceID, SoundProperty);
+}
+
+void CAmDatabaseObserver::sinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s & availability)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_Availability_s>(mCommandSender, &CAmCommandSender::cbSinkAvailabilityChanged, sinkID, availability);
+}
+
+void CAmDatabaseObserver::sourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s & availability)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_Availability_s>(mCommandSender, &CAmCommandSender::cbSourceAvailabilityChanged, sourceID, availability);
+}
+
+void CAmDatabaseObserver::volumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_mainVolume_t>(mCommandSender, &CAmCommandSender::cbVolumeChanged, sinkID, volume);
+}
+
+void CAmDatabaseObserver::sinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_MuteState_e>(mCommandSender, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState);
+}
+
+void CAmDatabaseObserver::systemPropertyChanged(const am_SystemProperty_s& SystemProperty)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_SystemProperty_s>(mCommandSender, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty);
+}
+
+void CAmDatabaseObserver::timingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_mainConnectionID_t, const am_timeSync_t>(mCommandSender, &CAmCommandSender::cbTimingInformationChanged, mainConnection, time);
+}
+
+void CAmDatabaseObserver::sinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible)
+{
+ if (visible)
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_sinkClass_t, const std::vector<am_MainSoundProperty_s> >(mCommandSender, &CAmCommandSender::cbSinkUpdated, sinkID, sinkClassID, listMainSoundProperties);
+}
+
+void CAmDatabaseObserver::sourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible)
+{
+ if (visible)
+ mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_sourceClass_t, const std::vector<am_MainSoundProperty_s> >(mCommandSender, &CAmCommandSender::cbSinkUpdated, sourceID, sourceClassID, listMainSoundProperties);
+}
+
+void CAmDatabaseObserver::sinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_NotificationConfiguration_s> (mCommandSender, &CAmCommandSender::cbSinkMainNotificationConfigurationChanged, sinkID, mainNotificationConfiguration);
+}
+
+void CAmDatabaseObserver::sourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration)
+{
+ mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_NotificationConfiguration_s>(mCommandSender, &CAmCommandSender::cbSourceMainNotificationConfigurationChanged, sourceID, mainNotificationConfiguration);
+}
+
+}
diff --git a/AudioManagerCore/src/CAmLog.cpp b/AudioManagerCore/src/CAmLog.cpp
new file mode 100644
index 0000000..f68f660
--- /dev/null
+++ b/AudioManagerCore/src/CAmLog.cpp
@@ -0,0 +1,101 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Aleksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2013
+ *
+ * \file CAmLog.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmLog.h"
+
+
+void CAmLog::CAmFileLogger::generateLogFilename(std::string &result)
+{
+ static uint32_t logFileID = 1;
+ time_t rawtime;
+ time (&rawtime);
+
+ std::ostringstream stream;
+ stream << DEFAULT_LOG_FOLDER << DEFAULT_LOGFILE_PREFIX << logFileID << "_" << rawtime << DEFAULT_LOGFILE_EXT;
+ logFileID++;
+ result = stream.str();
+}
+
+CAmLog::CAmFileLogger::~CAmFileLogger()
+{
+ if (mOutputStream)
+ {
+ std::ofstream* of = static_cast<std::ofstream*>(mOutputStream);
+ of->close();
+ DEL(mOutputStream)
+ }
+}
+
+CAmLog::CAmLog(const eCAmLogType type ):mLogType(type)
+{
+ instantiateLogger(type);
+}
+
+CAmLog::CAmLog():mLogType(eCAmLogStdout)
+{
+ instantiateLogger((const eCAmLogType)eCAmLogStdout);
+}
+
+CAmLog::~CAmLog()
+{
+ releaseLogger();
+}
+
+void CAmLog::releaseLogger()
+{
+ if(mLogger)
+ DEL(mLogger)
+}
+
+void CAmLog::instantiateLogger( const eCAmLogType type)
+{
+ if( eCAmLogStdout == type )
+ mLogger = new CAmStdOutLogger();
+ else if( eCAmLogFile == type )
+ {
+ std::string filename("");
+ CAmLog::CAmFileLogger::generateLogFilename(filename);
+ mLogger = new CAmFileLogger(filename);
+ }
+}
+
+CAmLog *CAmLog::getDefaultLog()
+{
+ static CAmLog theInstance;
+ return &theInstance;
+}
+
+void CAmLog::setLogType( const eCAmLogType type)
+{
+ if(mLogType!=type)
+ {
+ mLogType = type;
+ releaseLogger();
+ instantiateLogger(type);
+ }
+}
+
+eCAmLogType CAmLog::getLogType() const
+{
+ return mLogType;
+}
diff --git a/AudioManagerCore/src/CAmRouter.cpp b/AudioManagerCore/src/CAmRouter.cpp
new file mode 100644
index 0000000..f98bf11
--- /dev/null
+++ b/AudioManagerCore/src/CAmRouter.cpp
@@ -0,0 +1,884 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ * \author Aleksandar Donchev, Aleksander.Donchev@partner.bmw.de BMW 2013,2014
+ *
+ * \file CAmRouter.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <cassert>
+#include <algorithm>
+#include <vector>
+#include <iterator>
+#include "CAmRouter.h"
+#include "IAmDatabaseHandler.h"
+#include "CAmControlSender.h"
+#include "CAmDltWrapper.h"
+
+
+
+namespace am {
+
+
+template <class X> void getMergeConnectionFormats(const X * element,
+ const am_CustomConnectionFormat_t connectionFormat,
+ const std::vector<am_CustomConnectionFormat_t> & listConnectionFormats,
+ std::vector<am_CustomConnectionFormat_t> & outListMergeConnectionFormats)
+{
+ std::vector<am_CustomConnectionFormat_t> listRestrictedConnectionFormats;
+ CAmRouter::getRestrictedOutputFormats(element->convertionMatrix,
+ element->listSourceFormats,
+ element->listSinkFormats,
+ connectionFormat,
+ listRestrictedConnectionFormats);
+ std::sort(listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end()); //todo: this might be not needed if we use strictly sorted input
+ std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(outListMergeConnectionFormats, outListMergeConnectionFormats.begin());
+ set_intersection(listConnectionFormats.begin(), listConnectionFormats.end(), listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end(), inserter);
+}
+
+
+CAmRouter::CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender) :
+ mpDatabaseHandler(iDatabaseHandler), //
+ mpControlSender(iSender),
+ mOnlyFreeConversionNodes(false),
+ mRoutingGraph(),
+ mNodeListSources(),
+ mNodeListSinks(),
+ mNodeListGateways(),
+ mNodeListConverters()
+{
+ assert(mpDatabaseHandler);
+ assert(mpControlSender);
+}
+
+CAmRouter::~CAmRouter()
+{
+}
+
+/**
+ * returns the best route between a source and a sink
+ * @param onlyfree if true only free gateways are used
+ * @param sourceID
+ * @param sinkID
+ * @param returnList this list contains a set of routes
+ * @return E_OK in case of success
+ */
+am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s> & returnList)
+{
+ returnList.clear();
+ am_Source_s source;
+ am_Sink_s sink;
+ am_Error_e error = mpDatabaseHandler->getSourceInfoDB(sourceID, source);
+ if(error!=E_OK)
+ return error;
+ error = mpDatabaseHandler->getSinkInfoDB(sinkID, sink);
+ if(error!=E_OK)
+ return error;
+ error = getRoute(onlyfree, source, sink, returnList);
+ return error;
+}
+
+
+am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes)
+{
+ am_Error_e error;
+ load(onlyfree);
+
+ CAmRoutingNode* pRootSource = sourceNodeWithID(aSource.sourceID);
+ CAmRoutingNode* pRootSink = sinkNodeWithID(aSink.sinkID);
+
+ assert(pRootSource);
+ assert(pRootSink);
+
+#ifdef TRACE_GRAPH
+ mRoutingGraph.trace([&](const CAmRoutingNode & node, const std::vector<CAmVertex<am_RoutingNodeData_s,uint16_t>*> & list) {
+ std::cout << "Node " << node.getIndex() << " :";
+ ((CAmRoutingNode &)node).getData().trace();
+ std::cout << "-->";
+ std::for_each(list.begin(), list.end(), [&](const CAmVertex<am_RoutingNodeData_s,uint16_t>* refVertex){
+ am::CAmNode<am::am_RoutingNodeData_s>* data = refVertex->getNode();
+ std::cout << "Node " << data->getIndex() << " :";
+ data->getData().trace();
+ });
+ std::cout << std::endl;
+ });
+#endif
+
+ std::vector<std::vector<CAmRoutingNode*>> pathNodes;
+ error = getAllPaths(*pRootSource, *pRootSink, listRoutes, pathNodes);
+ return error;
+}
+
+void CAmRouter::load(const bool onlyFree)
+{
+ clear();
+ mOnlyFreeConversionNodes = onlyFree;
+
+#if defined (WITH_DATABASE_STORAGE)
+ std::deque<am_Source_s> listSources;
+ std::deque<am_Sink_s> listSinks;
+ std::deque<am_Gateway_s> listGateways;
+ std::deque<am_Converter_s> listConverters;
+#endif
+ am_RoutingNodeData_s nodeDataSrc;
+ nodeDataSrc.type = CAmNodeDataType::SOURCE;
+ mpDatabaseHandler->enumerateSources([&](const am_Source_s & obj){
+#if defined (WITH_DATABASE_STORAGE)
+ listSources.push_back(obj);
+ nodeDataSrc.data.source = &listSources.back();
+#else
+ nodeDataSrc.data.source = (am_Source_s*)&obj;
+#endif
+ mNodeListSources[nodeDataSrc.data.source->domainID].push_back(&mRoutingGraph.addNode(nodeDataSrc));
+ });
+ am_RoutingNodeData_s nodeDataSink;
+ nodeDataSink.type = CAmNodeDataType::SINK;
+ mpDatabaseHandler->enumerateSinks([&](const am_Sink_s & obj){
+#if defined (WITH_DATABASE_STORAGE)
+ listSinks.push_back(obj);
+ nodeDataSrc.data.sink = &listSinks.back();
+#else
+ nodeDataSink.data.sink = (am_Sink_s*)&obj;
+#endif
+ mNodeListSinks[nodeDataSink.data.sink->domainID].push_back(&mRoutingGraph.addNode(nodeDataSink));
+ });
+ am_RoutingNodeData_s nodeDataGateway;
+ nodeDataGateway.type = CAmNodeDataType::GATEWAY;
+ mpDatabaseHandler->enumerateGateways([&](const am_Gateway_s & obj){
+#if defined (WITH_DATABASE_STORAGE)
+ listGateways.push_back(obj);
+ nodeDataSrc.data.gateway = &listGateways.back();
+#else
+ nodeDataGateway.data.gateway = (am_Gateway_s*)&obj;
+#endif
+ mNodeListGateways[nodeDataGateway.data.gateway->controlDomainID].push_back(&mRoutingGraph.addNode(nodeDataGateway));
+ });
+ am_RoutingNodeData_s nodeDataConverter;
+ nodeDataConverter.type = CAmNodeDataType::CONVERTER;
+ mpDatabaseHandler->enumerateConverters([&](const am_Converter_s & obj){
+#if defined (WITH_DATABASE_STORAGE)
+ listConverters.push_back(obj);
+ nodeDataSrc.data.converter = &listConverters.back();
+#else
+ nodeDataConverter.data.converter = (am_Converter_s*)&obj;
+#endif
+ mNodeListConverters[nodeDataConverter.data.converter->domainID].push_back(&mRoutingGraph.addNode(nodeDataConverter));
+ });
+
+#ifdef ROUTING_BUILD_CONNECTIONS
+ constructConverterConnections();
+ constructGatewayConnections();
+ constructSourceSinkConnections();
+#endif
+}
+
+void CAmRouter::clear()
+{
+ mRoutingGraph.clear();
+ mNodeListSources.clear();
+ mNodeListSinks.clear();
+ mNodeListGateways.clear();
+ mNodeListConverters.clear();
+}
+
+CAmRoutingNode* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID)
+{
+ CAmRoutingNode* result = NULL;
+ for(auto it = mNodeListSinks.begin(); it!=mNodeListSinks.end(); it++)
+ {
+ result = sinkNodeWithID(sinkID, it->first);
+ if(result)
+ return result;
+ }
+ return result;
+}
+
+CAmRoutingNode* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID)
+{
+ CAmRoutingNode* result = NULL;
+ std::vector<CAmRoutingNode*> & value = mNodeListSinks[domainID];
+ auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){
+ return node->getData().data.sink->sinkID==sinkID;
+ });
+ if(iter!=value.end())
+ result = *iter;
+ return result;
+}
+
+CAmRoutingNode* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID)
+{
+ CAmRoutingNode* result = NULL;
+ for(auto it = mNodeListSources.begin(); it!=mNodeListSources.end(); it++)
+ {
+ result = sourceNodeWithID(sourceID, it->first);
+ if(result)
+ return result;
+ }
+ return result;
+}
+
+CAmRoutingNode* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID)
+{
+ CAmRoutingNode* result = NULL;
+ std::vector<CAmRoutingNode*> & value = mNodeListSources[domainID];
+ auto iter = std::find_if(value.begin(), value.end(), [sourceID](CAmRoutingNode* node){
+ return node->getData().data.source->sourceID==sourceID;
+ });
+ if(iter!=value.end())
+ result = *iter;
+ return result;
+}
+
+CAmRoutingNode* CAmRouter::converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID)
+{
+ CAmRoutingNode* result = NULL;
+ std::vector<CAmRoutingNode*> & value = mNodeListConverters[domainID];
+ auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){
+ return node->getData().data.converter->sinkID==sinkID;
+ });
+ if(iter!=value.end())
+ result = *iter;
+ return result;
+}
+
+CAmRoutingNode* CAmRouter::gatewayNodeWithSinkID(const am_sinkID_t sinkID)
+{
+ for(auto it = mNodeListGateways.begin(); it!=mNodeListGateways.end(); it++)
+ {
+ std::vector<CAmRoutingNode*> & value = it->second;
+ auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){
+ return node->getData().data.gateway->sinkID==sinkID;
+ });
+ if(iter!=value.end())
+ return *iter;
+ }
+ return NULL;
+}
+
+#ifdef ROUTING_BUILD_CONNECTIONS
+
+void CAmRouter::constructSourceSinkConnections()
+{
+ std::vector<am_CustomConnectionFormat_t> intersection;
+ for(auto itSrc = mNodeListSources.begin(); itSrc!=mNodeListSources.end(); itSrc++)
+ {
+ for(auto it = itSrc->second.begin(); it!=itSrc->second.end(); it++)
+ {
+ CAmRoutingNode* srcNode = *it;
+ am_RoutingNodeData_s & srcNodeData = srcNode->getData();
+ am_Source_s * source = srcNodeData.data.source;
+ for(auto itSink = mNodeListSinks[itSrc->first].begin(); itSink!=mNodeListSinks[itSrc->first].end(); itSink++)
+ {
+ CAmRoutingNode* sinkNode = *itSink;
+ am_RoutingNodeData_s & sinkNodeData = sinkNode->getData();
+ am_Sink_s * sink = sinkNodeData.data.sink;
+
+ intersection.clear();
+ //Check whether the hidden sink formats match the source formats...
+ listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, intersection);
+ if(intersection.size()>0)//OK match source -> sink
+ {
+ mRoutingGraph.connectNodes(*srcNode, *sinkNode, CF_UNKNOWN, 1);
+ }
+ }
+ }
+ }
+}
+
+void CAmRouter::constructGatewayConnections()
+{
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ for(auto iter = mNodeListGateways.begin(); iter!=mNodeListGateways.end(); iter++)
+ {
+ for(auto it = iter->second.begin(); it!=iter->second.end(); it++)
+ {
+ CAmRoutingNode* gatewayNode = *it;
+ am_RoutingNodeData_s & gatewayNodeData = gatewayNode->getData();
+ am_Gateway_s * gateway = gatewayNodeData.data.gateway;
+ //Get only gateways with end point in current source domain
+ if(!mOnlyFreeConversionNodes || !isComponentConnected(*gateway))
+ {
+ //Get the sink connected to the gateway...
+ CAmRoutingNode *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID, gateway->domainSinkID);
+ if(gatewaySinkNode)
+ {
+ am_RoutingNodeData_s & gatewaySinkData = gatewaySinkNode->getData();
+ //Check whether the hidden sink formats match the source formats...
+ sourceFormats.clear();
+ sinkFormats.clear();
+ if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmRoutingNode *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gateway->domainSourceID);
+ if(gatewaySourceNode)
+ {
+ //Connections hidden_sink->gateway->hidden_source
+ mRoutingGraph.connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1);
+ mRoutingGraph.connectNodes(*gatewayNode, *gatewaySourceNode, CF_UNKNOWN, 1);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void CAmRouter::constructConverterConnections()
+{
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+
+ for(auto iter = mNodeListConverters.begin(); iter!=mNodeListConverters.end(); iter++)
+ {
+ for(auto it = iter->second.begin(); it!=iter->second.end(); it++)
+ {
+ CAmRoutingNode* converterNode = *it;
+ am_RoutingNodeData_s & converterNodeData = converterNode->getData();
+ am_Converter_s * converter = converterNodeData.data.converter;
+ //Get only converters with end point in current source domain
+ if(!mOnlyFreeConversionNodes || !isComponentConnected(*converter))
+ {
+ //Get the sink connected to the converter...
+ CAmRoutingNode *converterSinkNode = this->sinkNodeWithID(converter->sinkID, converter->domainID);
+ if(converterSinkNode)
+ {
+ am_RoutingNodeData_s & converterSinkData = converterSinkNode->getData();
+ //Check whether the hidden sink formats match the source formats...
+ sourceFormats.clear();
+ sinkFormats.clear();
+ if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmRoutingNode *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converter->domainID);
+ if(converterSourceNode)
+ {
+ //Connections hidden_sink->converter->hidden_source
+ mRoutingGraph.connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1);
+ mRoutingGraph.connectNodes(*converterNode, *converterSourceNode, CF_UNKNOWN, 1);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#else
+
+void CAmRouter::getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list)
+{
+ am_RoutingNodeData_s & srcNodeData = ((CAmRoutingNode*)&node)->getData();
+ std::vector<am_CustomConnectionFormat_t> intersection;
+ am_Source_s * source = srcNodeData.data.source;
+ std::vector<CAmRoutingNode*> & sinks = mNodeListSinks[source->domainID];
+ for(auto itSink = sinks.begin(); itSink!=sinks.end(); itSink++)
+ {
+ CAmRoutingNode* sinkNode = *itSink;
+ am_RoutingNodeData_s & sinkNodeData = sinkNode->getData();
+ am_Sink_s * sink = sinkNodeData.data.sink;
+
+ intersection.clear();
+ //Check whether the hidden sink formats match the source formats...
+ listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, intersection);
+ if(intersection.size()>0)//OK match source -> sink
+ {
+ list.emplace_back(sinkNode, CF_UNKNOWN, 1);
+ }
+ }
+}
+
+void CAmRouter::getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list)
+{
+ am_RoutingNodeData_s & sinkNodeData = ((CAmRoutingNode*)&node)->getData();
+ std::vector<am_CustomConnectionFormat_t> intersection;
+ am_Sink_s * sink = sinkNodeData.data.sink;
+
+ CAmRoutingNode *converterNode = converterNodeWithSinkID(sink->sinkID, sink->domainID);
+ if(converterNode)
+ {
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ am_RoutingNodeData_s & converterData = converterNode->getData();
+ am_Converter_s * converter = converterData.data.converter;
+ if(!mOnlyFreeConversionNodes || !isComponentConnected(*converter))
+ {
+ if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats))
+ list.emplace_back(converterNode, CF_UNKNOWN, 1);
+ }
+ }
+ else
+ {
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ CAmRoutingNode *gatewayNode = gatewayNodeWithSinkID(sink->sinkID);
+ if(gatewayNode)
+ {
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ am_RoutingNodeData_s & gatewayData = gatewayNode->getData();
+ am_Gateway_s * gateway = gatewayData.data.gateway;
+ if(!mOnlyFreeConversionNodes || !isComponentConnected(*gateway))
+ {
+ if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats))
+ list.emplace_back(gatewayNode, CF_UNKNOWN, 1);
+ }
+ }
+ }
+
+}
+
+void CAmRouter::getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list)
+{
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ am_RoutingNodeData_s & converterNodeData = ((CAmRoutingNode*)&node)->getData();
+ am_Converter_s * converter = converterNodeData.data.converter;
+ //Get only converters with end point in current source domain
+ if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmRoutingNode *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converter->domainID);
+ if(converterSourceNode)
+ {
+ list.emplace_back(converterSourceNode, CF_UNKNOWN, 1);
+ }
+ }
+}
+
+void CAmRouter::getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list)
+{
+ am_RoutingNodeData_s & gatewayNodeData = ((CAmRoutingNode*)&node)->getData();
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ am_Gateway_s * gateway = gatewayNodeData.data.gateway;
+ if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmRoutingNode *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gateway->domainSourceID);
+ if(gatewaySourceNode)
+ {
+ //Connections hidden_sink->gateway->hidden_source
+ list.emplace_back(gatewaySourceNode, CF_UNKNOWN, 1);
+ }
+ }
+}
+
+void CAmRouter::getVerticesForNode(
+ const CAmRoutingNode & node,
+ CAmRoutingListVertices & list
+ )
+{
+ am_RoutingNodeData_s & nodeData = ((CAmRoutingNode*)&node)->getData();
+ if(nodeData.type==CAmNodeDataType::SOURCE)
+ {
+ getVerticesForSource(node, list);
+ }
+ else if(nodeData.type==CAmNodeDataType::SINK)
+ {
+ getVerticesForSink(node, list);
+ }
+ else if(nodeData.type==CAmNodeDataType::CONVERTER)
+ {
+ getVerticesForConverter(node, list);
+ }
+ else if(nodeData.type==CAmNodeDataType::GATEWAY)
+ {
+ getVerticesForGateway(node, list);
+ }
+}
+
+#endif
+
+am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes)
+{
+ std::vector<am_RoutingElement_s>::iterator routingElementIterator = routeObjects.route.begin();
+ std::vector<CAmRoutingNode*>::iterator nodeIterator = nodes.begin();
+ if( routingElementIterator!= routeObjects.route.end() && nodeIterator!=nodes.end() )
+ return doConnectionFormatsForPath(routeObjects, nodes, routingElementIterator, nodeIterator);
+ return E_OK;
+}
+
+am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects,
+ std::vector<CAmRoutingNode*> & nodes,
+ std::vector<am_RoutingElement_s>::iterator routingElementIterator,
+ std::vector<CAmRoutingNode*>::iterator nodeIterator)
+{
+ am_Error_e returnError = E_NOT_POSSIBLE;
+ std::vector<am_CustomConnectionFormat_t> listConnectionFormats;
+ std::vector<am_CustomConnectionFormat_t> listMergeConnectionFormats;
+
+ std::vector<CAmRoutingNode*>::iterator currentNodeIterator = nodeIterator;
+ std::vector<am_RoutingElement_s>::iterator currentRoutingElementIterator = routingElementIterator;
+
+ if (currentRoutingElementIterator!=routeObjects.route.begin())
+ {
+ std::vector<am_CustomConnectionFormat_t> listConnectionFormats;
+ std::vector<am_RoutingElement_s>::iterator tempIterator = (currentRoutingElementIterator-1);
+ CAmRoutingNode * currentNode = *currentNodeIterator;
+ getSourceSinkPossibleConnectionFormats(currentNodeIterator+1, currentNodeIterator+2, listConnectionFormats);
+
+ if(currentNode->getData().type==CAmNodeDataType::GATEWAY)
+ {
+ am_Gateway_s *gateway = currentNode->getData().data.gateway;
+ getMergeConnectionFormats(gateway, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats);
+ }
+ else if(currentNode->getData().type==CAmNodeDataType::CONVERTER)
+ {
+ am_Converter_s *converter = currentNode->getData().data.converter;
+ getMergeConnectionFormats(converter, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats);
+ }
+ currentNodeIterator+=3;
+ }
+ else
+ {
+ CAmRoutingNode * currentNode = *currentNodeIterator;
+ assert(currentNode->getData().type==CAmNodeDataType::SOURCE);
+
+ currentNodeIterator++;
+ assert(currentNodeIterator!=nodes.end());
+
+ CAmRoutingNode * nodeSink = *currentNodeIterator;
+ assert(nodeSink->getData().type==CAmNodeDataType::SINK);
+
+ am_Source_s *source = currentNode->getData().data.source;
+ am_Sink_s *sink = nodeSink->getData().data.sink;
+ listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listMergeConnectionFormats);
+ currentNodeIterator+=1; //now we are on the next converter/gateway
+ }
+
+ //let the controller decide:
+ std::vector<am_CustomConnectionFormat_t> listPriorityConnectionFormats;
+ mpControlSender->getConnectionFormatChoice(currentRoutingElementIterator->sourceID, currentRoutingElementIterator->sinkID, routeObjects,
+ listMergeConnectionFormats, listPriorityConnectionFormats);
+
+ //we have the list sorted after priors - now we try one after the other with the next part of the route
+ std::vector<am_CustomConnectionFormat_t>::iterator connectionFormatIterator = listPriorityConnectionFormats.begin();
+ //here we need to check if we are at the end and stop
+ std::vector<am_RoutingElement_s>::iterator nextIterator = currentRoutingElementIterator + 1;//next pair source and sink
+ if (nextIterator == routeObjects.route.end())
+ {
+ if (!listPriorityConnectionFormats.empty())
+ {
+ currentRoutingElementIterator->connectionFormat = listPriorityConnectionFormats.front();
+ return (E_OK);
+ }
+ else
+ return (E_NOT_POSSIBLE);
+ }
+
+ for (; connectionFormatIterator != listPriorityConnectionFormats.end(); ++connectionFormatIterator)
+ {
+ currentRoutingElementIterator->connectionFormat = *connectionFormatIterator;
+ if ((returnError = doConnectionFormatsForPath(routeObjects, nodes, nextIterator, currentNodeIterator)) == E_OK)
+ {
+ break;
+ }
+ }
+ return (returnError);
+}
+
+#ifdef ROUTING_BUILD_CONNECTIONS
+
+void CAmRouter::getShortestPath(const CAmRoutingNode & source,
+ const CAmRoutingNode & destination,
+ std::vector<CAmRoutingNode*> & resultPath)
+{
+ mRoutingGraph.getShortestPath(source, destination, resultPath);
+}
+
+void CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink,
+ am_Route_s & resultPath, std::vector<CAmRoutingNode*> & resultNodesPath)
+{
+ am_RoutingElement_s * element;
+ am_RoutingNodeData_s & sinkNodeData = aSink.getData();
+ am_RoutingNodeData_s & sourceNodeData = aSource.getData();
+ resultPath.sinkID = sinkNodeData.data.sink->sinkID;
+ resultPath.sourceID = sourceNodeData.data.source->sourceID;
+
+ std::function<void(const am_GraphPathPosition_e, CAmRoutingNode &)> cb = [&](const am_GraphPathPosition_e, CAmRoutingNode & object)
+ {
+ resultNodesPath.insert(resultNodesPath.begin(), (CAmRoutingNode*)&object);
+ am_RoutingNodeData_s & routingData = object.getData();
+ if(routingData.type==CAmNodeDataType::SINK)
+ {
+ auto iter = resultPath.route.emplace(resultPath.route.begin());
+ element = &(*iter);
+ element->domainID = routingData.data.sink->domainID;
+ element->sinkID = routingData.data.sink->sinkID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ else if(routingData.type==CAmNodeDataType::SOURCE)
+ {
+ element->domainID = routingData.data.source->domainID;
+ element->sourceID = routingData.data.source->sourceID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ };
+ mRoutingGraph.getShortestPath(aSource, aSink, cb);
+}
+
+#endif
+
+am_Error_e CAmRouter::getAllPaths(CAmRoutingNode & aSource,
+ CAmRoutingNode & aSink,
+ std::vector<am_Route_s> & resultPath,
+ std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath,
+ const bool includeCycles)
+{
+#ifndef ROUTING_BUILD_CONNECTIONS
+ bool cycles = false;
+#else
+ bool cycles = includeCycles;
+#endif
+ if(((CAmRoutingNode*)&aSource)->getData().type!=CAmNodeDataType::SOURCE ||
+ ((CAmRoutingNode*)&aSink)->getData().type!=CAmNodeDataType::SINK)
+ return E_NOT_POSSIBLE;
+
+ uint8_t errorsCount = 0, successCount = 0;
+ generateAllPaths(aSource, aSink, cycles, [&](const std::vector<CAmRoutingNode*> & path) {
+ resultNodesPath.push_back(path);
+ resultPath.emplace_back();
+ am_Route_s & nextRoute = resultPath.back();
+ nextRoute.sinkID = aSink.getData().data.sink->sinkID;
+ nextRoute.sourceID = aSource.getData().data.source->sourceID;
+ am_RoutingElement_s * element;
+ for(auto it = path.begin(); it!=path.end(); it++)
+ {
+ am_RoutingNodeData_s & routingData = (*it)->getData();
+ if(routingData.type==CAmNodeDataType::SOURCE)
+ {
+ auto iter = nextRoute.route.emplace(nextRoute.route.end());
+ element = &(*iter);
+ element->domainID = routingData.data.source->domainID;
+ element->sourceID = routingData.data.source->sourceID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ else if(routingData.type==CAmNodeDataType::SINK)
+ {
+ element->domainID = routingData.data.sink->domainID;
+ element->sinkID = routingData.data.sink->sinkID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ }
+
+ am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector<CAmRoutingNode*> &)path);
+ if(err!=E_OK)
+ {
+ errorsCount++;
+ auto last = resultPath.end()-1;
+ resultPath.erase(last);
+#ifdef TRACE_GRAPH
+ std::cout<<"Error by determining connection formats for path from source:"<<nextRoute.sourceID<<" to sink:"<<nextRoute.sinkID<<"\n";
+#endif
+ }
+ else
+ {
+#ifdef TRACE_GRAPH
+ std::cout<<"\nSuccessfully determined connection formats for path from source:"<<nextRoute.sourceID<<" to sink:"<<nextRoute.sinkID<<"\n";
+ for(auto it = nextRoute.route.begin(); it!=nextRoute.route.end(); it++)
+ {
+ am_RoutingElement_s & routingElement = *it;
+ std::cout<<"["
+ <<routingElement.sourceID
+ <<"->"
+ <<routingElement.sinkID
+ <<" cf:"
+ <<routingElement.connectionFormat
+ <<" d:"
+ <<routingElement.domainID
+ <<"]";
+ }
+ std::cout<<"\n";
+#endif
+ successCount++;
+ }
+ });
+ if(successCount)
+ return E_OK;
+ if(errorsCount)
+ return E_NOT_POSSIBLE;
+ return E_OK;
+}
+
+bool CAmRouter::shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID)
+{
+ if(visitedDomains.size())
+ {
+ if(visitedDomains.back()==nodeDomainID)
+ return true;
+
+ for(auto it=visitedDomains.begin();it!=visitedDomains.end()-1; it++)
+ {
+ if(nodeDomainID==*it)
+ return false;
+ }
+ }
+ return true;
+}
+
+void CAmRouter::generateAllPaths(const CAmRoutingNode & src,
+ const CAmRoutingNode & dst,
+ const bool includeCycles,
+ std::function<void(const std::vector<CAmRoutingNode*> & path)> cb)
+{
+ if(!includeCycles)
+ {
+ std::vector<CAmRoutingNode*> visited;
+ std::vector<am_domainID_t> visitedDomains;
+ visited.push_back((CAmRoutingNode*)&src);
+ visitedDomains.push_back(((CAmRoutingNode*)&src)->getData().domainID());
+ ((CAmRoutingNode*)&src)->setStatus(GES_VISITED);
+ goThroughAllPaths(dst, visited, visitedDomains, cb);
+ }
+ else
+ mRoutingGraph.getAllPaths(src, dst, cb);
+}
+
+void CAmRouter::goThroughAllPaths(const CAmRoutingNode & dst,
+ std::vector<CAmRoutingNode*> & visited,
+ std::vector<am_domainID_t> & visitedDomains,
+ std::function<void(const std::vector<CAmRoutingNode*> & path)> cb)
+{
+#ifndef ROUTING_BUILD_CONNECTIONS
+ CAmRoutingListVertices vertices;
+ getVerticesForNode(*visited.back(), vertices);
+ const CAmRoutingListVertices * nodes = &vertices;
+#else
+ const CAmRoutingListVertices * nodes = mRoutingGraph.getVertexList()[visited.back()->getIndex()];
+#endif
+ CAmRoutingListVertices::const_iterator vItr(nodes->begin());
+ for (; vItr != nodes->end(); ++vItr)
+ {
+ const CAmRoutingVertex & vertex = (*vItr);
+ if(vertex.getNode()->getStatus()!=GES_NOT_VISITED || !shouldGoInDomain(visitedDomains, vertex.getNode()->getData().domainID()))
+ continue;
+ if (vertex.getNode()==&dst)
+ {
+ vertex.getNode()->setStatus(GES_IN_PROGRESS);
+ visited.push_back(vertex.getNode());
+ visitedDomains.push_back(vertex.getNode()->getData().domainID());
+ //notify observer
+ cb(visited);
+ //remove last node from the list
+ auto last = visited.end()-1;
+ visited.erase(last);
+ visitedDomains.erase(visitedDomains.end()-1);
+ vertex.getNode()->setStatus(GES_NOT_VISITED);
+ break;
+ }
+ }
+ vItr = nodes->begin();
+ //bfs like loop
+ for (; vItr != nodes->end(); ++vItr)
+ {
+ const CAmRoutingVertex & vertex = (*vItr);
+ if(vertex.getNode()->getStatus()!=GES_NOT_VISITED
+ ||vertex.getNode()==&dst ||
+ !shouldGoInDomain(visitedDomains, vertex.getNode()->getData().domainID()))
+ continue;
+ vertex.getNode()->setStatus(GES_IN_PROGRESS);
+ visited.push_back(vertex.getNode());
+ visitedDomains.push_back(vertex.getNode()->getData().domainID());
+ goThroughAllPaths(dst, visited, visitedDomains, cb);
+ //remove last node from the list
+ auto last = visited.end()-1;
+ visited.erase(last);
+ visitedDomains.erase(visitedDomains.end()-1);
+ vertex.getNode()->setStatus(GES_NOT_VISITED);
+ }
+}
+
+bool CAmRouter::getAllowedFormatsFromConvMatrix( const std::vector<bool> & convertionMatrix,
+ const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
+ const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
+ std::vector<am_CustomConnectionFormat_t> & sourceFormats,
+ std::vector<am_CustomConnectionFormat_t> & sinkFormats)
+{
+ const size_t sizeSourceFormats = listSourceFormats.size();
+ const size_t sizeSinkFormats = listSinkFormats.size();
+ const size_t sizeConvertionMatrix = convertionMatrix.size();
+
+ if(sizeSourceFormats==0||sizeSinkFormats==0||sizeConvertionMatrix==0||sizeConvertionMatrix!=sizeSinkFormats*sizeSourceFormats)
+ {
+ return false;
+ }
+
+ std::vector<bool>::const_iterator iterator = convertionMatrix.begin();
+ for (; iterator != convertionMatrix.end(); ++iterator)
+ {
+ if( true == *iterator )
+ {
+ const size_t index = iterator-convertionMatrix.begin();
+ size_t idx = index%sizeSourceFormats;
+ sourceFormats.push_back(listSourceFormats.at(idx));
+ idx = index/sizeSourceFormats;
+ sinkFormats.push_back(listSinkFormats.at(idx));
+ }
+ }
+ return sourceFormats.size()>0;
+}
+
+void CAmRouter::listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats,
+ std::vector<am_CustomConnectionFormat_t> & inListSinkFormats,
+ std::vector<am_CustomConnectionFormat_t> & outListFormats)
+{
+ std::sort(inListSourceFormats.begin(), inListSourceFormats.end());
+ std::sort(inListSinkFormats.begin(), inListSinkFormats.end());
+ std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(outListFormats, outListFormats.begin());
+ set_intersection(inListSourceFormats.begin(), inListSourceFormats.end(), inListSinkFormats.begin(), inListSinkFormats.end(), inserter);
+}
+
+
+bool CAmRouter::getRestrictedOutputFormats(const std::vector<bool> & convertionMatrix,
+ const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
+ const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
+ const am_CustomConnectionFormat_t connectionFormat,
+ std::vector<am_CustomConnectionFormat_t> & listFormats)
+{
+ listFormats.clear();
+ std::vector<am_CustomConnectionFormat_t>::const_iterator rowSinkIterator = listSinkFormats.begin();
+ std::vector<bool>::const_iterator matrixIterator = convertionMatrix.begin();
+
+ //find the row number of the sink
+ rowSinkIterator = find(listSinkFormats.begin(), listSinkFormats.end(), connectionFormat);
+ int rowNumberSink = rowSinkIterator - listSinkFormats.begin();
+
+ //go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ...
+ std::advance(matrixIterator, rowNumberSink);
+
+ //iterate line-wise through the matrix and add more formats
+ do
+ {
+ if (*matrixIterator)
+ {
+ listFormats.push_back(listSourceFormats.at((matrixIterator - convertionMatrix.begin()) / listSinkFormats.size()));
+ }
+ std::advance(matrixIterator, listSinkFormats.size());
+ } while (convertionMatrix.end() - matrixIterator > 0);
+
+ return listFormats.size();
+}
+
+
+void CAmRouter::getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource,
+ std::vector<CAmRoutingNode*>::iterator iteratorSink,
+ std::vector<am_CustomConnectionFormat_t> & outConnectionFormats)
+{
+ CAmRoutingNode * nodeSink = *iteratorSink;
+ assert(nodeSink->getData().type==CAmNodeDataType::SINK);
+
+ CAmRoutingNode * nodeSource = *iteratorSource;
+ assert(nodeSource->getData().type==CAmNodeDataType::SOURCE);
+
+ am_Source_s *source = nodeSource->getData().data.source;
+ am_Sink_s *sink = nodeSink->getData().data.sink;
+ listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, outConnectionFormats);
+}
+
+
+}
diff --git a/AudioManagerCore/src/CAmRoutingReceiver.cpp b/AudioManagerCore/src/CAmRoutingReceiver.cpp
new file mode 100644
index 0000000..4189936
--- /dev/null
+++ b/AudioManagerCore/src/CAmRoutingReceiver.cpp
@@ -0,0 +1,620 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmRoutingReceiver.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmRoutingReceiver.h"
+#include <cassert>
+#include <algorithm>
+#include "IAmDatabaseHandler.h"
+#include "CAmRoutingSender.h"
+#include "CAmControlSender.h"
+#include "CAmDltWrapper.h"
+#include "CAmSocketHandler.h"
+
+namespace am
+{
+
+CAmRoutingReceiver::CAmRoutingReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmControlSender *iControlSender, CAmSocketHandler *iSocketHandler) :
+ mpDatabaseHandler(iDatabaseHandler), //
+ mpRoutingSender(iRoutingSender), //
+ mpControlSender(iControlSender), //
+ mpSocketHandler(iSocketHandler), //
+ mpDBusWrapper(NULL), //
+ mListStartupHandles(), //
+ mListRundownHandles(), //
+ handleCount(0), //
+ mWaitStartup(false), //
+ mWaitRundown(false), //
+ mLastStartupError(E_OK), //
+ mLastRundownError(E_OK) //
+{
+ assert(mpDatabaseHandler!=NULL);
+ assert(mpRoutingSender!=NULL);
+ assert(mpControlSender!=NULL);
+ assert(mpSocketHandler!=NULL);
+}
+
+CAmRoutingReceiver::CAmRoutingReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmControlSender *iControlSender, CAmSocketHandler *iSocketHandler, CAmDbusWrapper *iDBusWrapper) :
+ mpDatabaseHandler(iDatabaseHandler), //
+ mpRoutingSender(iRoutingSender), //
+ mpControlSender(iControlSender), //
+ mpSocketHandler(iSocketHandler), //
+ mpDBusWrapper(iDBusWrapper), //
+ mListStartupHandles(), //
+ mListRundownHandles(), //
+ handleCount(0), //
+ mWaitStartup(false), //
+ mWaitRundown(false),
+ mLastStartupError(E_OK), //
+ mLastRundownError(E_OK) //
+{
+ assert(mpDatabaseHandler!=NULL);
+ assert(mpRoutingSender!=NULL);
+ assert(mpControlSender!=NULL);
+ assert(mpSocketHandler!=NULL);
+ assert(mpDBusWrapper!=NULL);
+}
+
+CAmRoutingReceiver::~CAmRoutingReceiver()
+{
+}
+
+void CAmRoutingReceiver::ackConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
+{
+ mpRoutingSender->removeHandle(handle);
+ if (error == am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeConnectionFinal(connectionID);
+ }
+ else
+ {
+ mpDatabaseHandler->removeConnection(connectionID);
+ mpRoutingSender->removeConnectionLookup(connectionID);
+ }
+ mpControlSender->cbAckConnect(handle, error);
+}
+
+void CAmRoutingReceiver::ackDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
+{
+
+ //so we will remove the connection anyway no matter what is answered
+ mpRoutingSender->removeHandle(handle);
+ mpDatabaseHandler->removeConnection(connectionID);
+ mpRoutingSender->removeConnectionLookup(connectionID);
+ mpControlSender->cbAckDisconnect(handle, error);
+}
+
+void CAmRoutingReceiver::ackSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error== am_Error_e::E_OK || error== am_Error_e::E_ABORTED)
+ {
+ mpDatabaseHandler->changeSinkVolume(handleData.sinkID, volume);
+ }
+
+ if(error == am_Error_e::E_OK || handleData.volume!=volume)
+ {
+ logError("ackSetSinkVolumeChange volumes do not match, requested volume",handleData.volume,"returned volume",volume);
+ }
+ mpControlSender->cbAckSetSinkVolumeChange(handle, volume, error);
+}
+
+void CAmRoutingReceiver::ackSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error== am_Error_e::E_OK || error== am_Error_e::E_ABORTED)
+ {
+ mpDatabaseHandler->changeSourceVolume(handleData.sourceID, volume);
+ }
+
+ if(error == E_OK || handleData.volume!=volume)
+ {
+ logError("ackSetSourceVolumeChange volumes do not match, requested volume",handleData.volume,"returned volume",volume);
+ }
+ mpControlSender->cbAckSetSourceVolumeChange(handle, volume, error);
+}
+
+void CAmRoutingReceiver::ackSetSourceState(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ //no error, so we can write the change into the database;
+ if (error == am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeSourceState(handleData.sourceID, handleData.sourceState);
+ }
+
+ mpControlSender->cbAckSetSourceState(handle, error);
+}
+
+void CAmRoutingReceiver::ackSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error==am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeSinkSoundPropertyDB(handleData.soundPropery, handleData.sinkID);
+ }
+
+ mpControlSender->cbAckSetSinkSoundProperty(handle, error);
+
+}
+
+void am::CAmRoutingReceiver::ackSetSinkSoundProperties(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if (error==am_Error_e::E_OK)
+ {
+ std::vector<am_SoundProperty_s>::const_iterator it = handleData.soundProperties->begin();
+ for (; it != handleData.soundProperties->end(); ++it)
+ {
+ mpDatabaseHandler->changeSinkSoundPropertyDB(*it, handleData.sinkID);
+ }
+ }
+
+ try
+ {
+ delete handleData.soundProperties;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSetSinkSoundProperties");
+ }
+ mpControlSender->cbAckSetSinkSoundProperties(handle, error);
+}
+
+void CAmRoutingReceiver::ackSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeSourceSoundPropertyDB(handleData.soundPropery, handleData.sourceID);
+ }
+ mpControlSender->cbAckSetSourceSoundProperty(handle, error);
+}
+
+void am::CAmRoutingReceiver::ackSetSourceSoundProperties(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
+ {
+ std::vector<am_SoundProperty_s>::const_iterator it = handleData.soundProperties->begin();
+ for (; it != handleData.soundProperties->end(); ++it)
+ {
+ mpDatabaseHandler->changeSourceSoundPropertyDB(*it, handleData.sourceID);
+ }
+ }
+
+ try
+ {
+ delete handleData.soundProperties;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSetSourceSoundProperties");
+ }
+ mpControlSender->cbAckSetSourceSoundProperties(handle, error);
+}
+
+void CAmRoutingReceiver::ackCrossFading(const am_Handle_s handle, const am_HotSink_e hotSink, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeCrossFaderHotSink(handleData.crossfaderID, hotSink);
+ }
+ mpControlSender->cbAckCrossFade(handle, hotSink, error);
+}
+
+void CAmRoutingReceiver::ackSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume)
+{
+ mpControlSender->hookSystemSourceVolumeTick(handle, sourceID, volume);
+}
+
+void CAmRoutingReceiver::ackSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume)
+{
+ mpControlSender->hookSystemSinkVolumeTick(handle, sinkID, volume);
+}
+
+am_Error_e CAmRoutingReceiver::peekDomain(const std::string & name, am_domainID_t & domainID)
+{
+ return (mpDatabaseHandler->peekDomain(name, domainID));
+
+}
+
+am_Error_e CAmRoutingReceiver::registerDomain(const am_Domain_s & domainData, am_domainID_t & domainID)
+{
+ return (mpControlSender->hookSystemRegisterDomain(domainData, domainID));
+}
+
+am_Error_e CAmRoutingReceiver::deregisterDomain(const am_domainID_t domainID)
+{
+ return (mpControlSender->hookSystemDeregisterDomain(domainID));
+}
+
+am_Error_e CAmRoutingReceiver::registerGateway(const am_Gateway_s & gatewayData, am_gatewayID_t & gatewayID)
+{
+ return (mpControlSender->hookSystemRegisterGateway(gatewayData, gatewayID));
+}
+
+am_Error_e CAmRoutingReceiver::registerConverter(const am_Converter_s& converterData, am_converterID_t& converterID)
+{
+ return (mpControlSender->hookSystemRegisterConverter(converterData, converterID));
+}
+
+am_Error_e CAmRoutingReceiver::deregisterGateway(const am_gatewayID_t gatewayID)
+{
+ return (mpControlSender->hookSystemDeregisterGateway(gatewayID));
+}
+
+am_Error_e CAmRoutingReceiver::deregisterConverter(const am_converterID_t converterID)
+{
+ return (mpControlSender->hookSystemDeregisterConverter(converterID));
+}
+
+am_Error_e CAmRoutingReceiver::peekSink(const std::string& name, am_sinkID_t & sinkID)
+{
+ return (mpDatabaseHandler->peekSink(name, sinkID));
+}
+
+am_Error_e CAmRoutingReceiver::registerSink(const am_Sink_s & sinkData, am_sinkID_t & sinkID)
+{
+ return (mpControlSender->hookSystemRegisterSink(sinkData, sinkID));
+}
+
+am_Error_e CAmRoutingReceiver::deregisterSink(const am_sinkID_t sinkID)
+{
+ return (mpControlSender->hookSystemDeregisterSink(sinkID));
+}
+
+am_Error_e CAmRoutingReceiver::peekSource(const std::string & name, am_sourceID_t & sourceID)
+{
+ return (mpDatabaseHandler->peekSource(name, sourceID));
+}
+
+am_Error_e CAmRoutingReceiver::registerSource(const am_Source_s & sourceData, am_sourceID_t & sourceID)
+{
+ return (mpControlSender->hookSystemRegisterSource(sourceData, sourceID));
+}
+
+am_Error_e CAmRoutingReceiver::deregisterSource(const am_sourceID_t sourceID)
+{
+ return (mpControlSender->hookSystemDeregisterSource(sourceID));
+}
+
+am_Error_e CAmRoutingReceiver::registerCrossfader(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID)
+{
+ return (mpControlSender->hookSystemRegisterCrossfader(crossfaderData, crossfaderID));
+}
+
+am_Error_e CAmRoutingReceiver::deregisterCrossfader(const am_crossfaderID_t crossfaderID)
+{
+ return (mpControlSender->hookSystemDeregisterCrossfader(crossfaderID));
+}
+
+void CAmRoutingReceiver::hookInterruptStatusChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState)
+{
+ return (mpControlSender->hookSystemInterruptStateChange(sourceID, interruptState));
+}
+
+void CAmRoutingReceiver::hookDomainRegistrationComplete(const am_domainID_t domainID)
+{
+ mpControlSender->hookSystemDomainRegistrationComplete(domainID);
+}
+
+void CAmRoutingReceiver::hookSinkAvailablityStatusChange(const am_sinkID_t sinkID, const am_Availability_s & availability)
+{
+ mpControlSender->hookSystemSinkAvailablityStateChange(sinkID, availability);
+}
+
+void CAmRoutingReceiver::hookSourceAvailablityStatusChange(const am_sourceID_t sourceID, const am_Availability_s & availability)
+{
+ mpControlSender->hookSystemSourceAvailablityStateChange(sourceID, availability);
+}
+
+void CAmRoutingReceiver::hookDomainStateChange(const am_domainID_t domainID, const am_DomainState_e domainState)
+{
+ mpControlSender->hookSystemDomainStateChange(domainID, domainState);
+}
+
+void CAmRoutingReceiver::hookTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t delay)
+{
+ mpDatabaseHandler->changeConnectionTimingInformation(connectionID, delay);
+ mpControlSender->hookSystemSingleTimingInformationChanged(connectionID,delay);
+}
+
+void CAmRoutingReceiver::sendChangedData(const std::vector<am_EarlyData_s> & earlyData)
+{
+ mpControlSender->hookSystemReceiveEarlyData(earlyData);
+}
+
+am_Error_e CAmRoutingReceiver::peekSinkClassID(const std::string& name, am_sinkClass_t& sinkClassID)
+{
+ return (mpDatabaseHandler->peekSinkClassID(name, sinkClassID));
+}
+
+am_Error_e CAmRoutingReceiver::peekSourceClassID(const std::string& name, am_sourceClass_t& sourceClassID)
+{
+ return (mpDatabaseHandler->peekSourceClassID(name, sourceClassID));
+}
+
+#ifdef WITH_DBUS_WRAPPER
+am_Error_e CAmRoutingReceiver::getDBusConnectionWrapper(CAmDbusWrapper *& dbusConnectionWrapper) const
+{
+ dbusConnectionWrapper = mpDBusWrapper;
+ return (E_OK);
+#else
+am_Error_e CAmRoutingReceiver::getDBusConnectionWrapper(CAmDbusWrapper *& ) const
+{
+ return (E_UNKNOWN);
+#endif
+}
+
+am_Error_e CAmRoutingReceiver::getSocketHandler(CAmSocketHandler *& socketHandler) const
+{
+ socketHandler = mpSocketHandler;
+ return (E_OK);
+}
+
+void CAmRoutingReceiver::getInterfaceVersion(std::string & version) const
+{
+ version = RoutingVersion;
+}
+
+void CAmRoutingReceiver::confirmRoutingReady(const uint16_t handle, const am_Error_e error)
+{
+ if (error!=E_OK)
+ mLastStartupError=error;
+ mListStartupHandles.erase(std::remove(mListStartupHandles.begin(), mListStartupHandles.end(), handle), mListStartupHandles.end());
+ if (mWaitStartup && mListStartupHandles.empty())
+ mpControlSender->confirmRoutingReady(mLastStartupError);
+}
+
+void CAmRoutingReceiver::confirmRoutingRundown(const uint16_t handle, const am_Error_e error)
+{
+ if (error!=E_OK)
+ mLastRundownError=error;
+ mListRundownHandles.erase(std::remove(mListRundownHandles.begin(), mListRundownHandles.end(), handle), mListRundownHandles.end());
+ if (mWaitRundown && mListRundownHandles.empty())
+ mpControlSender->confirmRoutingRundown(mLastRundownError);
+}
+
+uint16_t am::CAmRoutingReceiver::getStartupHandle()
+{
+ uint16_t handle = ++handleCount; //todo: handle overflow
+ mListStartupHandles.push_back(handle);
+ return (handle);
+}
+
+uint16_t am::CAmRoutingReceiver::getRundownHandle()
+{
+ uint16_t handle = ++handleCount; //todo: handle overflow
+ mListRundownHandles.push_back(handle);
+ return (handle);
+}
+
+void am::CAmRoutingReceiver::waitOnStartup(bool startup)
+{
+ mWaitStartup = startup;
+ mLastStartupError=E_OK;
+}
+
+void CAmRoutingReceiver::ackSinkNotificationConfiguration(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeSinkNotificationConfigurationDB(handleData.sinkID,*handleData.notificationConfiguration);
+ }
+
+ try
+ {
+ delete handleData.notificationConfiguration;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSinkNotificationConfiguration");
+ }
+ mpControlSender->cbAckSetSinkNotificationConfiguration(handle,error);
+}
+
+void CAmRoutingReceiver::ackSourceNotificationConfiguration(const am_Handle_s handle, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
+ {
+ mpDatabaseHandler->changeSourceNotificationConfigurationDB(handleData.sourceID,*handleData.notificationConfiguration);
+ }
+ try
+ {
+ delete handleData.notificationConfiguration;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSourceNotificationConfiguration");
+ }
+ mpControlSender->cbAckSetSourceNotificationConfiguration(handle,error);
+}
+
+am_Error_e CAmRoutingReceiver::updateGateway(const am_gatewayID_t gatewayID, const std::vector<am_CustomConnectionFormat_t>& listSourceFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkFormats, const std::vector<bool>& convertionMatrix)
+{
+ return (mpControlSender->hookSystemUpdateGateway(gatewayID,listSourceFormats,listSinkFormats,convertionMatrix));
+}
+
+am_Error_e CAmRoutingReceiver::updateConverter(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkFormats, const std::vector<bool>& convertionMatrix)
+{
+ return (mpControlSender->hookSystemUpdateConverter(converterID,listSourceFormats,listSinkFormats,convertionMatrix));
+}
+
+am_Error_e CAmRoutingReceiver::updateSink(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ return (mpControlSender->hookSystemUpdateSink(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
+}
+
+am_Error_e CAmRoutingReceiver::updateSource(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
+{
+ return (mpControlSender->hookSystemUpdateSource(sourceID,sourceClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
+}
+
+void CAmRoutingReceiver::ackSetVolumes(const am_Handle_s handle, const std::vector<am_Volumes_s>& listvolumes, const am_Error_e error)
+{
+ CAmRoutingSender::am_handleData_c handleData;
+ if (mpRoutingSender->returnHandleDataAndRemove(handle,handleData))
+ {
+ logError(__PRETTY_FUNCTION__,"Could not find handleData, handle: ",handle.handle);
+ return;
+ }
+
+ if(error==am_Error_e::E_OK)
+ {
+ std::vector<am_Volumes_s>::const_iterator iterator (listvolumes.begin());
+
+ for (;iterator!=listvolumes.end();++iterator)
+ {
+ if (iterator->volumeType==VT_SINK)
+ {
+ mpDatabaseHandler->changeSinkVolume(iterator->volumeID.sink,iterator->volume);
+ }
+ else if (iterator->volumeType==VT_SOURCE)
+ {
+ mpDatabaseHandler->changeSourceVolume(iterator->volumeID.source,iterator->volume);
+ }
+ }
+
+ }
+
+ try
+ {
+ delete handleData.listVolumes;
+ }
+ catch(...)
+ {
+ logError("exception while deleting handleData while ackSetVolumes");
+ }
+
+ mpControlSender->cbAckSetVolume(handle,listvolumes,error);
+}
+
+void CAmRoutingReceiver::hookSinkNotificationDataChange(const am_sinkID_t sinkID, const am_NotificationPayload_s& payload)
+{
+ logInfo("CAmRoutingReceiver::hookSinkNotificationDataChange received, sinkID=",sinkID,"type=",payload.type,"notificationValue=",payload.value);
+ mpControlSender->hookSinkNotificationDataChanged(sinkID,payload);
+}
+
+void CAmRoutingReceiver::hookSourceNotificationDataChange(const am_sourceID_t sourceID, const am_NotificationPayload_s& payload)
+{
+ logInfo("CAmRoutingReceiver::hookSourceNotificationDataChange received, sinkID=",sourceID,"type=",payload.type,"notificationValue=",payload.value);
+ mpControlSender->hookSourceNotificationDataChanged(sourceID,payload);
+}
+
+am_Error_e CAmRoutingReceiver::getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t& domainID) const
+{
+ return (mpDatabaseHandler->getDomainOfSink(sinkID,domainID));
+}
+
+am_Error_e CAmRoutingReceiver::getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t& domainID) const
+{
+ return (mpDatabaseHandler->getDomainOfSource(sourceID,domainID));
+}
+
+am_Error_e CAmRoutingReceiver::getDomainOfCrossfader(const am_crossfaderID_t crossfader, am_domainID_t& domainID) const
+{
+ return (mpDatabaseHandler->getDomainOfCrossfader(crossfader,domainID));
+}
+
+void CAmRoutingReceiver::waitOnRundown(bool rundown)
+{
+ mWaitRundown = rundown;
+ mLastRundownError=E_OK;
+}
+
+am_Error_e CAmRoutingSender::removeConnectionLookup(const am_connectionID_t connectionID)
+{
+ ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
+ iter = mMapConnectionInterface.find(connectionID);
+ if (iter != mMapConnectionInterface.end())
+ {
+ mMapConnectionInterface.erase(iter);
+ return (E_OK);
+ }
+ return (E_UNKNOWN);
+}
+
+}
diff --git a/AudioManagerCore/src/CAmRoutingSender.cpp b/AudioManagerCore/src/CAmRoutingSender.cpp
new file mode 100644
index 0000000..35e35b8
--- /dev/null
+++ b/AudioManagerCore/src/CAmRoutingSender.cpp
@@ -0,0 +1,838 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * \file CAmRoutingSender.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmRoutingSender.h"
+#include <utility>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include "CAmRoutingReceiver.h"
+#include "TAmPluginTemplate.h"
+#include "CAmDltWrapper.h"
+
+namespace am
+{
+
+#define REQUIRED_INTERFACE_VERSION_MAJOR 1 //!< major interface version. All versions smaller than this will be rejected
+#define REQUIRED_INTERFACE_VERSION_MINOR 0 //!< minor interface version. All versions smaller than this will be rejected
+
+CAmRoutingSender::CAmRoutingSender(const std::vector<std::string>& listOfPluginDirectories) :
+ mHandleCount(0), //
+ mlistActiveHandles(), //
+ mListInterfaces(), //
+ mMapConnectionInterface(), //
+ mMapCrossfaderInterface(), //
+ mMapDomainInterface(), //
+ mMapSinkInterface(), //
+ mMapSourceInterface(), //
+ mMapHandleInterface(), //
+ mpRoutingReceiver()
+{
+
+ if (listOfPluginDirectories.empty())
+ {
+ logError("CAmRoutingSender::CAmRoutingSender: List of routingplugins is empty");
+ }
+
+ std::vector<std::string> sharedLibraryNameList;
+ std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
+ std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
+
+ // search communicator plugins in configured directories
+ for (; dirIter < dirIterEnd; ++dirIter)
+ {
+ const char* directoryName = dirIter->c_str();
+ logInfo("Searching for HookPlugins in", directoryName);
+ DIR *directory = opendir(directoryName);
+
+ if (!directory)
+ {
+ logError("RoutingSender::RoutingSender Error opening directory: ", directoryName);
+ continue;
+ }
+
+ // iterate content of directory
+ struct dirent *itemInDirectory = 0;
+ while ((itemInDirectory = readdir(directory)))
+ {
+ unsigned char entryType = itemInDirectory->d_type;
+ std::string entryName = itemInDirectory->d_name;
+ std::string fullName = *dirIter + "/" + entryName;
+
+ bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
+ bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
+
+ // Handle cases where readdir() could not determine the file type
+ if (entryType == DT_UNKNOWN) {
+ struct stat buf;
+
+ if (stat(fullName.c_str(), &buf)) {
+ logInfo(__PRETTY_FUNCTION__,"Failed to stat file: ", entryName, errno);
+ continue;
+ }
+
+ regularFile = S_ISREG(buf.st_mode);
+ }
+
+ if (regularFile && sharedLibExtension)
+ {
+ logInfo("RoutingSender::RoutingSender adding file: ", entryName);
+ std::string name(directoryName);
+ sharedLibraryNameList.push_back(name + "/" + entryName);
+ }
+ else
+ {
+ logInfo("RoutingSender::RoutingSender PluginSearch ignoring file :", entryName);
+ }
+ }
+
+ closedir(directory);
+ }
+
+ // iterate all communicator plugins and start them
+ std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
+ std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
+
+ for (; iter != iterEnd; ++iter)
+ {
+ logInfo("RoutingSender::RoutingSender try loading: ", *iter);
+
+ IAmRoutingSend* (*createFunc)();
+ void* tempLibHandle = NULL;
+ createFunc = getCreateFunction<IAmRoutingSend*()>(*iter, tempLibHandle);
+
+ if (!createFunc)
+ {
+ logError("RoutingSender::RoutingSender Entry point of RoutingPlugin not found");
+ continue;
+ }
+
+ IAmRoutingSend* router = createFunc();
+
+ if (!router)
+ {
+ logError("RoutingSender::RoutingSender RoutingPlugin initialization failed. Entry Function not callable");
+ dlclose(tempLibHandle);
+ continue;
+ }
+
+ InterfaceNamePairs routerInterface;
+ routerInterface.routingInterface = router;
+
+ //check libversion
+ std::string version, cVersion(RoutingVersion);
+ router->getInterfaceVersion(version);
+ uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion;
+ std::istringstream(version.substr(0, 1)) >> majorVersion;
+ std::istringstream(version.substr(2, 1)) >> minorVersion;
+ std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion;
+ std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion;
+
+
+
+ if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion)))
+ {
+ logError("Routing initialization failed. Version of Interface to old");
+ dlclose(tempLibHandle);
+ continue;
+ }
+
+ //here, the busname is saved together with the interface. Later The domains will register with the name and sinks, sources etc with the domain....
+ router->returnBusName(routerInterface.busName);
+ assert(!routerInterface.busName.empty());
+ mListInterfaces.push_back(routerInterface);
+ mListLibraryHandles.push_back(tempLibHandle);
+ }
+}
+
+CAmRoutingSender::~CAmRoutingSender()
+{
+ //unloadLibraries();
+ HandlesMap::iterator it = mlistActiveHandles.begin();
+
+ //clean up heap if existent
+ for (; it != mlistActiveHandles.end(); ++it)
+ {
+ if (it->first.handleType == H_SETSINKSOUNDPROPERTIES || it->first.handleType == H_SETSOURCESOUNDPROPERTIES)
+ {
+ delete it->second.soundProperties;
+ }
+ }
+}
+
+am_Error_e CAmRoutingSender::startupInterfaces(CAmRoutingReceiver *iRoutingReceiver)
+{
+ mpRoutingReceiver = iRoutingReceiver;
+ am_Error_e returnError = E_OK;
+
+ std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
+ std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
+ for (; iter < iterEnd; ++iter)
+ {
+ am_Error_e error = (*iter).routingInterface->startupInterface(iRoutingReceiver);
+ if (error != E_OK)
+ {
+ returnError = error;
+ }
+ }
+ return (returnError);
+}
+
+am_Error_e CAmRoutingSender::asyncAbort(const am_Handle_s& handle)
+{
+ HandleInterfaceMap::iterator iter = mMapHandleInterface.begin();
+ iter = mMapHandleInterface.find(handle.handle);
+ if (iter != mMapHandleInterface.end())
+ {
+ removeHandle(handle);
+ return (iter->second->asyncAbort(handle));
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncConnect(am_Handle_s& handle, const am_connectionID_t connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat)
+{
+ am_handleData_c handleData;
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if (iter != mMapSinkInterface.end())
+ {
+ handleData.connectionID = connectionID;
+ handle = createHandle(handleData, H_CONNECT);
+ mMapConnectionInterface.insert(std::make_pair(connectionID, iter->second));
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncConnect(handle, connectionID, sourceID, sinkID, connectionFormat));
+
+ if (syncError)
+ {
+ removeHandle(handle);
+ removeConnectionLookup(connectionID);
+ }
+ return(syncError);
+
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncDisconnect(am_Handle_s& handle, const am_connectionID_t connectionID)
+{
+ am_handleData_c handleData;
+ ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin();
+ iter = mMapConnectionInterface.find(connectionID);
+ if (iter != mMapConnectionInterface.end())
+ {
+ handleData.connectionID = connectionID;
+ handle = createHandle(handleData, H_DISCONNECT);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncDisconnect(handle, connectionID));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::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_handleData_c handleData;
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if (iter != mMapSinkInterface.end())
+ {
+ handleData.sinkID = sinkID;
+ handleData.volume = volume;
+ handle = createHandle(handleData, H_SETSINKVOLUME);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSinkVolume(handle, sinkID, volume, ramp, time));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::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_handleData_c handleData;
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ handleData.sourceID = sourceID;
+ handleData.volume = volume;
+ handle = createHandle(handleData, H_SETSOURCEVOLUME);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSourceVolume(handle, sourceID, volume, ramp, time));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncSetSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state)
+{
+ am_handleData_c handleData;
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ handleData.sourceID = sourceID;
+ handleData.sourceState = state;
+ handle = createHandle(handleData, H_SETSOURCESTATE);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSourceState(handle, sourceID, state));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncSetSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s & soundProperty)
+{
+ am_handleData_c handleData;
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if (iter != mMapSinkInterface.end())
+ {
+ handleData.sinkID = sinkID;
+ handleData.soundPropery = soundProperty;
+ handle = createHandle(handleData, H_SETSINKSOUNDPROPERTY);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSinkSoundProperty(handle, sinkID, soundProperty));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncSetSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s & soundProperty)
+{
+ am_handleData_c handleData;
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ handleData.sourceID = sourceID;
+ handleData.soundPropery = soundProperty;
+ handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTY);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSourceSoundProperty(handle, sourceID, soundProperty));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sourceID_t sourceID)
+{
+ am_handleData_c handleData;
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ handleData.sourceID = sourceID;
+ handleData.soundProperties = new std::vector<am_SoundProperty_s>(listSoundProperties);
+ handle = createHandle(handleData, H_SETSOURCESOUNDPROPERTIES);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSourceSoundProperties(handle, sourceID, listSoundProperties));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s> & listSoundProperties, const am_sinkID_t sinkID)
+{
+ am_handleData_c handleData;
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if (iter != mMapSinkInterface.end())
+ {
+ handleData.sinkID = sinkID;
+ handleData.soundProperties = new std::vector<am_SoundProperty_s>(listSoundProperties);
+ handle = createHandle(handleData, H_SETSINKSOUNDPROPERTIES);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSinkSoundProperties(handle, sinkID, listSoundProperties));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.soundProperties;
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+
+}
+
+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)
+{
+ am_handleData_c handleData;
+ CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
+ iter = mMapCrossfaderInterface.find(crossfaderID);
+ if (iter != mMapCrossfaderInterface.end())
+ {
+ handleData.crossfaderID = crossfaderID;
+ handleData.hotSink = hotSink;
+ handle = createHandle(handleData, H_CROSSFADE);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncCrossFade(handle, crossfaderID, hotSink, rampType, time));
+ if (syncError)
+ {
+ removeHandle(handle);
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
+{
+ DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
+ iter = mMapDomainInterface.find(domainID);
+ if (iter != mMapDomainInterface.end())
+ return (iter->second->setDomainState(domainID, domainState));
+ return (E_NON_EXISTENT);
+}
+
+/**
+ * @author Christian
+ * this adds the domain to the lookup table of the Router. The data is used to have a quick lookup of the correct pluginInterface.
+ * This must be done whenever a domain is registered.
+ */
+am_Error_e CAmRoutingSender::addDomainLookup(const am_Domain_s& domainData)
+{
+ std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
+ std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
+ for (; iter < iterEnd; ++iter)
+ {
+ if ((*iter).busName.compare(domainData.busname) == 0)
+ {
+ mMapDomainInterface.insert(std::make_pair(domainData.domainID, (*iter).routingInterface));
+ return (E_OK);
+ }
+ }
+ logError(__PRETTY_FUNCTION__," Could not find busname for bus",domainData.busname);
+ return (E_UNKNOWN);
+}
+
+/**
+ * @author Christian
+ * this adds the Source to the lookup table of the Router. The data is used to have a quick lookup of the correct pluginInterface.
+ * This must be done whenever a Source is registered.
+ */
+am_Error_e CAmRoutingSender::addSourceLookup(const am_Source_s& sourceData)
+{
+ DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
+ iter = mMapDomainInterface.find(sourceData.domainID);
+ if (iter != mMapDomainInterface.end())
+ {
+ mMapSourceInterface.insert(std::make_pair(sourceData.sourceID, iter->second));
+ return (E_OK);
+ }
+ logError(__PRETTY_FUNCTION__," Could not find domainInterface for domainID",sourceData.domainID);
+ return (E_UNKNOWN);
+}
+
+/**
+ * @author Christian
+ * this adds the Sink to the lookup table of the Router. The data is used to have a quick lookup of the correct pluginInterface.
+ * This must be done whenever a Sink is registered.
+ */
+am_Error_e CAmRoutingSender::addSinkLookup(const am_Sink_s& sinkData)
+{
+ DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
+ iter = mMapDomainInterface.find(sinkData.domainID);
+ if (iter != mMapDomainInterface.end())
+ {
+ mMapSinkInterface.insert(std::make_pair(sinkData.sinkID, iter->second));
+ return (E_OK);
+ }
+ logError(__PRETTY_FUNCTION__,"Could not find domainInterface for domainID",sinkData.domainID);
+ return (E_UNKNOWN);
+}
+
+/**
+ * @author Christian
+ * this adds the Crossfader to the lookup table of the Router. The data is used to have a quick lookup of the correct pluginInterface.
+ * This must be done whenever a Crossfader is registered.
+ */
+am_Error_e CAmRoutingSender::addCrossfaderLookup(const am_Crossfader_s& crossfaderData)
+{
+ DomainInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(crossfaderData.sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ mMapSourceInterface.insert(std::make_pair(crossfaderData.crossfaderID, iter->second));
+ return (E_OK);
+ }
+ logError(__PRETTY_FUNCTION__," Could not find sourceInterface for source",crossfaderData.sourceID);
+ return (E_UNKNOWN);
+}
+
+/**
+ * @author Christian
+ * this removes the Domain to the lookup table of the Router. This must be done everytime a domain is deregistered.
+ */
+am_Error_e CAmRoutingSender::removeDomainLookup(const am_domainID_t domainID)
+{
+ DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
+ iter = mMapDomainInterface.find(domainID);
+ if (iter != mMapDomainInterface.end())
+ {
+ mMapDomainInterface.erase(iter);
+ return (E_OK);
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+/**
+ * @author Christian
+ * this removes the Source to the lookup table of the Router. This must be done everytime a source is deregistered.
+ */
+am_Error_e CAmRoutingSender::removeSourceLookup(const am_sourceID_t sourceID)
+{
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ mMapSourceInterface.erase(iter);
+ return (E_OK);
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+/**
+ * @author Christian
+ * this removes the Sink to the lookup table of the Router. This must be done everytime a sink is deregistered.
+ */
+am_Error_e CAmRoutingSender::removeSinkLookup(const am_sinkID_t sinkID)
+{
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if (iter != mMapSinkInterface.end())
+ {
+ mMapSinkInterface.erase(iter);
+ return (E_OK);
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+/**
+ * @author Christian
+ * this removes the Crossfader to the lookup table of the Router. This must be done everytime a crossfader is deregistered.
+ */
+am_Error_e CAmRoutingSender::removeCrossfaderLookup(const am_crossfaderID_t crossfaderID)
+{
+ CrossfaderInterfaceMap::iterator iter = mMapCrossfaderInterface.begin();
+ iter = mMapCrossfaderInterface.find(crossfaderID);
+ if (iter != mMapCrossfaderInterface.end())
+ {
+ mMapCrossfaderInterface.erase(iter);
+ return (E_OK);
+ }
+
+ return (E_NON_EXISTENT);
+}
+
+/**
+ * removes a handle from the list
+ * @param handle to be removed
+ * @return E_OK in case of success
+ */
+am_Error_e CAmRoutingSender::removeHandle(const am_Handle_s& handle)
+{
+ if (mlistActiveHandles.erase(handle))
+ {
+ return (E_OK);
+ }
+ logError(__PRETTY_FUNCTION__,"Could not remove handle",handle.handle);
+ return (E_UNKNOWN);
+}
+
+am_Error_e CAmRoutingSender::getListHandles(std::vector<am_Handle_s> & listHandles) const
+{
+ listHandles.clear();
+ HandlesMap::const_iterator it = mlistActiveHandles.begin();
+ for (; it != mlistActiveHandles.end(); ++it)
+ {
+ listHandles.push_back(it->first);
+ }
+ return (E_OK);
+}
+
+/**
+ * creates a handle and adds it to the list of handles
+ * @param handleData the data that should be saves together with the handle
+ * @param type the type of handle to be created
+ * @return the handle
+ */
+am_Handle_s CAmRoutingSender::createHandle(const am_handleData_c& handleData, const am_Handle_e type)
+{
+ am_Handle_s handle;
+ if (++mHandleCount>=1024) //defined by 10 bit (out if structure!)
+ mHandleCount=1;
+ handle.handle = mHandleCount;
+ handle.handleType = type;
+ mlistActiveHandles.insert(std::make_pair(handle, handleData));
+ if ((mlistActiveHandles.size()%100) == 0)
+ logInfo("CAmRoutingSender::createHandle warning: too many open handles, number of handles: ", mlistActiveHandles.size());
+ logInfo(__PRETTY_FUNCTION__,handle.handle, handle.handleType);
+ return (handle);
+}
+
+/**
+ * returns the data that belong to handles
+ * @param handle the handle
+ * @return a class holding the handle data
+ */
+am_Error_e CAmRoutingSender::returnHandleData(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData) const
+{
+ HandlesMap::const_iterator it = mlistActiveHandles.begin();
+ it = mlistActiveHandles.find(handle);
+ if (it!=mlistActiveHandles.end())
+ {
+ handleData = it->second;
+ return (am_Error_e::E_OK);
+ }
+ handleData.sinkID=0;
+ logError(__PRETTY_FUNCTION__,"could not find handle data for handle",handle.handle,handle.handleType);
+ return (am_Error_e::E_NON_EXISTENT);
+}
+
+void CAmRoutingSender::setRoutingReady()
+{
+ mpRoutingReceiver->waitOnStartup(false);
+
+ //create a list of handles
+ std::vector<uint16_t> listStartupHandles;
+ for (size_t i = 0; i < mListInterfaces.size(); i++)
+ {
+ listStartupHandles.push_back(mpRoutingReceiver->getStartupHandle());
+ }
+
+ //set the receiver ready to wait for replies
+ mpRoutingReceiver->waitOnStartup(true);
+
+ std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
+ std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
+ std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
+ for (; iter < iterEnd; ++iter)
+ {
+ (*iter).routingInterface->setRoutingReady(*(handleIter++));
+ }
+}
+
+void CAmRoutingSender::setRoutingRundown()
+{
+ mpRoutingReceiver->waitOnRundown(false);
+ //create a list of handles
+ std::vector<uint16_t> listStartupHandles;
+ for (size_t i = 0; i < mListInterfaces.size(); i++)
+ {
+ listStartupHandles.push_back(mpRoutingReceiver->getRundownHandle());
+ }
+
+ //set the receiver ready to wait for replies
+ mpRoutingReceiver->waitOnRundown(true);
+
+ std::vector<InterfaceNamePairs>::iterator iter = mListInterfaces.begin();
+ std::vector<InterfaceNamePairs>::iterator iterEnd = mListInterfaces.end();
+ std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
+ for (; iter < iterEnd; ++iter)
+ {
+ (*iter).routingInterface->setRoutingRundown(*(handleIter++));
+ }
+}
+
+am_Error_e CAmRoutingSender::asyncSetVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes)
+{
+ am_handleData_c handleData;
+ IAmRoutingSend* pRoutingInterface(NULL);
+ if (listVolumes.empty())
+ return (E_NOT_POSSIBLE);
+
+ //we need an interface so lets get either the sink or source ID from the first entry in the listVolumes
+ if (listVolumes[0].volumeType==VT_SINK)
+ {
+ am_sinkID_t sinkID=listVolumes[0].volumeID.sink;
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if(iter!=mMapSinkInterface.end())
+ pRoutingInterface=iter->second;
+ else
+ return(E_NON_EXISTENT);
+ }
+
+ else if (listVolumes[0].volumeType==VT_SOURCE)
+ {
+ am_sourceID_t sourceID=listVolumes[0].volumeID.source;
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter!=mMapSourceInterface.end())
+ pRoutingInterface=iter->second;
+ else
+ return(E_NON_EXISTENT);
+ }
+ else
+ return (E_NON_EXISTENT);
+
+ handleData.volumeID=listVolumes[0].volumeID;
+ handleData.listVolumes= new std::vector<am_Volumes_s>(listVolumes);
+ handle = createHandle(handleData, H_SETVOLUMES);
+
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, pRoutingInterface));
+ am_Error_e syncError(pRoutingInterface->asyncSetVolumes(handle, listVolumes));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.listVolumes;
+ }
+ return(syncError);
+
+}
+
+am_Error_e CAmRoutingSender::asyncSetSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration)
+{
+ am_handleData_c handleData;
+ SinkInterfaceMap::iterator iter = mMapSinkInterface.begin();
+ iter = mMapSinkInterface.find(sinkID);
+ if (iter != mMapSinkInterface.end())
+ {
+ handleData.sinkID = sinkID;
+ handleData.notificationConfiguration = new am_NotificationConfiguration_s(notificationConfiguration);
+ handle = createHandle(handleData, H_SETSINKNOTIFICATION);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSinkNotificationConfiguration(handle, sinkID,notificationConfiguration));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.notificationConfiguration;
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::asyncSetSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration)
+{
+ am_handleData_c handleData;
+ SourceInterfaceMap::iterator iter = mMapSourceInterface.begin();
+ iter = mMapSourceInterface.find(sourceID);
+ if (iter != mMapSourceInterface.end())
+ {
+ handleData.sourceID = sourceID;
+ handleData.notificationConfiguration = new am_NotificationConfiguration_s(notificationConfiguration);
+ handle = createHandle(handleData, H_SETSOURCENOTIFICATION);
+ mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second));
+ am_Error_e syncError(iter->second->asyncSetSourceNotificationConfiguration(handle, sourceID,notificationConfiguration));
+ if (syncError)
+ {
+ removeHandle(handle);
+ delete handleData.notificationConfiguration;
+ }
+ return(syncError);
+ }
+ return (E_NON_EXISTENT);
+}
+
+void CAmRoutingSender::unloadLibraries(void)
+{
+ std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
+ for (; iterator < mListLibraryHandles.end(); ++iterator)
+ {
+ dlclose(*iterator);
+ }
+ mListLibraryHandles.clear();
+}
+
+am_Error_e CAmRoutingSender::getListPlugins(std::vector<std::string>& interfaces) const
+{
+ std::vector<InterfaceNamePairs>::const_iterator it = mListInterfaces.begin();
+ for (; it != mListInterfaces.end(); ++it)
+ {
+ interfaces.push_back(it->busName);
+ }
+ return (E_OK);
+}
+
+void CAmRoutingSender::getInterfaceVersion(std::string & version) const
+{
+ version = RoutingVersion;
+}
+am_Error_e CAmRoutingSender::resyncConnectionState(const am_domainID_t domainID,std::vector<am_Connection_s>& listOfExistingConnections)
+{
+ DomainInterfaceMap::iterator iter = mMapDomainInterface.begin();
+ iter = mMapDomainInterface.find(domainID);
+ if (iter != mMapDomainInterface.end())
+ return (iter->second->resyncConnectionState(domainID, listOfExistingConnections));
+ return (E_NON_EXISTENT);
+}
+
+am_Error_e CAmRoutingSender::returnHandleDataAndRemove(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData)
+{
+ HandlesMap::const_iterator it = mlistActiveHandles.begin();
+ it = mlistActiveHandles.find(handle);
+ if (it!=mlistActiveHandles.end())
+ {
+ handleData = it->second;
+ mlistActiveHandles.erase(handle);
+ return (am_Error_e::E_OK);
+ }
+ handleData.sinkID=0;
+ logError(__PRETTY_FUNCTION__,"could not find handle data for handle",handle.handle,handle.handleType);
+ return (am_Error_e::E_NON_EXISTENT);
+
+}
+
+}
diff --git a/AudioManagerCore/src/CAmTelnetMenuHelper.cpp b/AudioManagerCore/src/CAmTelnetMenuHelper.cpp
new file mode 100644
index 0000000..2aae4f5
--- /dev/null
+++ b/AudioManagerCore/src/CAmTelnetMenuHelper.cpp
@@ -0,0 +1,1438 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ * \author Frank Herchet, frank.fh.herchet@bmw.de BMW 2012
+ *
+ * \file CAmTelnetMenuHelper.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmTelnetMenuHelper.h"
+#include <cassert>
+#include "audiomanagerconfig.h"
+#include "CAmRouter.h"
+#include "CAmTelnetServer.h"
+#include "IAmDatabaseHandler.h"
+#include "CAmControlSender.h"
+#include "CAmCommandSender.h"
+#include "CAmRoutingSender.h"
+#include "CAmRoutingReceiver.h"
+#include "CAmCommandReceiver.h"
+#include "CAmControlReceiver.h"
+#include "CAmDltWrapper.h"
+
+static const std::string COLOR_WELCOME("\033[1;33m\033[44m");
+static const std::string COLOR_HEAD("\033[1m\033[42m");
+static const std::string COLOR_DEFAULT("\033[0m");
+
+
+namespace am {
+
+CAmTelnetMenuHelper* CAmTelnetMenuHelper::instance = NULL;
+
+/****************************************************************************/
+CAmTelnetMenuHelper::CAmTelnetMenuHelper(CAmSocketHandler *iSocketHandler, CAmCommandSender *iCommandSender, CAmCommandReceiver *iCommandReceiver, CAmRoutingSender *iRoutingSender, CAmRoutingReceiver *iRoutingReceiver, CAmControlSender *iControlSender, CAmControlReceiver *iControlReceiver, IAmDatabaseHandler *iDatabasehandler, CAmRouter *iRouter, CAmTelnetServer *iTelnetServer)
+/****************************************************************************/
+:mpTelenetServer(iTelnetServer), mpSocketHandler(iSocketHandler), mpCommandSender(iCommandSender), mpCommandReceiver(iCommandReceiver), mpRoutingSender(iRoutingSender), mpRoutingReceiver(iRoutingReceiver), mpControlSender(iControlSender), mpControlReceiver(iControlReceiver), mpDatabasehandler(iDatabasehandler), mpRouter(iRouter)
+{
+ instance = this;
+ createCommandMaps();
+}
+
+/****************************************************************************/
+CAmTelnetMenuHelper::~CAmTelnetMenuHelper()
+/****************************************************************************/
+{
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::createCommandMaps()
+/****************************************************************************/
+{
+ // ROOT commands
+ mRootCommands.clear();
+ mRootCommands.insert(std::make_pair("help", sCommandPrototypeInfo("show all possible commands", &CAmTelnetMenuHelper::helpCommand)));
+ mRootCommands.insert(std::make_pair("list", sCommandPrototypeInfo("Go into 'list'-submenu", &CAmTelnetMenuHelper::rootListCommand)));
+ mRootCommands.insert(std::make_pair("info", sCommandPrototypeInfo("Go into 'info'-submenu", &CAmTelnetMenuHelper::rootInfoCommand)));
+ mRootCommands.insert(std::make_pair("set", sCommandPrototypeInfo("Go into 'set'-submenu", &CAmTelnetMenuHelper::rootSetCommand)));
+ mRootCommands.insert(std::make_pair("get", sCommandPrototypeInfo("Go into 'get'-submenu", &CAmTelnetMenuHelper::rootGetCommand)));
+ mRootCommands.insert(std::make_pair("exit", sCommandPrototypeInfo("quit telnet session", &CAmTelnetMenuHelper::exitCommand)));
+ // List commands
+ mListCommands.insert(std::make_pair("help", sCommandPrototypeInfo(std::string("show all possible commands"), &CAmTelnetMenuHelper::helpCommand)));
+ mListCommands.insert(std::make_pair("conn", sCommandPrototypeInfo("list all connections", &CAmTelnetMenuHelper::listConnectionsCommand)));
+ mListCommands.insert(std::make_pair("sources", sCommandPrototypeInfo("list all available sources", &CAmTelnetMenuHelper::listSourcesCommand)));
+ mListCommands.insert(std::make_pair("sinks", sCommandPrototypeInfo("list all available sinks", &CAmTelnetMenuHelper::listSinksCommands)));
+ mListCommands.insert(std::make_pair("crfader", sCommandPrototypeInfo("list all crossfaders", &CAmTelnetMenuHelper::listCrossfaders)));
+ mListCommands.insert(std::make_pair("domains", sCommandPrototypeInfo("list all domains", &CAmTelnetMenuHelper::listDomainsCommand)));
+ mListCommands.insert(std::make_pair("gws", sCommandPrototypeInfo("list all gateways", &CAmTelnetMenuHelper::listGatewaysCommand)));
+ mListCommands.insert(std::make_pair("mainconn", sCommandPrototypeInfo("list all main connections", &CAmTelnetMenuHelper::listMainConnectionsCommand)));
+ mListCommands.insert(std::make_pair("mainsinks", sCommandPrototypeInfo("list all main sinks", &CAmTelnetMenuHelper::listMainSinksCommand)));
+ mListCommands.insert(std::make_pair("mainsources", sCommandPrototypeInfo("list all main sources", &CAmTelnetMenuHelper::listMainSourcesCommand)));
+ mListCommands.insert(std::make_pair("..", sCommandPrototypeInfo("one step back in menu tree (back to root folder)", &CAmTelnetMenuHelper::oneStepBackCommand)));
+ mListCommands.insert(std::make_pair("exit", sCommandPrototypeInfo("close telnet session", &CAmTelnetMenuHelper::exitCommand)));
+ // Set commands
+ mSetCommands.insert(std::make_pair("help", sCommandPrototypeInfo(std::string("show all possible commands"), &CAmTelnetMenuHelper::helpCommand)));
+ mSetCommands.insert(std::make_pair("..", sCommandPrototypeInfo("one step back in menu tree (back to root folder)", &CAmTelnetMenuHelper::oneStepBackCommand)));
+ mSetCommands.insert(std::make_pair("exit", sCommandPrototypeInfo("close telnet session", &CAmTelnetMenuHelper::exitCommand)));
+ mSetCommands.insert(std::make_pair("conn", sCommandPrototypeInfo("use 'conn sourceId sinkId' to connect a source and a sink", &CAmTelnetMenuHelper::setConnection)));
+ mSetCommands.insert(std::make_pair("routing", sCommandPrototypeInfo("use 'routing sourceId sinkId' to get all\n\t possible routes between a sourceID and a sinkID", &CAmTelnetMenuHelper::setRoutingCommand)));
+ mSetCommands.insert(std::make_pair("disc", sCommandPrototypeInfo("use 'disc connectionID' to disconnect \n\t this connection", &CAmTelnetMenuHelper::setDisconnectConnId)));
+ mSetCommands.insert(std::make_pair("sinkvolume", sCommandPrototypeInfo("use 'sinkvolume sinkID volume' to set \n\t absorption in db of sink", &CAmTelnetMenuHelper::setSinkVolume)));
+ mSetCommands.insert(std::make_pair("sinkvolstep", sCommandPrototypeInfo("use 'sinkvolstep sinkID volumestep' to increment \n\t or decrement volume", &CAmTelnetMenuHelper::setVolumeStep)));
+ mSetCommands.insert(std::make_pair("sinkprop", sCommandPrototypeInfo("use 'sinkprop type value' to set \n\t a specific sinksoundproperty", &CAmTelnetMenuHelper::setSinkSoundProperty)));
+ mSetCommands.insert(std::make_pair("sinkmute", sCommandPrototypeInfo("use 'sinkmute sinkid mutestate' to mute \n\t or unmute", &CAmTelnetMenuHelper::setSinkMuteState)));
+ mSetCommands.insert(std::make_pair("sourceprop", sCommandPrototypeInfo("use 'sourceprop type value' to set \n\t a specific sinksoundproperty", &CAmTelnetMenuHelper::setSourceSoundProperty)));
+ // Get commands
+ mGetCommands.insert(std::make_pair("help", sCommandPrototypeInfo(std::string("show all possible commands"), &CAmTelnetMenuHelper::helpCommand)));
+ mGetCommands.insert(std::make_pair("routing", sCommandPrototypeInfo("show current routing", &CAmTelnetMenuHelper::getRoutingCommand)));
+ mGetCommands.insert(std::make_pair("sendv", sCommandPrototypeInfo("show senderversion", &CAmTelnetMenuHelper::getSenderversionCommand)));
+ mGetCommands.insert(std::make_pair("recv", sCommandPrototypeInfo("show receiverversion ", &CAmTelnetMenuHelper::getReceiverversionCommand)));
+ mGetCommands.insert(std::make_pair("..", sCommandPrototypeInfo("one step back in menu tree (back to root folder)", &CAmTelnetMenuHelper::oneStepBackCommand)));
+ mGetCommands.insert(std::make_pair("exit", sCommandPrototypeInfo("close telnet session", &CAmTelnetMenuHelper::exitCommand)));
+ // Info comands
+ mInfoCommands.insert(std::make_pair("help", sCommandPrototypeInfo(std::string("show all possible commands"), &CAmTelnetMenuHelper::helpCommand)));
+ mInfoCommands.insert(std::make_pair("sysprop", sCommandPrototypeInfo("show all systemproperties", &CAmTelnetMenuHelper::infoSystempropertiesCommand)));
+ mInfoCommands.insert(std::make_pair("dump", sCommandPrototypeInfo("create a database dump of currently used data", &CAmTelnetMenuHelper::infoDumpCommand)));
+ mInfoCommands.insert(std::make_pair("..", sCommandPrototypeInfo("one step back in menu tree (back to root folder)", &CAmTelnetMenuHelper::oneStepBackCommand)));
+ mInfoCommands.insert(std::make_pair("exit", sCommandPrototypeInfo("close telnet session", &CAmTelnetMenuHelper::exitCommand)));
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::newSocketConnection(int filedescriptor)
+/****************************************************************************/
+{
+ EMainState state = eRootState;
+ std::map<int, EMainState>::iterator it;
+ std::stringstream welcome;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ // socket connection already exists, delete entry and go back to root state
+ mCurrentMainStateMap.erase(it);
+ }
+ it = mCurrentMainStateMap.begin();
+ // insert new socket connection
+ mCurrentMainStateMap.insert(it, std::make_pair(filedescriptor, state));
+ // Send welcome message
+ welcome << COLOR_WELCOME << "Welcome to GENIVI AudioManager " << DAEMONVERSION << COLOR_DEFAULT << "\n>";
+ assert(send(filedescriptor, welcome.str().c_str(), welcome.str().size(), 0)>=0);
+ logInfo("[TN] New connection: ", filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::socketConnectionsClosed(int filedescriptor)
+/****************************************************************************/
+{
+ std::map<int, EMainState>::iterator it;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ mCurrentMainStateMap.erase(it);
+ }
+ else
+ {
+ logError("[TN] socketConnectionsClosed, fd not found, ", filedescriptor);
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::enterCmdQueue(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ std::map<int, EMainState>::iterator it;
+ std::string cmd;
+ tCommandMap::iterator cmditer;
+ // find current filedescriptor to get the current state of the telnet session
+ it = mCurrentMainStateMap.find(filedescriptor);
+ while (!CmdQueue.empty())
+ {
+ cmd = CmdQueue.front();
+ // Now remove the first command, it's stored in 'cmd'
+ CmdQueue.pop();
+ // telnet session found. depending on the current state, different commands are available
+ switch (it->second)
+ {
+ case eRootState:
+ cmditer = mRootCommands.find(cmd);
+ if (mRootCommands.end() != cmditer)
+ cmditer->second.CommandPrototype(CmdQueue, filedescriptor);
+ else
+ sendError(filedescriptor, "Command not found\n");
+
+ break;
+ case eListState:
+ cmditer = mListCommands.find(cmd);
+ if (mListCommands.end() != cmditer)
+ cmditer->second.CommandPrototype(CmdQueue, filedescriptor);
+ else
+ sendError(filedescriptor, "Command not found\n");
+
+ break;
+ case eInfoState:
+ cmditer = mInfoCommands.find(cmd);
+ if (mInfoCommands.end() != cmditer)
+ cmditer->second.CommandPrototype(CmdQueue, filedescriptor);
+ else
+ sendError(filedescriptor, "Command not found\n");
+
+ break;
+ case eGetState:
+ cmditer = mGetCommands.find(cmd);
+ if (mGetCommands.end() != cmditer)
+ cmditer->second.CommandPrototype(CmdQueue, filedescriptor);
+ else
+ sendError(filedescriptor, "Command not found\n");
+
+ break;
+ case eSetState:
+ cmditer = mSetCommands.find(cmd);
+ if (mSetCommands.end() != cmditer)
+ cmditer->second.CommandPrototype(CmdQueue, filedescriptor);
+ else
+ sendError(filedescriptor, "Command not found\n");
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ sendCurrentCmdPrompt(filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::sendError(int& filedescriptor, std::string error_string)
+/****************************************************************************/
+{
+ assert(send(filedescriptor, error_string.c_str(), error_string.size(), 0)>=0);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::sendTelnetLine(int& filedescriptor, std::stringstream& line)
+/****************************************************************************/
+{
+ assert(send(filedescriptor, line.str().c_str(), line.str().size(), 0)>=0);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::sendCurrentCmdPrompt(int& filedescriptor)
+/****************************************************************************/
+{
+ std::map<int, EMainState>::iterator it;
+ std::stringstream outputstream;
+ outputstream << std::endl;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ switch (it->second)
+ {
+ case eRootState:
+ outputstream << "\\>";
+ break;
+ case eListState:
+ outputstream << "\\List>";
+ break;
+ case eGetState:
+ outputstream << "\\Get>";
+ break;
+ case eSetState:
+ outputstream << "\\Set>";
+ break;
+ case eInfoState:
+ outputstream << "\\Info>";
+ break;
+ default:
+ break;
+ }
+ assert(send(filedescriptor, outputstream.str().c_str(), outputstream.str().size(), 0)>=0);
+ }
+ else
+ {
+ logInfo("[TN] sendCurrentCmdPrompt, fd not found: ", filedescriptor);
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::exitCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->exitCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::oneStepBackCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ switch (it->second)
+ {
+ case eRootState:
+ it->second = eRootState;
+ break;
+ case eListState:
+ it->second = eRootState;
+ ;
+ break;
+ case eGetState:
+ it->second = eRootState;
+ ;
+ break;
+ case eSetState:
+ it->second = eRootState;
+ ;
+ break;
+ case eInfoState:
+ it->second = eRootState;
+ ;
+ break;
+ default:
+ it->second = eRootState;
+ break;
+ }
+ logInfo("[TN] oneStepBackCommandExec, state: ", it->second);
+ }
+
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::oneStepBackCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->oneStepBackCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::exitCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ std::stringstream line;
+ std::stringstream output;
+ // Sending a last message to the client
+ output << "bye!" << COLOR_DEFAULT << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ tCommandMap::iterator iter;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ if (NULL != mpTelenetServer)
+ {
+ logInfo("[TN] exitCommandExec, removing fd ", filedescriptor);
+ mpTelenetServer->disconnectClient(filedescriptor);
+ mCurrentMainStateMap.erase(it);
+ }
+ else
+ {
+ logError("[TN] exitCommandExec, mpTelenetServer == NULL, fd ", filedescriptor);
+ }
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::helpCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->helpCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::helpCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ std::stringstream line;
+ tCommandMap::iterator cmdIter;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ line << COLOR_HEAD << "###################################################" << COLOR_DEFAULT << std::endl;
+ line << COLOR_HEAD << "###### The following commands are supported: ######" << COLOR_DEFAULT << std::endl;
+ line << COLOR_HEAD << "###################################################" << COLOR_DEFAULT << std::endl << std::endl;
+ switch (it->second)
+ {
+ case eRootState:
+ cmdIter = mRootCommands.begin();
+ while (cmdIter != mRootCommands.end())
+ {
+ line << cmdIter->first << "\t\t- " << cmdIter->second.info << std::endl;
+ cmdIter++;
+ }
+ break;
+ case eListState:
+ cmdIter = mListCommands.begin();
+ while (cmdIter != mListCommands.end())
+ {
+ line << cmdIter->first << "\t\t- " << cmdIter->second.info << std::endl;
+ cmdIter++;
+ }
+ break;
+ case eGetState:
+ cmdIter = mGetCommands.begin();
+ while (cmdIter != mGetCommands.end())
+ {
+ line << cmdIter->first << "\t\t- " << cmdIter->second.info << std::endl;
+ cmdIter++;
+ }
+ break;
+ case eSetState:
+ cmdIter = mSetCommands.begin();
+ while (cmdIter != mSetCommands.end())
+ {
+ line << cmdIter->first << "\t\t- " << cmdIter->second.info << std::endl;
+ cmdIter++;
+ }
+ break;
+ case eInfoState:
+ cmdIter = mInfoCommands.begin();
+ while (cmdIter != mInfoCommands.end())
+ {
+ line << cmdIter->first << "\t\t- " << cmdIter->second.info << std::endl;
+ cmdIter++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ sendTelnetLine(filedescriptor, line);
+ }
+
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootGetCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->rootGetCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootGetCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ it->second = eGetState;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootSetCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->rootSetCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootSetCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ it->second = eSetState;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootListCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->rootListCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootListCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ it->second = eListState;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootInfoCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->rootInfoCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::rootInfoCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::map<int, EMainState>::iterator it;
+ it = mCurrentMainStateMap.find(filedescriptor);
+ if (it != mCurrentMainStateMap.end())
+ {
+ it->second = eInfoState;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listConnectionsCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listConnectionsCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listConnectionsCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_Connection_s > listConnections;
+ if (E_OK == mpDatabasehandler->getListConnections(listConnections))
+ {
+ std::stringstream output;
+ output << "\tConnections: " << listConnections.size() << std::endl;
+ for (std::vector<am_Connection_s>::iterator iter(listConnections.begin()); iter < listConnections.end(); iter++)
+ {
+ output << "\tID: " << iter->connectionID << "\tSrcID: " << iter->sourceID << "\tSinkID: " << iter->sinkID << "\tFormat: " << iter->connectionFormat << "\tdelay: " << iter->delay << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListConnections");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listSourcesCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listSourcesCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listSourcesCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_Source_s > listSources;
+ if (E_OK == mpDatabasehandler->getListSources(listSources))
+ {
+ std::stringstream output;
+ output << "\tSources: " << listSources.size() << std::endl;
+ for (std::vector<am_Source_s>::iterator iter(listSources.begin()); iter < listSources.end(); iter++)
+ {
+ output << "\tID: " << iter->sourceID << "\tName: " << iter->name << "\tDomainID: " << iter->domainID << "\tState: " << iter->sourceState << "\tVolume: " << iter->volume << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListSources");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listSinksCommands(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listSinksCommandsExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listSinksCommandsExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_Sink_s > listSinks;
+ if (E_OK == mpDatabasehandler->getListSinks(listSinks))
+ {
+ std::stringstream output;
+ output << "\tSinks: " << listSinks.size() << std::endl;
+ for (std::vector<am_Sink_s>::iterator iter(listSinks.begin()); iter < listSinks.end(); iter++)
+ {
+ output << "\tID: " << iter->sinkID << "\tDomainID: " << iter->domainID << "\tName: " << iter->name << "\tAvailable: " << iter->available.availability << "\tVolume: " << iter->volume << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListSinks");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listCrossfaders(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listCrossfadersExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listCrossfadersExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_Crossfader_s > listCrossfaders;
+ if (E_OK == mpDatabasehandler->getListCrossfaders(listCrossfaders))
+ {
+ std::stringstream output;
+ output << "\tCrossfader: " << listCrossfaders.size() << std::endl;
+ for (std::vector<am_Crossfader_s>::iterator iter(listCrossfaders.begin()); iter < listCrossfaders.end(); iter++)
+ {
+ output << "\tID: " << iter->crossfaderID << "\tName: " << iter->name << "\tSinkA: " << iter->sinkID_A << "\tSinkB: " << iter->sinkID_B << "\tSourceID: " << iter->sourceID << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListCrossfaders");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listDomainsCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listDomainsCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listDomainsCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_Domain_s > listDomains;
+ if (E_OK == mpDatabasehandler->getListDomains(listDomains))
+ {
+ std::stringstream output;
+ output << "\tDomains: " << listDomains.size() << std::endl;
+ for (std::vector<am_Domain_s>::iterator iter(listDomains.begin()); iter < listDomains.end(); iter++)
+ {
+ output << "\tID: " << iter->domainID << "\tName: " << iter->name << "\tBusname: " << iter->busname << "\tNodename: " << iter->nodename << "\tState: " << static_cast<int>(iter->state) << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListDomains");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listGatewaysCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listGatewaysCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listGatewaysCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_Gateway_s > listGateways;
+ if (E_OK == mpDatabasehandler->getListGateways(listGateways))
+ {
+ std::stringstream output;
+ output << "\tGateways: " << listGateways.size();
+ for (std::vector<am_Gateway_s>::iterator iter(listGateways.begin()); iter < listGateways.end(); iter++)
+ {
+ output << "\tID: " << iter->gatewayID << "\tName: " << iter->name << "\tSourceID: " << iter->sourceID << "\tSinkID: " << iter->sinkID << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListGateways");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::getRoutingCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->getRoutingCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::getRoutingCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ (void) (filedescriptor);
+//TODO: fill with function
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::getSenderversionCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->getSenderversionCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::getSenderversionCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::stringstream output;
+ std::string versionCommand;
+ std::string versionRouting;
+ std::string versionControl;
+ mpControlSender->getInterfaceVersion(versionControl);
+ mpRoutingSender->getInterfaceVersion(versionRouting);
+ mpCommandSender->getInterfaceVersion(versionCommand);
+ output << "\tSender versions:" << std::endl << "\tCtrl: " << versionControl << " | " << "Cmd: " << versionCommand << " | " << "Routing: " << versionRouting << std::endl;
+ sendTelnetLine(filedescriptor, output);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::getReceiverversionCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->getReceiverversionCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::getReceiverversionCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::stringstream output;
+ std::string versionCommand;
+ std::string versionRouting;
+ std::string versionControl;
+ mpControlReceiver->getInterfaceVersion(versionControl);
+ mpRoutingReceiver->getInterfaceVersion(versionRouting);
+ mpCommandReceiver->getInterfaceVersion(versionCommand);
+ output << "\tReceiver versions:" << std::endl << "\tCtrl: " << versionControl << " | " << "Cmd: " << versionCommand << " | " << "Routing: " << versionRouting << std::endl;
+ sendTelnetLine(filedescriptor, output);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::infoSystempropertiesCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->infoSystempropertiesCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::infoDumpCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->infoDumpCommandExec(CmdQueue, filedescriptor);
+}
+
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setVolumeStep(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setSinkVolumeExec(CmdQueue,filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setVolumeStepExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ if (CmdQueue.size() >= 2)
+ {
+ int16_t volumestep = 0;
+ am_sinkID_t sinkID = 0;
+ bool error = false;
+ std::istringstream istream_sinkID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_volumestep(CmdQueue.front());
+ CmdQueue.pop();
+ if (!(istream_volumestep >> volumestep))
+ error = true;
+
+ if (!(istream_sinkID >> sinkID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing setVolumeStep 'sinkID' or 'volumestep'");
+ return;
+ }
+ if (E_OK == mpCommandReceiver->volumeStep(sinkID,volumestep))
+ {
+ std::stringstream output;
+ output << "SetSinkVolumeStep set: " << sinkID << "->" << volumestep << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error SetSinkVolumeStep");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to set SetSinkVolumeStep, please enter 'sinkID' and 'volumestep' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSinkMuteState(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setSinkMuteStateExec(CmdQueue,filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSinkMuteStateExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ if (CmdQueue.size() >= 2)
+ {
+ u_int16_t tmp = 0;
+ am_MuteState_e MuteState = MS_UNKNOWN;
+ am_sinkID_t sinkID = 0;
+ bool error = false;
+ std::istringstream istream_sinkID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_mutestate(CmdQueue.front());
+ CmdQueue.pop();
+ if (!(istream_mutestate >> tmp))
+ error = true;
+
+ if (!(istream_sinkID >> sinkID))
+ error = true;
+
+ if(tmp < MS_MAX)
+ {
+ MuteState = static_cast<am_MuteState_e>(tmp);
+ }
+ else
+ {
+ sendError(filedescriptor, "You tried to set an invalid am_MuteState_e");
+ error = true;
+ }
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing setSinkMuteState 'sinkID' or 'mutestate'");
+ return;
+ }
+ if (E_OK == mpCommandReceiver->setSinkMuteState(sinkID,MuteState))
+ {
+ std::stringstream output;
+ output << "setSinkMuteState set: " << sinkID << "->" << MuteState << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error setSinkMuteState");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to set setSinkMuteState, please enter 'sinkID' and 'mutestate' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSourceSoundProperty(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setSourceSoundPropertiesExec(CmdQueue,filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSourceSoundPropertyExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ unsigned int tmpType = 0;
+ bool error = false;
+ if (CmdQueue.size() >= 3)
+ {
+ std::istringstream istream_sourceID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_type(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_value(CmdQueue.front());
+ CmdQueue.pop();
+ if (!(istream_type >> tmpType))
+ error = true;
+
+ am_MainSoundProperty_s soundProperty;
+ soundProperty.type = static_cast<am_CustomMainSoundPropertyType_t>(tmpType);
+
+ if (!(istream_value >> soundProperty.value))
+ error = true;
+
+ am_sourceID_t sourceID = 0;
+ if (!(istream_sourceID >> sourceID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing setMainSourceSoundProperty 'type', 'value' or 'sourceID'");
+ return;
+ }
+ if (E_OK == mpCommandReceiver->setMainSourceSoundProperty(soundProperty, sourceID))
+ {
+ std::stringstream output;
+ output << "setMainSourceSoundProperty set: " << soundProperty.type << "->" << soundProperty.value << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error setMainSourceSoundProperty");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to set setMainSourceSoundProperty, please enter 'sourceID', 'type' and 'value' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::infoSystempropertiesCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_SystemProperty_s > listSystemProperties;
+ if (E_OK == mpDatabasehandler->getListSystemProperties(listSystemProperties))
+ {
+ std::stringstream output;
+ output << "\tSystemproperties: " << listSystemProperties.size() << std::endl;
+ std::vector<am_SystemProperty_s>::iterator it;
+ for (it = listSystemProperties.begin(); it < listSystemProperties.end(); it++)
+ {
+ output << "\tType: " << it->type << " Value: " << it->value << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListSystemProperties");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::infoDumpCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+
+ std::stringstream *pOutput = new std::stringstream();
+
+ mpDatabasehandler->dump(*pOutput);
+
+ sendTelnetLine(filedescriptor, *pOutput);
+
+ delete pOutput;
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setRoutingCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setRoutingCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setRoutingCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ if (CmdQueue.size() >= 2)
+ {
+ bool error = false;
+ std::istringstream istream_sourceID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_sinkID(CmdQueue.front());
+ CmdQueue.pop();
+ am_sourceID_t sourceID = 0;
+ if (!(istream_sourceID >> sourceID))
+ error = true;
+
+ am_sinkID_t sinkID = 0;
+ if (!(istream_sinkID >> sinkID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing sourcID and sinkID");
+ return;
+ }
+ std::vector < am_Route_s > routingList;
+ if (E_OK == mpRouter->getRoute(true, sourceID, sinkID, routingList))
+ {
+ std::stringstream output;
+ std::vector<am_Route_s>::iterator rlIter = routingList.begin();
+ for (int rlCnt = 1; rlIter < routingList.end(); rlIter++)
+ {
+ output << "#" << rlCnt << " ";
+ std::vector<am_RoutingElement_s>::iterator reIter = rlIter->route.begin();
+ for (; reIter < rlIter->route.end(); reIter++)
+ {
+ output << ">(" << reIter->sourceID << ")->--[D:" << reIter->domainID << "][F:" << reIter->connectionFormat << "]-->-(" << reIter->sinkID << ")" << std::endl;
+ }
+ rlCnt++;
+ }
+
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error getting route");
+ }
+ }
+ else
+ {
+ if (!CmdQueue.empty())
+ CmdQueue.pop();
+
+ sendError(filedescriptor, "Not enough arguments to set routing. Please enter sourceID and sinkID after command");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setConnection(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setConnectionExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setConnectionExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ bool error = false;
+ am_Error_e rError = E_OK;
+ if (CmdQueue.size() >= 2)
+ {
+ std::istringstream istream_sourceID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_sinkID(CmdQueue.front());
+ CmdQueue.pop();
+ am_sourceID_t sourceID = 0;
+ if (!(istream_sourceID >> sourceID))
+ error = true;
+
+ am_sinkID_t sinkID = 0;
+ if (!(istream_sinkID >> sinkID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing sinkID and/or sourceID");
+ return;
+ }
+// Try to set up connection
+ am_mainConnectionID_t connID = 0;
+ rError = mpCommandReceiver->connect(sourceID, sinkID, connID);
+ if (E_OK == rError)
+ {
+ std::stringstream output;
+ output << "ConnID: " << connID << "\tSrc: " << sourceID << " ---> Sink: " << sinkID << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error connecting sourceID and sinkID");
+ }
+ }
+ else
+ {
+// remove 1 element if list is not empty
+ if (!CmdQueue.empty())
+ CmdQueue.pop();
+
+ sendError(filedescriptor, "Not enough arguments to set routing. Please enter sourceID and sinkID after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setDisconnectConnId(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setDisconnectConnIdExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setDisconnectConnIdExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ am_mainConnectionID_t connID = 0;
+ bool error = false;
+ am_Error_e rError = E_OK;
+ if (CmdQueue.size() >= 1)
+ {
+ std::istringstream istream_connID(CmdQueue.front());
+ CmdQueue.pop();
+ if (!(istream_connID >> connID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing connID");
+ return;
+ }
+// Try to disconnect connection id
+ rError = mpCommandReceiver->disconnect(connID);
+ if (E_OK == rError)
+ {
+ std::stringstream output;
+ output << "ConnID " << connID << " closed successfully! " << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error disconnecting connectionID");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to disconnect a Main Connection, please enter 'connectionID' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSourceSoundProperties(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setConnectionExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSourceSoundPropertiesExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ if (CmdQueue.size() >= 3)
+ {
+ bool error = false;
+ std::istringstream istream_sourceID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_type(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_value(CmdQueue.front());
+ CmdQueue.pop();
+ unsigned int tmpType = 0;
+ if (!(istream_type >> tmpType))
+ error = true;
+
+ am_MainSoundProperty_s soundProperty;
+ soundProperty.type = static_cast<am_CustomMainSoundPropertyType_t>(tmpType);
+
+ if (!(istream_value >> soundProperty.value))
+ error = true;
+
+ am_sinkID_t sourceID = 0;
+ if (!(istream_sourceID >> sourceID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing MainSinkSoundProperty 'type', 'value' or 'sourceID'");
+ return;
+ }
+ if (E_OK == mpCommandReceiver->setMainSourceSoundProperty(soundProperty, sourceID))
+ {
+ std::stringstream output;
+ output << "MainSourceSoundProperty set: " << soundProperty.type << "->" << soundProperty.value << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error setMainSourceSoundProperty");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to set MainSourceSoundProperty, please enter 'sourceID', 'type' and 'value' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSinkSoundProperty(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setSinkSoundPropertyExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSinkSoundPropertyExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ unsigned int tmpType = 0;
+ bool error = false;
+ if (CmdQueue.size() >= 3)
+ {
+ std::istringstream istream_sinkID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_type(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_value(CmdQueue.front());
+ CmdQueue.pop();
+ if (!(istream_type >> tmpType))
+ error = true;
+
+ am_MainSoundProperty_s soundProperty;
+ soundProperty.type = static_cast<am_CustomMainSoundPropertyType_t>(tmpType);
+
+ if (!(istream_value >> soundProperty.value))
+ error = true;
+
+ am_sinkID_t sinkID = 0;
+ if (!(istream_sinkID >> sinkID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing MainSinkSoundProperty 'type', 'value' or 'sinkID'");
+ return;
+ }
+ if (E_OK == mpCommandReceiver->setMainSinkSoundProperty(soundProperty, sinkID))
+ {
+ std::stringstream output;
+ output << "MainSinkSoundProperty set: " << soundProperty.type << "->" << soundProperty.value << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error setMainSinkSoundProperty");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to set MainSinkSoundProperty, please enter 'sinkID', 'type' and 'value' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSinkVolume(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->setSinkVolumeExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::setSinkVolumeExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ if (CmdQueue.size() >= 2)
+ {
+ am_volume_t volume = 0;
+ am_sinkID_t sinkID = 0;
+ bool error = false;
+ std::istringstream istream_sinkID(CmdQueue.front());
+ CmdQueue.pop();
+ std::istringstream istream_volume(CmdQueue.front());
+ CmdQueue.pop();
+ if (!(istream_volume >> volume))
+ error = true;
+
+ if (!(istream_sinkID >> sinkID))
+ error = true;
+
+ if (error)
+ {
+ sendError(filedescriptor, "Error parsing SetSinkVolume 'sinkID' or 'volume'");
+ return;
+ }
+ if (E_OK == mpCommandReceiver->setVolume(sinkID,volume))
+ {
+ std::stringstream output;
+ output << "setVolume set: " << sinkID << "->" << volume << std::endl;
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "Error setVolume");
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "Not enough arguments to set setVolume, please enter 'sinkID' and 'volume' after command");
+ return;
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listPluginsCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listPluginsCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listPluginsCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < std::string > PlugInNames;
+ std::vector<std::string>::iterator iter;
+ std::stringstream output;
+ if (E_OK == mpCommandSender->getListPlugins(PlugInNames))
+ {
+ output << "\tCommandSender Plugins loaded: " << PlugInNames.size() << std::endl;
+ for (iter = PlugInNames.begin(); iter < PlugInNames.end(); iter++)
+ {
+ output << iter->c_str() << std::endl;
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mCommandSender->getListPlugins");
+ }
+ if (E_OK == mpRoutingSender->getListPlugins(PlugInNames))
+ {
+ output << std::endl << "\tRoutingSender Plugins loaded: " << PlugInNames.size() << std::endl;
+ for (iter = PlugInNames.begin(); iter < PlugInNames.end(); iter++)
+ {
+ output << iter->c_str() << std::endl;
+ }
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mRoutingSender->getListPlugins");
+ }
+ sendTelnetLine(filedescriptor, output);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listMainSourcesCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listMainSourcesCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listMainSourcesCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_SourceType_s > listMainSources;
+ if (E_OK == mpDatabasehandler->getListMainSources(listMainSources))
+ {
+ std::stringstream output;
+ output << std::endl << "\tMainSources: " << listMainSources.size() << std::endl;
+ std::vector<am_SourceType_s>::iterator iter;
+ for (iter = listMainSources.begin(); iter < listMainSources.end(); iter++)
+ {
+ output << "\tID: " << iter->sourceID << "\tName: " << iter->name << "\tsourceClassID: " << iter->sourceClassID << "\tavailability: " << iter->availability.availability << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListMainSources");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listMainSinksCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listMainSinksCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listMainSinksCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector < am_SinkType_s > listMainSinks;
+ if (E_OK == mpDatabasehandler->getListMainSinks(listMainSinks))
+ {
+ std::stringstream output;
+ output << std::endl << "\tMainSinks: " << listMainSinks.size() << std::endl;
+ std::vector<am_SinkType_s>::iterator iter;
+ for (iter = listMainSinks.begin(); iter < listMainSinks.end(); iter++)
+ {
+ output << "\tID: " << iter->sinkID << "\tsinkClassID: " << iter->sinkClassID << "\tName: " << iter->name << "\tAvailable: " << iter->availability.availability << "\tVolume: " << iter->volume << std::endl;
+ }
+ sendTelnetLine(filedescriptor, output);
+ }
+ else
+ {
+ sendError(filedescriptor, "ERROR: mDatabasehandler->getListMainSinks");
+ }
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listMainConnectionsCommand(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ instance->listMainConnectionsCommandExec(CmdQueue, filedescriptor);
+}
+
+/****************************************************************************/
+void CAmTelnetMenuHelper::listMainConnectionsCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor)
+/****************************************************************************/
+{
+ (void) (CmdQueue);
+ std::vector<am_MainConnection_s> listMainConnections;
+
+ if(E_OK == mpDatabasehandler->getListMainConnections(listMainConnections))
+ {
+ std::stringstream output;
+ output << std::endl << "\tMainConnections: " << listMainConnections.size() << std::endl;
+
+ std::vector<am_MainConnection_s>::iterator iter;
+ for (iter = listMainConnections.begin(); iter < listMainConnections.end(); iter++)
+ {
+ output << "\tID: " << iter->mainConnectionID
+ << "\tState: " << iter->connectionState
+ << "\tDelay: " << iter->delay
+ << "\tsourceID: " << iter->sourceID
+ << "\tsinkID: " << iter->sinkID << std::endl;
+
+ output << "ConnectionIDs: ";
+ std::vector<am_connectionID_t>::iterator list_connIDs_iter = iter->listConnectionID.begin();
+ for(;list_connIDs_iter < iter->listConnectionID.end();list_connIDs_iter++)
+ {
+ output << *list_connIDs_iter << " ";
+ }
+
+ output << std::endl;
+ }
+ sendTelnetLine(filedescriptor,output);
+ }
+ else
+ {
+ sendError(filedescriptor,"ERROR: mDatabasehandler->getListMainSinks");
+ }
+}
+}
+
+
+
+
+
diff --git a/AudioManagerCore/src/CAmTelnetServer.cpp b/AudioManagerCore/src/CAmTelnetServer.cpp
new file mode 100755
index 0000000..22f7b0e
--- /dev/null
+++ b/AudioManagerCore/src/CAmTelnetServer.cpp
@@ -0,0 +1,257 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ * \author Frank Herchet, frank.fh.herchet@bmw.de BMW 2012
+ *
+ * \file CAmTelnetServer.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmTelnetServer.h"
+#include <cassert>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <netdb.h>
+#include <audiomanagerconfig.h>
+#include <errno.h>
+#include <sstream>
+#include <istream>
+#include <iostream>
+#include <iterator>
+#include <unistd.h>
+#include <stdexcept>
+#include <cstdlib>
+#include "CAmRoutingSender.h"
+#include "CAmTelnetMenuHelper.h"
+#include "CAmDltWrapper.h"
+
+namespace am
+{
+
+CAmTelnetServer* CAmTelnetServer::mpInstance = NULL;
+
+#define PRINT_BOOL(var) var ? output+="true\t\t" : output+="false\t\t";
+
+CAmTelnetServer::CAmTelnetServer(CAmSocketHandler *iSocketHandler, CAmCommandSender *iCommandSender, CAmCommandReceiver *iCommandReceiver, CAmRoutingSender *iRoutingSender, CAmRoutingReceiver *iRoutingReceiver, CAmControlSender *iControlSender, CAmControlReceiver *iControlReceiver, IAmDatabaseHandler *iDatabasehandler, CAmRouter *iRouter, unsigned int servPort, unsigned int maxConnections) :
+ telnetConnectFiredCB(this, &CAmTelnetServer::connectSocket), //
+ telnetReceiveFiredCB(this, &CAmTelnetServer::receiveData), //
+ telnetDispatchCB(this, &CAmTelnetServer::dispatchData), //
+ telnetCheckCB(this, &CAmTelnetServer::check), //
+ mpSocketHandler(iSocketHandler), //
+ mpCommandSender(iCommandSender), //
+ mpCommandReceiver(iCommandReceiver), //
+ mpRoutingSender(iRoutingSender), //
+ mpRoutingReceiver(iRoutingReceiver), //
+ mpControlSender(iControlSender), //
+ mpControlReceiver(iControlReceiver), //
+ mpDatabasehandler(iDatabasehandler), //
+ mpRouter(iRouter), //
+ mConnecthandle(), //
+ mListMessages(), //
+ mListConnections(), //
+ mConnectFD(0), //
+ mServerPort(servPort), //
+ mMaxConnections(maxConnections), //
+ mTelnetMenuHelper(iSocketHandler, iCommandSender, iCommandReceiver, iRoutingSender, iRoutingReceiver, iControlSender, iControlReceiver, iDatabasehandler, iRouter, this)
+{
+ assert(mpSocketHandler!=NULL);
+ assert(mpCommandReceiver!=NULL);
+ assert(mpCommandSender!=NULL);
+ assert(mpControlSender!=NULL);
+ assert(mpControlReceiver!=NULL);
+ assert(mpRoutingSender!=NULL);
+ assert(mpRoutingReceiver!=NULL);
+ assert(mpDatabasehandler!=NULL);
+ assert(mpRouter!=NULL);
+ assert(servPort!=0);
+ assert(mMaxConnections!=0);
+
+ mpInstance = this;
+ //mTelnetMenuHelper.setTelnetServer(this);
+
+ int yes = 1;
+ struct sockaddr_in servAddr;
+
+ //setup the port Listener
+ mConnectFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert (mConnectFD>0);
+ assert(setsockopt(mConnectFD, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))==0);
+ memset(&servAddr, 0, sizeof(servAddr));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_addr.s_addr = INADDR_ANY;
+ servAddr.sin_port = htons(servPort);
+ if(bind(mConnectFD, (struct sockaddr *) &servAddr, sizeof(servAddr))!=0)
+ {
+ logError("CAmTelnetServer::CAmTelnetServer bind failed, error",errno);
+ throw std::runtime_error("CAmTelnetServer::CAmTelnetServer bind failed");
+ }
+
+ if (listen(mConnectFD, mMaxConnections) < 0)
+ {
+ logError("TelnetServer::TelnetServerk cannot listen ", errno);
+ throw std::runtime_error("CAmTelnetServer::CAmTelnetServer bind failed");
+ }
+ else
+ logInfo("TelnetServer::TelnetServer started listening on port", mServerPort);
+
+ int a = 1;
+ ioctl(mConnectFD, FIONBIO, (char *) &a);
+ setsockopt(mConnectFD, SOL_SOCKET, SO_KEEPALIVE, (char *) &a, sizeof(a));
+
+ short events = 0;
+ events |= POLLIN;
+ mpSocketHandler->addFDPoll(mConnectFD, events, NULL, &telnetConnectFiredCB, NULL, NULL, NULL, mConnecthandle);
+}
+
+CAmTelnetServer::~CAmTelnetServer()
+{
+}
+
+void CAmTelnetServer::connectSocket(const pollfd pfd, const sh_pollHandle_t handle, void *userData)
+{
+ (void) handle;
+ (void) userData;
+ //first, accept the connection, create a new filedescriptor
+ struct sockaddr answer;
+ socklen_t len = sizeof(answer);
+ connection_s connection;
+ connection.handle = 0;
+ connection.filedescriptor = accept(pfd.fd, (struct sockaddr*) &answer, &len);
+
+ assert(connection.filedescriptor>0);
+
+ // Notiy menuhelper
+ mTelnetMenuHelper.newSocketConnection(connection.filedescriptor);
+
+ //set the correct event:
+ short event = 0;
+ event |= POLLIN;
+
+ //add the filedescriptor to the sockethandler and register the callbacks for receiving the data
+ mpSocketHandler->addFDPoll(connection.filedescriptor, event, NULL, &telnetReceiveFiredCB, &telnetCheckCB, &telnetDispatchCB, NULL, connection.handle);
+ mListConnections.push_back(connection);
+}
+
+void CAmTelnetServer::disconnectClient(int filedescriptor)
+{
+ std::vector<connection_s>::iterator iter = mListConnections.begin();
+ while (iter != mListConnections.end())
+ {
+ if (filedescriptor == iter->filedescriptor)
+ {
+ if (E_OK == mpSocketHandler->removeFDPoll(iter->handle))
+ {
+ mListConnections.erase(iter);
+ close(filedescriptor);
+ }
+ else
+ {
+ // TODO: Handle error
+ }
+
+ break;
+ }
+ iter++;
+ }
+}
+
+void CAmTelnetServer::receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
+{
+ (void) handle;
+ (void) userData;
+ //initialize buffer
+ char buffer[100];
+ //read until buffer is full or no more data is there
+ int read = recv(pollfd.fd, buffer, 100, 0);
+ if (read > 1)
+ {
+ //read the message and store it in a queue - its a telnet connection so data will be sent on enter !
+ std::string msg = std::string(buffer, read);
+ mListMessages.push(msg);
+ }
+}
+
+bool CAmTelnetServer::dispatchData(const sh_pollHandle_t handle, void *userData)
+{
+ (void) userData;
+ std::vector<connection_s>::iterator iterator = mListConnections.begin();
+ for (; iterator != mListConnections.end(); ++iterator)
+ {
+ if (iterator->handle == handle)
+ break;
+ }
+ if (iterator==mListConnections.end())
+ {
+ logError("CAmTelnetServer::dispatchData could not find handle !");
+ return (false);
+ }
+
+ std::string command;
+ std::queue<std::string> MsgQueue;
+ if (!mListMessages.empty())
+ {
+ sliceCommand(mListMessages.front(), command, MsgQueue);
+ mListMessages.pop();
+ mTelnetMenuHelper.enterCmdQueue(MsgQueue, iterator->filedescriptor);
+ }
+ else
+ {
+ logError("CAmTelnetServer::dispatchData Message queue was empty!");
+ }
+
+ // must return false to stop endless polling
+ return (false);
+}
+
+bool CAmTelnetServer::check(const sh_pollHandle_t handle, void *userData)
+{
+ (void) handle;
+ (void) userData;
+ if (mListMessages.size() != 0)
+ return (true);
+ return (false);
+}
+
+void am::CAmTelnetServer::sliceCommand(const std::string & string, std::string & command, std::queue<std::string> & MsgQueue)
+{
+ (void) command;
+ std::stringstream stream(string);
+ std::istream_iterator<std::string> begin(stream);
+ std::istream_iterator<std::string> end;
+ std::string cmd;
+ bool endOfStream = false;
+
+ int c = 0;
+
+ while (!endOfStream)
+ {
+ cmd = *begin;
+ MsgQueue.push(cmd);
+ begin++;
+
+ if (begin == end)
+ {
+ endOfStream = true;
+ }
+ c++;
+ }
+}
+}
+