summaryrefslogtreecommitdiff
path: root/AudioManagerCore
diff options
context:
space:
mode:
Diffstat (limited to 'AudioManagerCore')
-rw-r--r--AudioManagerCore/CMakeLists.txt109
-rw-r--r--AudioManagerCore/include/CAmCommandReceiver.h97
-rw-r--r--AudioManagerCore/include/CAmCommandSender.h91
-rw-r--r--AudioManagerCore/include/CAmControlReceiver.h156
-rw-r--r--AudioManagerCore/include/CAmControlSender.h154
-rw-r--r--AudioManagerCore/include/CAmDatabaseHandlerMap.h495
-rw-r--r--AudioManagerCore/include/CAmDatabaseObserver.h87
-rw-r--r--AudioManagerCore/include/CAmGraph.h630
-rw-r--r--AudioManagerCore/include/CAmLog.h129
-rw-r--r--AudioManagerCore/include/CAmRouter.h317
-rw-r--r--AudioManagerCore/include/CAmRoutingReceiver.h127
-rw-r--r--AudioManagerCore/include/CAmRoutingSender.h155
-rw-r--r--AudioManagerCore/include/CAmTelnetMenuHelper.h204
-rw-r--r--AudioManagerCore/include/CAmTelnetServer.h100
-rw-r--r--AudioManagerCore/include/IAmDatabaseHandler.h200
-rw-r--r--AudioManagerCore/include/TAmPluginTemplate.h91
-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
-rw-r--r--AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp673
-rw-r--r--AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.h76
-rw-r--r--AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt52
-rw-r--r--AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt~50
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.cpp3276
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.h92
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/CAmTestDatabaseObserver.cpp98
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt49
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt~54
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/MockDatabaseObserver.h120
-rw-r--r--AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.cpp3183
-rw-r--r--AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h108
-rw-r--r--AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt47
-rw-r--r--AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt~47
-rw-r--r--AudioManagerCore/test/AmRouterTest/CAmRouterTest.cpp1967
-rw-r--r--AudioManagerCore/test/AmRouterTest/CAmRouterTest.h81
-rw-r--r--AudioManagerCore/test/AmRouterTest/CMakeLists.txt48
-rw-r--r--AudioManagerCore/test/AmRouterTest/CMakeLists.txt~47
-rw-r--r--AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp383
-rw-r--r--AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.h71
-rw-r--r--AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt49
-rw-r--r--AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt~48
-rw-r--r--AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.cpp209
-rw-r--r--AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.h107
-rw-r--r--AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt48
-rw-r--r--AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt~46
-rw-r--r--AudioManagerCore/test/CAmCommonFunctions.cpp383
-rw-r--r--AudioManagerCore/test/CAmCommonFunctions.h96
-rw-r--r--AudioManagerCore/test/CMakeLists.txt35
-rw-r--r--AudioManagerCore/test/IAmCommandBackdoor.h47
-rw-r--r--AudioManagerCore/test/IAmControlBackdoor.h44
-rw-r--r--AudioManagerCore/test/IAmRoutingBackdoor.h46
-rw-r--r--AudioManagerCore/test/MockIAmCommandSend.h94
-rw-r--r--AudioManagerCore/test/MockIAmControlSend.h160
-rw-r--r--AudioManagerCore/test/MockIAmRoutingSend.h83
63 files changed, 24426 insertions, 0 deletions
diff --git a/AudioManagerCore/CMakeLists.txt b/AudioManagerCore/CMakeLists.txt
new file mode 100644
index 0000000..2a553ba
--- /dev/null
+++ b/AudioManagerCore/CMakeLists.txt
@@ -0,0 +1,109 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project (AudioManagerCore LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
+
+SET(AUDIOMANAGER_CORE_INCLUDE
+ ${AUDIOMANAGER_CORE}/include
+ ${AUDIOMANAGER_UTILITIES_INCLUDE}
+ CACHE INTERNAL "AUDIOMANAGER_CORE_INCLUDE directories" FORCE)
+
+SET(AUDIO_MANAGER_CORE_LIBS
+ ${AUDIO_MANAGER_UTILITIES_LIBS}
+ AudioManagerUtilities
+ CACHE INTERNAL "AUDIO_MANAGER_CORE_LIBS libs" FORCE)
+
+IF (WITH_SHARED_CORE)
+ SET(LIBRARY_TYPE SHARED)
+ELSE (WITH_SHARED_CORE)
+ SET(LIBRARY_TYPE STATIC)
+ENDIF (WITH_SHARED_CORE)
+
+set(AUDIOMAN_CORE_SRCS_CXX
+ src/CAmCommandReceiver.cpp
+ src/CAmCommandSender.cpp
+ src/CAmControlReceiver.cpp
+ src/CAmControlSender.cpp
+ src/CAmDatabaseObserver.cpp
+ src/CAmRoutingReceiver.cpp
+ src/CAmRoutingSender.cpp
+ src/CAmRouter.cpp
+ src/CAmLog.cpp
+ src/CAmDatabaseHandlerMap.cpp
+)
+
+if(WITH_TELNET)
+ set (AUDIOMAN_CORE_SRCS_CXX
+ ${AUDIOMAN_CORE_SRCS_CXX}
+ src/CAmTelnetServer.cpp
+ src/CAmTelnetMenuHelper.cpp)
+endif(WITH_TELNET)
+
+INCLUDE_DIRECTORIES(${AUDIOMANAGER_CORE_INCLUDE})
+
+ADD_LIBRARY(AudioManagerCore ${LIBRARY_TYPE} ${AUDIOMAN_CORE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AudioManagerCore ${AUDIO_MANAGER_CORE_LIBS} )
+
+ADD_DEPENDENCIES(AudioManagerCore AudioManagerUtilities)
+
+set_target_properties(AudioManagerCore PROPERTIES VERSION ${AudioManagerCore_VERSION} SOVERSION ${AudioManagerCore_VERSION_MAJOR})
+
+
+IF (WITH_SHARED_CORE)
+ INSTALL(TARGETS AudioManagerCore
+ LIBRARY DESTINATION lib
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT bin)
+ELSE (WITH_SHARED_CORE)
+ INSTALL(TARGETS AudioManagerCore
+ ARCHIVE DESTINATION lib
+ COMPONENT dev)
+ENDIF (WITH_SHARED_CORE)
+
+configure_file( ${CMAKE_SOURCE_DIR}/cmake/audiomanagercore.pc.in ${CMAKE_BINARY_DIR}/audiomanagercore.pc @ONLY )
+install(FILES ${CMAKE_BINARY_DIR}/audiomanagercore.pc DESTINATION lib/pkgconfig COMPONENT devel)
+
+configure_package_config_file (
+ ${CMAKE_SOURCE_DIR}/cmake/AudioManagerCoreConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/AudioManagerCoreConfig.cmake
+ INSTALL_DESTINATION lib/${LIB_INSTALL_SUFFIX}/cmake
+ PATH_VARS AUDIO_INCLUDE_FOLDER )
+
+write_basic_package_version_file(
+ ${CMAKE_CURRENT_BINARY_DIR}/AudioManagerCoreConfigVersion.cmake
+ VERSION ${DAEMONVERSION}
+ COMPATIBILITY SameMajorVersion )
+
+install(
+FILES ${CMAKE_CURRENT_BINARY_DIR}/AudioManagerCoreConfig.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/AudioManagerCoreConfigVersion.cmake
+DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/AudioManagerCore-${DAEMONVERSION})
+
+INSTALL(DIRECTORY "${AUDIOMANAGER_CORE}/include/"
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${LIB_INSTALL_SUFFIX}/AudioManagerCore
+ COMPONENT dev)
+
+if(WITH_TESTS)
+ add_subdirectory (test)
+endif(WITH_TESTS)
+
+
+
diff --git a/AudioManagerCore/include/CAmCommandReceiver.h b/AudioManagerCore/include/CAmCommandReceiver.h
new file mode 100644
index 0000000..0f30d81
--- /dev/null
+++ b/AudioManagerCore/include/CAmCommandReceiver.h
@@ -0,0 +1,97 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef COMMANDRECEIVER_H_
+#define COMMANDRECEIVER_H_
+
+#include "IAmCommand.h"
+
+namespace am
+{
+
+class IAmDatabaseHandler;
+class CAmControlSender;
+class CAmDbusWrapper;
+class CAmSocketHandler;
+
+/**
+ * This class realizes the command Interface
+ */
+class CAmCommandReceiver: public IAmCommandReceive
+{
+public:
+ CAmCommandReceiver(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iControlSender, CAmSocketHandler* iSocketHandler);
+ CAmCommandReceiver(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iControlSender, CAmSocketHandler* iSocketHandler, CAmDbusWrapper* iDBusWrapper);
+ ~CAmCommandReceiver();
+ am_Error_e connect(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t& mainConnectionID);
+ am_Error_e disconnect(const am_mainConnectionID_t mainConnectionID);
+ am_Error_e setVolume(const am_sinkID_t sinkID, const am_mainVolume_t volume);
+ am_Error_e volumeStep(const am_sinkID_t sinkID, const int16_t volumeStep);
+ am_Error_e setSinkMuteState(const am_sinkID_t sinkID, const am_MuteState_e muteState);
+ am_Error_e setMainSinkSoundProperty(const am_MainSoundProperty_s& soundProperty, const am_sinkID_t sinkID);
+ am_Error_e setMainSourceSoundProperty(const am_MainSoundProperty_s& soundProperty, const am_sourceID_t sourceID);
+ am_Error_e setSystemProperty(const am_SystemProperty_s& property);
+ am_Error_e getVolume(const am_sinkID_t sinkID, am_mainVolume_t& mainVolume) const;
+ am_Error_e getListMainConnections(std::vector<am_MainConnectionType_s>& listConnections) const;
+ am_Error_e getListMainSinks(std::vector<am_SinkType_s>& listMainSinks) const;
+ am_Error_e getListMainSources(std::vector<am_SourceType_s>& listMainSources) const;
+ am_Error_e getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s>& listSoundProperties) const;
+ am_Error_e getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s>& listSourceProperties) const;
+ am_Error_e getListSourceClasses(std::vector<am_SourceClass_s>& listSourceClasses) const;
+ am_Error_e getListSinkClasses(std::vector<am_SinkClass_s>& listSinkClasses) const;
+ am_Error_e getListSystemProperties(std::vector<am_SystemProperty_s>& listSystemProperties) const;
+ am_Error_e getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t& delay) const;
+ am_Error_e getDBusConnectionWrapper(CAmDbusWrapper*& dbusConnectionWrapper) const;
+ am_Error_e getSocketHandler(CAmSocketHandler*& socketHandler) const;
+ void confirmCommandReady(const uint16_t handle, const am_Error_e error);
+ void confirmCommandRundown(const uint16_t handle, const am_Error_e error);
+ void getInterfaceVersion(std::string& version) const;
+ am_Error_e getListMainSinkNotificationConfigurations(const am_sinkID_t sinkID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations) const ;
+ am_Error_e getListMainSourceNotificationConfigurations(const am_sourceID_t sourceID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations) const ;
+ am_Error_e setMainSinkNotificationConfiguration(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration) ;
+ am_Error_e setMainSourceNotificationConfiguration(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration) ;
+
+ uint16_t getStartupHandle(); //!< returns a startup handle
+ uint16_t getRundownHandle(); //!< returns a rundown handle
+
+ void waitOnStartup(bool startup); //!< tells the ComandReceiver to start waiting for all handles to be confirmed
+ void waitOnRundown(bool rundown); //!< tells the ComandReceiver to start waiting for all handles to be confirmed
+
+private:
+ IAmDatabaseHandler* mDatabaseHandler; //!< pointer to the databasehandler
+ CAmControlSender* mControlSender; //!< pointer to the control sender
+ CAmDbusWrapper* mDBusWrapper; //!< pointer to the dbuswrapper
+ CAmSocketHandler* mSocketHandler; //!< pointer to the SocketHandler
+
+ uint16_t handleCount; //!< counts all handles
+ std::vector<uint16_t> mListStartupHandles; //!< list of handles that wait for a confirm
+ std::vector<uint16_t> mListRundownHandles; //!< list of handles that wait for a confirm
+ bool mWaitStartup; //!< if true confirmation will be sent if list of handles = 0
+ bool mWaitRundown; //!< if true confirmation will be sent if list of handles = 0
+ am_Error_e mLastErrorStartup;
+ am_Error_e mLastErrorRundown;
+};
+
+}
+
+#endif /* COMMANDRECEIVER_H_ */
diff --git a/AudioManagerCore/include/CAmCommandSender.h b/AudioManagerCore/include/CAmCommandSender.h
new file mode 100644
index 0000000..82363de
--- /dev/null
+++ b/AudioManagerCore/include/CAmCommandSender.h
@@ -0,0 +1,91 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef COMMANDSENDER_H_
+#define COMMANDSENDER_H_
+
+#ifdef UNIT_TEST
+#include "../test/IAmCommandBackdoor.h" //we need this for the unit test
+#endif
+
+#include "IAmCommand.h"
+
+namespace am
+{
+
+class CAmCommandReceiver;
+
+
+/**
+ * This class is used to send data to the CommandInterface.
+ * All loaded plugins will be called when a callback is invoked.
+ */
+class CAmCommandSender
+{
+public:
+ CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories);
+ ~CAmCommandSender();
+ am_Error_e startupInterfaces(CAmCommandReceiver* iCommandReceiver);
+ void setCommandReady();
+ void setCommandRundown();
+ void cbNewMainConnection(const am_MainConnectionType_s mainConnection);
+ void cbRemovedMainConnection(const am_mainConnectionID_t mainConnection);
+ void cbNewSink(am_SinkType_s sink);
+ void cbRemovedSink(const am_sinkID_t sink);
+ void cbNewSource(const am_SourceType_s source);
+ void cbRemovedSource(const am_sourceID_t source);
+ void cbNumberOfSinkClassesChanged();
+ void cbNumberOfSourceClassesChanged();
+ void cbMainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState);
+ void cbMainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& soundProperty);
+ void cbMainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& soundProperty);
+ void cbSinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s& availability);
+ void cbSourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s& availability);
+ void cbVolumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume);
+ void cbSinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState);
+ void cbSystemPropertyChanged(const am_SystemProperty_s& systemProperty);
+ void cbTimingInformationChanged(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time);
+ void getInterfaceVersion(std::string& version) const;
+ am_Error_e getListPlugins(std::vector<std::string>& interfaces) const;
+ void cbSinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties);
+ void cbSourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties);
+ void cbSinkNotification(const am_sinkID_t sinkID, const am_NotificationPayload_s& notification);
+ void cbSourceNotification(const am_sourceID_t sourceID, const am_NotificationPayload_s& notification);
+ void cbSinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration);
+ void cbSourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration);
+
+#ifdef UNIT_TEST
+ friend class IAmCommandBackdoor; //this is to get access to the loaded plugins and be able to exchange the interfaces
+#endif
+private:
+ void unloadLibraries(void); //!< unload the shared libraries
+ std::vector<IAmCommandSend*> mListInterfaces; //!< list of all interfaces
+ std::vector<void*> mListLibraryHandles; //!< list of all library handles. This information is used to unload the plugins correctly.
+ std::vector<std::string> mListLibraryNames; //!< list of all library names. This information is used for getListPlugins.
+
+ CAmCommandReceiver *mCommandReceiver;
+};
+
+}
+
+#endif /* COMMANDSENDER_H_ */
diff --git a/AudioManagerCore/include/CAmControlReceiver.h b/AudioManagerCore/include/CAmControlReceiver.h
new file mode 100644
index 0000000..3f39189
--- /dev/null
+++ b/AudioManagerCore/include/CAmControlReceiver.h
@@ -0,0 +1,156 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef CONTRONLRECEIVER_H_
+#define CONTRONLRECEIVER_H_
+
+#include "IAmControl.h"
+
+namespace am
+{
+
+class CAmSocketHandler;
+class IAmDatabaseHandler;
+class CAmRoutingSender;
+class CAmCommandSender;
+class CAmRouter;
+class CAmNodeStateCommunicator;
+
+/**
+ * This class is used to receive all commands from the control interface
+ */
+class CAmControlReceiver: public IAmControlReceive
+{
+public:
+ CAmControlReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmCommandSender *iCommandSender, CAmSocketHandler *iSocketHandler, CAmRouter* iRouter);
+ ~CAmControlReceiver();
+ am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
+ am_Error_e connect(am_Handle_s& handle, am_connectionID_t& connectionID, const am_CustomConnectionFormat_t format, const am_sourceID_t sourceID, const am_sinkID_t sinkID);
+ am_Error_e disconnect(am_Handle_s& handle, const am_connectionID_t connectionID);
+ am_Error_e 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);
+ am_Error_e abortAction(const am_Handle_s handle);
+ am_Error_e setSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state);
+ am_Error_e 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);
+ am_Error_e 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);
+ am_Error_e setSinkSoundProperties(am_Handle_s& handle, const am_sinkID_t sinkID, const std::vector<am_SoundProperty_s>& soundProperty);
+ am_Error_e setSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s& soundProperty);
+ am_Error_e setSourceSoundProperties(am_Handle_s& handle, const am_sourceID_t sourceID, const std::vector<am_SoundProperty_s>& soundProperty);
+ am_Error_e setSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s& soundProperty);
+ am_Error_e setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState);
+ am_Error_e enterDomainDB(const am_Domain_s& domainData, am_domainID_t& domainID);
+ am_Error_e enterMainConnectionDB(const am_MainConnection_s& mainConnectionData, am_mainConnectionID_t& connectionID);
+ am_Error_e enterSinkDB(const am_Sink_s& sinkData, am_sinkID_t& sinkID);
+ am_Error_e enterCrossfaderDB(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID);
+ am_Error_e enterGatewayDB(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID);
+ am_Error_e enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID);
+ am_Error_e enterSourceDB(const am_Source_s& sourceData, am_sourceID_t& sourceID);
+ am_Error_e enterSinkClassDB(const am_SinkClass_s& sinkClass, am_sinkClass_t& sinkClassID);
+ am_Error_e enterSourceClassDB(am_sourceClass_t& sourceClassID, const am_SourceClass_s& sourceClass);
+ am_Error_e changeSinkClassInfoDB(const am_SinkClass_s& sinkClass);
+ am_Error_e changeSourceClassInfoDB(const am_SourceClass_s& sourceClass);
+ am_Error_e enterSystemPropertiesListDB(const std::vector<am_SystemProperty_s>& listSystemProperties);
+ am_Error_e changeMainConnectionRouteDB(const am_mainConnectionID_t mainconnectionID, const std::vector<am_connectionID_t>& listConnectionID);
+ am_Error_e changeMainConnectionStateDB(const am_mainConnectionID_t mainconnectionID, const am_ConnectionState_e connectionState);
+ am_Error_e changeSinkMainVolumeDB(const am_mainVolume_t mainVolume, const am_sinkID_t sinkID);
+ am_Error_e changeSinkAvailabilityDB(const am_Availability_s& availability, const am_sinkID_t sinkID);
+ am_Error_e changDomainStateDB(const am_DomainState_e domainState, const am_domainID_t domainID);
+ am_Error_e changeSinkMuteStateDB(const am_MuteState_e muteState, const am_sinkID_t sinkID);
+ am_Error_e changeMainSinkSoundPropertyDB(const am_MainSoundProperty_s& soundProperty, const am_sinkID_t sinkID);
+ am_Error_e changeMainSourceSoundPropertyDB(const am_MainSoundProperty_s& soundProperty, const am_sourceID_t sourceID);
+ am_Error_e changeSourceAvailabilityDB(const am_Availability_s& availability, const am_sourceID_t sourceID);
+ am_Error_e changeSystemPropertyDB(const am_SystemProperty_s& property);
+ am_Error_e removeMainConnectionDB(const am_mainConnectionID_t mainConnectionID);
+ am_Error_e removeSinkDB(const am_sinkID_t sinkID);
+ am_Error_e removeSourceDB(const am_sourceID_t sourceID);
+ am_Error_e removeGatewayDB(const am_gatewayID_t gatewayID);
+ am_Error_e removeConverterDB(const am_converterID_t converterID);
+ am_Error_e removeCrossfaderDB(const am_crossfaderID_t crossfaderID);
+ am_Error_e removeDomainDB(const am_domainID_t domainID);
+ am_Error_e removeSinkClassDB(const am_sinkClass_t sinkClassID);
+ am_Error_e removeSourceClassDB(const am_sourceClass_t sourceClassID);
+ am_Error_e getSourceClassInfoDB(const am_sourceID_t sourceID, am_SourceClass_s& classInfo) const;
+ am_Error_e getSinkClassInfoDB(const am_sinkID_t sinkID, am_SinkClass_s& sinkClass) const;
+ am_Error_e getSinkInfoDB(const am_sinkID_t sinkID, am_Sink_s& sinkData) const;
+ am_Error_e getSourceInfoDB(const am_sourceID_t sourceID, am_Source_s& sourceData) const;
+ am_Error_e getGatewayInfoDB(const am_gatewayID_t gatewayID, am_Gateway_s& gatewayData) const;
+ am_Error_e getConverterInfoDB(const am_converterID_t converterID, am_Converter_s& converterData) const;
+ am_Error_e getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s& crossfaderData) const;
+ am_Error_e getMainConnectionInfoDB(const am_mainConnectionID_t mainConnectionID, am_MainConnection_s& mainConnectionData) const;
+ am_Error_e getListSinksOfDomain(const am_domainID_t domainID, std::vector<am_sinkID_t>& listSinkID) const;
+ am_Error_e getListSourcesOfDomain(const am_domainID_t domainID, std::vector<am_sourceID_t>& listSourceID) const;
+ am_Error_e getListCrossfadersOfDomain(const am_domainID_t domainID, std::vector<am_crossfaderID_t>& listCrossfadersID) const;
+ am_Error_e getListGatewaysOfDomain(const am_domainID_t domainID, std::vector<am_gatewayID_t>& listGatewaysID) const;
+ am_Error_e getListConvertersOfDomain(const am_domainID_t domainID, std::vector<am_converterID_t>& listConverterID) const;
+ am_Error_e getListMainConnections(std::vector<am_MainConnection_s>& listMainConnections) const;
+ am_Error_e getListDomains(std::vector<am_Domain_s>& listDomains) const;
+ am_Error_e getListConnections(std::vector<am_Connection_s>& listConnections) const;
+ am_Error_e getListSinks(std::vector<am_Sink_s>& listSinks) const;
+ am_Error_e getListSources(std::vector<am_Source_s>& listSources) const;
+ am_Error_e getListSourceClasses(std::vector<am_SourceClass_s>& listSourceClasses) const;
+ am_Error_e getListHandles(std::vector<am_Handle_s>& listHandles) const;
+ am_Error_e getListCrossfaders(std::vector<am_Crossfader_s>& listCrossfaders) const;
+ am_Error_e getListGateways(std::vector<am_Gateway_s>& listGateways) const;
+ am_Error_e getListConverters(std::vector<am_Converter_s>& listConverters) const;
+ am_Error_e getListSinkClasses(std::vector<am_SinkClass_s>& listSinkClasses) const;
+ am_Error_e getListSystemProperties(std::vector<am_SystemProperty_s>& listSystemProperties) const;
+ void setCommandReady();
+ void setCommandRundown();
+ void setRoutingReady();
+ void setRoutingRundown();
+ void confirmControllerReady(const am_Error_e error);
+ void confirmControllerRundown(const am_Error_e error);
+ am_Error_e getSocketHandler(CAmSocketHandler*& socketHandler);
+ void getInterfaceVersion(std::string& version) const;
+ am_Error_e 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) ;
+ am_Error_e 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) ;
+ am_Error_e 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) ;
+ am_Error_e 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);
+ am_Error_e setVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes) ;
+ am_Error_e setSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration) ;
+ am_Error_e setSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration) ;
+ void sendMainSinkNotificationPayload(const am_sinkID_t sinkID, const am_NotificationPayload_s& notificationPayload) ;
+ void sendMainSourceNotificationPayload(const am_sourceID_t sourceID, const am_NotificationPayload_s& notificationPayload) ;
+ am_Error_e changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration) ;
+ am_Error_e changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration) ;
+ am_Error_e getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s>& listSoundproperties) const;
+ am_Error_e getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s>& listSoundproperties) const;
+ am_Error_e getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const;
+ am_Error_e getListSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_SoundProperty_s>& listSoundproperties) const;
+ am_Error_e getMainSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections);
+
+private:
+ IAmDatabaseHandler* mDatabaseHandler; //!< pointer tto the databasehandler
+ CAmRoutingSender* mRoutingSender; //!< pointer to the routing send interface.
+ CAmCommandSender* mCommandSender; //!< pointer to the command send interface
+ CAmSocketHandler* mSocketHandler; //!< pointer to the socketHandler
+ CAmRouter* mRouter; //!< pointer to the Router
+ CAmNodeStateCommunicator* mNodeStateCommunicator;
+};
+
+}
+
+#endif /* CONTRONLRECEIVER_H_ */
diff --git a/AudioManagerCore/include/CAmControlSender.h b/AudioManagerCore/include/CAmControlSender.h
new file mode 100644
index 0000000..40ab379
--- /dev/null
+++ b/AudioManagerCore/include/CAmControlSender.h
@@ -0,0 +1,154 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef CONTROLSENDER_H_
+#define CONTROLSENDER_H_
+
+#ifdef UNIT_TEST
+#include "../test/IAmControlBackdoor.h"
+#endif
+
+#include "IAmControl.h"
+#include "CAmSocketHandler.h"
+#include "unistd.h"
+
+namespace am
+{
+
+/**
+ * sends data to the commandInterface, takes the file of the library that needs to be loaded
+ */
+class CAmControlSender
+{
+public:
+ CAmControlSender(std::string controlPluginFile,CAmSocketHandler* sockethandler);
+ CAmControlSender();
+ ~CAmControlSender();
+ am_Error_e startupController(IAmControlReceive* controlreceiveinterface) ;
+ void setControllerReady() ;
+ void setControllerRundown(const int16_t signal) ;
+ am_Error_e hookUserConnectionRequest(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t& mainConnectionID) ;
+ am_Error_e hookUserDisconnectionRequest(const am_mainConnectionID_t connectionID) ;
+ am_Error_e hookUserSetMainSinkSoundProperty(const am_sinkID_t sinkID, const am_MainSoundProperty_s& soundProperty) ;
+ am_Error_e hookUserSetMainSourceSoundProperty(const am_sourceID_t sourceID, const am_MainSoundProperty_s& soundProperty) ;
+ am_Error_e hookUserSetSystemProperty(const am_SystemProperty_s& property) ;
+ am_Error_e hookUserVolumeChange(const am_sinkID_t SinkID, const am_mainVolume_t newVolume) ;
+ am_Error_e hookUserVolumeStep(const am_sinkID_t SinkID, const int16_t increment) ;
+ am_Error_e hookUserSetSinkMuteState(const am_sinkID_t sinkID, const am_MuteState_e muteState) ;
+ am_Error_e hookSystemRegisterDomain(const am_Domain_s& domainData, am_domainID_t& domainID) ;
+ am_Error_e hookSystemDeregisterDomain(const am_domainID_t domainID) ;
+ void hookSystemDomainRegistrationComplete(const am_domainID_t domainID) ;
+ am_Error_e hookSystemRegisterSink(const am_Sink_s& sinkData, am_sinkID_t& sinkID) ;
+ am_Error_e hookSystemDeregisterSink(const am_sinkID_t sinkID) ;
+ am_Error_e hookSystemRegisterSource(const am_Source_s& sourceData, am_sourceID_t& sourceID) ;
+ am_Error_e hookSystemDeregisterSource(const am_sourceID_t sourceID) ;
+ am_Error_e hookSystemRegisterGateway(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID) ;
+ am_Error_e hookSystemRegisterConverter(const am_Converter_s& converterData, am_converterID_t& converterID);
+ am_Error_e hookSystemDeregisterGateway(const am_gatewayID_t gatewayID) ;
+ am_Error_e hookSystemDeregisterConverter(const am_converterID_t converterID) ;
+ am_Error_e hookSystemRegisterCrossfader(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID) ;
+ am_Error_e hookSystemDeregisterCrossfader(const am_crossfaderID_t crossfaderID) ;
+ void hookSystemSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume) ;
+ void hookSystemSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume) ;
+ void hookSystemInterruptStateChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState) ;
+ void hookSystemSinkAvailablityStateChange(const am_sinkID_t sinkID, const am_Availability_s& availability) ;
+ void hookSystemSourceAvailablityStateChange(const am_sourceID_t sourceID, const am_Availability_s& availability) ;
+ void hookSystemDomainStateChange(const am_domainID_t domainID, const am_DomainState_e state) ;
+ void hookSystemReceiveEarlyData(const std::vector<am_EarlyData_s>& data) ;
+ void hookSystemSpeedChange(const am_speed_t speed) ;
+ void hookSystemTimingInformationChanged(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time) ;
+ void cbAckConnect(const am_Handle_s handle, const am_Error_e errorID) ;
+ void cbAckDisconnect(const am_Handle_s handle, const am_Error_e errorID) ;
+ void cbAckCrossFade(const am_Handle_s handle, const am_HotSink_e hostsink, const am_Error_e error) ;
+ void cbAckSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error) ;
+ void cbAckSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t voulme, const am_Error_e error) ;
+ void cbAckSetSourceState(const am_Handle_s handle, const am_Error_e error) ;
+ void cbAckSetSourceSoundProperties(const am_Handle_s handle, const am_Error_e error) ;
+ void cbAckSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error) ;
+ void cbAckSetSinkSoundProperties(const am_Handle_s handle, const am_Error_e error) ;
+ void cbAckSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error) ;
+ am_Error_e 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) ;
+ void confirmCommandReady(const am_Error_e error) ;
+ void confirmRoutingReady(const am_Error_e error) ;
+ void confirmCommandRundown(const am_Error_e error) ;
+ void confirmRoutingRundown(const am_Error_e error) ;
+ void getInterfaceVersion(std::string& version) const ;
+ am_Error_e 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) ;
+ am_Error_e 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) ;
+ am_Error_e 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) ;
+ am_Error_e 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);
+ void cbAckSetVolume(const am_Handle_s handle, const std::vector<am_Volumes_s>& listVolumes, const am_Error_e error) ;
+ void cbAckSetSinkNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) ;
+ void cbAckSetSourceNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) ;
+ void hookSinkNotificationDataChanged(const am_sinkID_t sinkID, const am_NotificationPayload_s& payload) ;
+ void hookSourceNotificationDataChanged(const am_sourceID_t sourceID, const am_NotificationPayload_s& payload) ;
+ am_Error_e hookUserSetMainSinkNotificationConfiguration(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration) ;
+ am_Error_e hookUserSetMainSourceNotificationConfiguration(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration) ;
+ void hookSystemSingleTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t time);
+
+ void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
+ bool checkerCallback(const sh_pollHandle_t handle, void* userData);
+ bool dispatcherCallback(const sh_pollHandle_t handle, void* userData);
+
+ void setControllerRundownSafe(int16_t signal)
+ {
+ int16_t p(signal);
+ ssize_t result(-1);
+ result = write(mPipe[1], &p, sizeof(p));
+ }
+
+ TAmShPollFired<CAmControlSender> receiverCallbackT;
+ TAmShPollCheck<CAmControlSender> checkerCallbackT;
+ TAmShPollDispatch<CAmControlSender> dispatcherCallbackT;
+
+
+ //we need this here to call the rundown from the signal handler. In case everything screwed up
+ static void CallsetControllerRundown(int16_t signal)
+ {
+ if (mInstance)
+ mInstance->setControllerRundown(signal);
+ }
+
+ //this static callback is used from the signal handler. It is used when a normal rundown is assumed and the mainloop is used to call rundown.
+ static void CallsetControllerRundownSafe(int16_t signal)
+ {
+ if (mInstance)
+ {
+ mInstance->setControllerRundownSafe(signal);
+ }
+ }
+
+#ifdef UNIT_TEST
+ friend class IAmControlBackdoor;
+#endif
+private:
+ int mPipe[2];
+ void* mlibHandle; //!< pointer to the loaded control plugin interface
+ IAmControlSend* mController; //!< pointer to the ControlSend interface
+ static CAmControlSender* mInstance;
+ int16_t mSignal;
+};
+
+}
+
+#endif /* CONTROLSENDER_H_ */
diff --git a/AudioManagerCore/include/CAmDatabaseHandlerMap.h b/AudioManagerCore/include/CAmDatabaseHandlerMap.h
new file mode 100644
index 0000000..cf319f7
--- /dev/null
+++ b/AudioManagerCore/include/CAmDatabaseHandlerMap.h
@@ -0,0 +1,495 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef MAPHANDLER_H_
+#define MAPHANDLER_H_
+
+#include <stdint.h>
+#include <limits.h>
+#include <sstream>
+#include <iostream>
+#include <unordered_map>
+#include <algorithm>
+#include <assert.h>
+#include <vector>
+#include "IAmDatabaseHandler.h"
+
+namespace am
+{
+#ifndef AM_MAP_CAPACITY
+ #define AM_MAP_CAPACITY 0
+#endif
+
+#ifndef AM_MAX_CONNECTIONS
+ #define AM_MAX_CONNECTIONS 0x1000
+#endif
+
+#ifndef AM_MAX_MAIN_CONNECTIONS
+ #define AM_MAX_MAIN_CONNECTIONS SHRT_MAX
+#endif
+
+
+
+//todo: check the enum values before entering & changing in the database.
+//todo: change asserts for dynamic boundary checks into failure answers.#
+//todo: check autoincrement boundary and set to 16bit limits
+//todo: If the sink is part of a gateway, the listconnectionFormats is copied to the gatewayInformation. Check this statement for sinks & sources
+//todo: exchange last_insert_row id to be more safe
+//todo: create test to ensure uniqueness of names throughout the database
+//todo: enforce the uniqueness of names
+
+/**
+ * This class handles and abstracts the database
+ */
+class CAmDatabaseHandlerMap : public IAmDatabaseHandler
+{
+ bool mFirstStaticSink; //!< bool for dynamic range handling
+ bool mFirstStaticSource; //!< bool for dynamic range handling
+ bool mFirstStaticGateway; //!< bool for dynamic range handling
+ bool mFirstStaticConverter; //!< bool for dynamic range handling
+ bool mFirstStaticSinkClass; //!< bool for dynamic range handling
+ bool mFirstStaticSourceClass; //!< bool for dynamic range handling
+ bool mFirstStaticCrossfader; //!< bool for dynamic range handling
+
+public:
+ CAmDatabaseHandlerMap();
+ virtual ~CAmDatabaseHandlerMap();
+ am_Error_e enterDomainDB(const am_Domain_s& domainData, am_domainID_t& domainID);
+ am_Error_e enterMainConnectionDB(const am_MainConnection_s& mainConnectionData, am_mainConnectionID_t& connectionID);
+ am_Error_e enterSinkDB(const am_Sink_s& sinkData, am_sinkID_t& sinkID);
+ am_Error_e enterCrossfaderDB(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID);
+ am_Error_e enterGatewayDB(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID);
+ am_Error_e enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID);
+ am_Error_e enterSourceDB(const am_Source_s& sourceData, am_sourceID_t& sourceID);
+ am_Error_e enterConnectionDB(const am_Connection_s& connection, am_connectionID_t& connectionID);
+ am_Error_e enterSinkClassDB(const am_SinkClass_s& sinkClass, am_sinkClass_t& sinkClassID);
+ am_Error_e enterSourceClassDB(am_sourceClass_t& sourceClassID, const am_SourceClass_s& sourceClass);
+ am_Error_e enterSystemProperties(const std::vector<am_SystemProperty_s>& listSystemProperties);
+ am_Error_e changeMainConnectionRouteDB(const am_mainConnectionID_t mainconnectionID, const std::vector<am_connectionID_t>& listConnectionID);
+ am_Error_e changeMainConnectionStateDB(const am_mainConnectionID_t mainconnectionID, const am_ConnectionState_e connectionState);
+ am_Error_e changeSinkMainVolumeDB(const am_mainVolume_t mainVolume, const am_sinkID_t sinkID);
+ am_Error_e changeSinkAvailabilityDB(const am_Availability_s& availability, const am_sinkID_t sinkID);
+ am_Error_e changDomainStateDB(const am_DomainState_e domainState, const am_domainID_t domainID);
+ am_Error_e changeSinkMuteStateDB(const am_MuteState_e muteState, const am_sinkID_t sinkID);
+ am_Error_e changeMainSinkSoundPropertyDB(const am_MainSoundProperty_s& soundProperty, const am_sinkID_t sinkID);
+ am_Error_e changeMainSourceSoundPropertyDB(const am_MainSoundProperty_s& soundProperty, const am_sourceID_t sourceID);
+ am_Error_e changeSourceSoundPropertyDB(const am_SoundProperty_s& soundProperty, const am_sourceID_t sourceID);
+ am_Error_e changeSinkSoundPropertyDB(const am_SoundProperty_s& soundProperty, const am_sinkID_t sinkID);
+ am_Error_e changeSourceAvailabilityDB(const am_Availability_s& availability, const am_sourceID_t sourceID);
+ am_Error_e changeSystemPropertyDB(const am_SystemProperty_s& property);
+ am_Error_e changeDelayMainConnection(const am_timeSync_t & delay, const am_mainConnectionID_t & connectionID);
+ am_Error_e changeSinkClassInfoDB(const am_SinkClass_s& sinkClass);
+ am_Error_e changeSourceClassInfoDB(const am_SourceClass_s& sourceClass);
+ am_Error_e changeConnectionTimingInformation(const am_connectionID_t connectionID, const am_timeSync_t delay);
+ am_Error_e changeConnectionFinal(const am_connectionID_t connectionID);
+ am_Error_e changeSourceState(const am_sourceID_t sourceID, const am_SourceState_e sourceState);
+ am_Error_e changeSinkVolume(const am_sinkID_t sinkID, const am_volume_t volume);
+ am_Error_e changeSourceVolume(const am_sourceID_t sourceID, const am_volume_t volume);
+ am_Error_e changeCrossFaderHotSink(const am_crossfaderID_t crossfaderID, const am_HotSink_e hotsink);
+ am_Error_e removeMainConnectionDB(const am_mainConnectionID_t mainConnectionID);
+ am_Error_e removeSinkDB(const am_sinkID_t sinkID);
+ am_Error_e removeSourceDB(const am_sourceID_t sourceID);
+ am_Error_e removeGatewayDB(const am_gatewayID_t gatewayID);
+ am_Error_e removeConverterDB(const am_converterID_t converterID);
+ am_Error_e removeCrossfaderDB(const am_crossfaderID_t crossfaderID);
+ am_Error_e removeDomainDB(const am_domainID_t domainID);
+ am_Error_e removeSinkClassDB(const am_sinkClass_t sinkClassID);
+ am_Error_e removeSourceClassDB(const am_sourceClass_t sourceClassID);
+ am_Error_e removeConnection(const am_connectionID_t connectionID);
+ am_Error_e getSourceClassInfoDB(const am_sourceID_t sourceID, am_SourceClass_s& classInfo) const;
+ am_Error_e getSinkClassInfoDB(const am_sinkID_t sinkID, am_SinkClass_s& sinkClass) const;
+ am_Error_e getGatewayInfoDB(const am_gatewayID_t gatewayID, am_Gateway_s& gatewayData) const;
+ am_Error_e getConverterInfoDB(const am_converterID_t converterID, am_Converter_s& converterData) const;
+ am_Error_e getSinkInfoDB(const am_sinkID_t sinkID, am_Sink_s& sinkData) const;
+ am_Error_e getSourceInfoDB(const am_sourceID_t sourceID, am_Source_s& sourceData) const;
+ am_Error_e getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s& crossfaderData) const;
+ am_Error_e getMainConnectionInfoDB(const am_mainConnectionID_t mainConnectionID, am_MainConnection_s& mainConnectionData) const;
+ am_Error_e getSinkMainVolume(const am_sinkID_t sinkID, am_mainVolume_t& mainVolume) const;
+ am_Error_e getSinkVolume(const am_sinkID_t sinkID, am_volume_t& volume) const;
+ am_Error_e getSourceVolume(const am_sourceID_t sourceID, am_volume_t& volume) const;
+ am_Error_e getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getMainSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const;
+ am_Error_e getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const;
+ am_Error_e getListSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_SoundProperty_s>& listSoundproperties) const;
+ am_Error_e getListSinksOfDomain(const am_domainID_t domainID, std::vector<am_sinkID_t>& listSinkID) const;
+ am_Error_e getListSourcesOfDomain(const am_domainID_t domainID, std::vector<am_sourceID_t>& listSourceID) const;
+ am_Error_e getListCrossfadersOfDomain(const am_domainID_t domainID, std::vector<am_crossfaderID_t>& listGatewaysID) const;
+ am_Error_e getListGatewaysOfDomain(const am_domainID_t domainID, std::vector<am_gatewayID_t>& listGatewaysID) const;
+ am_Error_e getListConvertersOfDomain(const am_domainID_t domainID, std::vector<am_converterID_t>& listConvertersID) const;
+ am_Error_e getListMainConnections(std::vector<am_MainConnection_s>& listMainConnections) const;
+ am_Error_e getListDomains(std::vector<am_Domain_s>& listDomains) const;
+ am_Error_e getListConnections(std::vector<am_Connection_s>& listConnections) const;
+ am_Error_e getListSinks(std::vector<am_Sink_s>& listSinks) const;
+ am_Error_e getListSources(std::vector<am_Source_s>& lisSources) const;
+ am_Error_e getListSourceClasses(std::vector<am_SourceClass_s>& listSourceClasses) const;
+ am_Error_e getListCrossfaders(std::vector<am_Crossfader_s>& listCrossfaders) const;
+ am_Error_e getListGateways(std::vector<am_Gateway_s>& listGateways) const;
+ am_Error_e getListConverters(std::vector<am_Converter_s> & listConverters) const;
+ am_Error_e getListSinkClasses(std::vector<am_SinkClass_s>& listSinkClasses) const;
+ am_Error_e getListVisibleMainConnections(std::vector<am_MainConnectionType_s>& listConnections) const;
+ am_Error_e getListMainSinks(std::vector<am_SinkType_s>& listMainSinks) const;
+ am_Error_e getListMainSources(std::vector<am_SourceType_s>& listMainSources) const;
+ am_Error_e getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s>& listSoundProperties) const;
+ am_Error_e getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s>& listSourceProperties) const;
+ am_Error_e getListSystemProperties(std::vector<am_SystemProperty_s>& listSystemProperties) const;
+ am_Error_e getListSinkConnectionFormats(const am_sinkID_t sinkID, std::vector<am_CustomAvailabilityReason_t> & listConnectionFormats) const;
+ am_Error_e getListSourceConnectionFormats(const am_sourceID_t sourceID, std::vector<am_CustomAvailabilityReason_t> & listConnectionFormats) const;
+ am_Error_e getListGatewayConnectionFormats(const am_gatewayID_t gatewayID, std::vector<bool> & listConnectionFormat) const;
+ am_Error_e getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t& delay) const;
+ am_Error_e getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t& domainID) const;
+ am_Error_e getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t& domainID) const;
+ am_Error_e getDomainOfCrossfader(const am_converterID_t crossfader, am_domainID_t& domainID) const;
+ am_Error_e getSoureState(const am_sourceID_t sourceID, am_SourceState_e& sourceState) const;
+ am_Error_e getDomainState(const am_domainID_t domainID, am_DomainState_e& state) const;
+ am_Error_e peekDomain(const std::string& name, am_domainID_t& domainID);
+ am_Error_e peekSink(const std::string& name, am_sinkID_t& sinkID);
+ am_Error_e peekSource(const std::string& name, am_sourceID_t& sourceID);
+ am_Error_e peekSinkClassID(const std::string& name, am_sinkClass_t& sinkClassID);
+ am_Error_e peekSourceClassID(const std::string& name, am_sourceClass_t& sourceClassID);
+ am_Error_e changeSourceDB(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomAvailabilityReason_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties);
+ am_Error_e changeSinkDB(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomAvailabilityReason_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties);
+ am_Error_e getListMainSinkNotificationConfigurations(const am_sinkID_t sinkID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations);
+ am_Error_e getListMainSourceNotificationConfigurations(const am_sourceID_t sourceID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations);
+ am_Error_e changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration);
+ am_Error_e changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration);
+ am_Error_e changeGatewayDB(const am_gatewayID_t gatewayID, const std::vector<am_CustomAvailabilityReason_t>& listSourceConnectionFormats, const std::vector<am_CustomAvailabilityReason_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix);
+ am_Error_e 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);
+ am_Error_e changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID,const am_NotificationConfiguration_s notificationConfiguration);
+ am_Error_e changeSourceNotificationConfigurationDB(const am_sourceID_t sourceID,const am_NotificationConfiguration_s notificationConfiguration);
+
+ bool existMainConnection(const am_mainConnectionID_t mainConnectionID) const;
+ bool existCrossFader(const am_crossfaderID_t crossfaderID) const;
+ bool existConnection(const am_Connection_s & connection) const;
+ bool existConnectionID(const am_connectionID_t connectionID) const;
+ bool existSource(const am_sourceID_t sourceID) const;
+ bool existSourceNameOrID(const am_sourceID_t sourceID, const std::string& name) const;
+ bool existSourceName(const std::string& name) const;
+ bool existSink(const am_sinkID_t sinkID) const;
+ bool existSinkNameOrID(const am_sinkID_t sinkID, const std::string& name) const;
+ bool existSinkName(const std::string& name) const;
+ bool existDomain(const am_domainID_t domainID) const;
+ bool existGateway(const am_gatewayID_t gatewayID) const;
+ bool existConverter(const am_converterID_t converterID) const;
+ bool existSinkClass(const am_sinkClass_t sinkClassID) const;
+ bool existSourceClass(const am_sourceClass_t sourceClassID) const;
+ void registerObserver(CAmDatabaseObserver *iObserver);
+ bool sourceVisible(const am_sourceID_t sourceID) const;
+ bool sinkVisible(const am_sinkID_t sinkID) const;
+ bool isComponentConnected(const am_Gateway_s & gateway) const;
+ bool isComponentConnected(const am_Converter_s & converter) const;
+ void dump( std::ostream & output ) const;
+ am_Error_e enumerateSources(std::function<void(const am_Source_s & element)> cb) const;
+ am_Error_e enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const;
+ am_Error_e enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const;
+ am_Error_e enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const;
+ /**
+ * The following structures extend the base structures with the field 'reserved'.
+ */
+
+#define AM_SUBCLASS_BEGIN(Subclass, Class) \
+ typedef struct Subclass : public Class\
+ {
+
+#define AM_SUBCLASS_CONSTR(Subclass, Class) \
+ Subclass():Class()
+
+#define AM_SUBCLASS_CONSTR_BODY()\
+ {};
+
+#define AM_SUBCLASS_COPY_OP_START(Subclass, Class) \
+ Subclass & operator=(const Subclass & anObject)\
+ {\
+ if (this != &anObject)\
+ {\
+ Class::operator=(anObject);
+
+#define AM_SUBCLASS_COPY_OP_END()\
+ }\
+ return *this;\
+ };
+
+#define AM_SUBCLASS_OP(Subclass, Class) \
+ Subclass & operator=(const Class & anObject)\
+ {\
+ if (this != &anObject)\
+ Class::operator=(anObject);\
+ return *this;\
+ };
+
+#define AM_SUBCLASS_END(Typedef) \
+ void getDescription (std::string & outString) const;\
+ } Typedef;
+
+#define AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(Subclass, Class)\
+ AM_SUBCLASS_BEGIN(Subclass, Class)\
+ bool reserved;\
+ AM_SUBCLASS_CONSTR(Subclass, Class)\
+ ,reserved(false)\
+ AM_SUBCLASS_CONSTR_BODY()\
+ AM_SUBCLASS_COPY_OP_START(Subclass, Class)\
+ reserved = anObject.reserved;\
+ AM_SUBCLASS_COPY_OP_END()\
+ AM_SUBCLASS_OP(Subclass, Class)\
+
+#define AM_TYPEDEF_SUBCLASS_SOUND_PROPERTIES_BEGIN(Subclass, Class)\
+ AM_SUBCLASS_BEGIN(Subclass, Class)\
+ bool reserved;\
+ std::unordered_map<am_CustomSoundPropertyType_t, int16_t> cacheSoundProperties;\
+ std::unordered_map<am_CustomMainSoundPropertyType_t, int16_t> cacheMainSoundProperties;\
+ AM_SUBCLASS_CONSTR(Subclass, Class)\
+ ,reserved(false), cacheSoundProperties(), cacheMainSoundProperties()\
+ AM_SUBCLASS_CONSTR_BODY()\
+ AM_SUBCLASS_COPY_OP_START(Subclass, Class)\
+ reserved = anObject.reserved;\
+ cacheSoundProperties = anObject.cacheSoundProperties;\
+ cacheMainSoundProperties = anObject.cacheMainSoundProperties;\
+ AM_SUBCLASS_COPY_OP_END()\
+ AM_SUBCLASS_OP(Subclass, Class)\
+
+#define AM_TYPEDEF_SUBCLASS_BEGIN(Subclass, Class)\
+ AM_SUBCLASS_BEGIN(Subclass, Class)\
+ AM_SUBCLASS_COPY_OP_START(Subclass, Class)\
+ AM_SUBCLASS_COPY_OP_END()\
+ AM_SUBCLASS_OP(Subclass, Class)\
+
+
+ AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Domain_Database_s,am_Domain_s)
+ AM_SUBCLASS_END(CAmDomain)
+
+ AM_TYPEDEF_SUBCLASS_SOUND_PROPERTIES_BEGIN(am_Sink_Database_s,am_Sink_s)
+ void getSinkType(am_SinkType_s & sinkType) const;\
+ AM_SUBCLASS_END(CAmSink)
+
+ AM_TYPEDEF_SUBCLASS_SOUND_PROPERTIES_BEGIN(am_Source_Database_s,am_Source_s)
+ void getSourceType(am_SourceType_s & sourceType) const;\
+ AM_SUBCLASS_END(CAmSource)
+
+ AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Connection_Database_s,am_Connection_s)
+ AM_SUBCLASS_END(CAmConnection)
+
+ /**
+ * The following structures extend the base structures with print capabilities.
+ */
+ AM_TYPEDEF_SUBCLASS_BEGIN(am_MainConnection_Database_s, am_MainConnection_s)
+ void getMainConnectionType(am_MainConnectionType_s & connectionType) const;\
+ AM_SUBCLASS_END(CAmMainConnection)
+
+ AM_TYPEDEF_SUBCLASS_BEGIN(am_SourceClass_Database_s, am_SourceClass_s)
+ AM_SUBCLASS_END(CAmSourceClass)
+
+ AM_TYPEDEF_SUBCLASS_BEGIN(am_SinkClass_Database_s, am_SinkClass_s)
+ AM_SUBCLASS_END(CAmSinkClass)
+
+ AM_TYPEDEF_SUBCLASS_BEGIN(am_Gateway_Database_s, am_Gateway_s)
+ AM_SUBCLASS_END(CAmGateway)
+
+ AM_TYPEDEF_SUBCLASS_BEGIN(am_Converter_Database_s, am_Converter_s)
+ AM_SUBCLASS_END(CAmConverter)
+
+ AM_TYPEDEF_SUBCLASS_BEGIN(am_Crossfader_Database_s, am_Crossfader_s)
+ AM_SUBCLASS_END(CAmCrossfader)
+
+ private:
+ typedef std::unordered_map<am_domainID_t, CAmDomain> CAmMapDomain;
+ typedef std::unordered_map<am_sourceClass_t, CAmSourceClass> CAmMapSourceClass;
+ typedef std::unordered_map<am_sinkClass_t, CAmSinkClass> CAmMapSinkClass;
+ typedef std::unordered_map<am_sinkID_t, CAmSink> CAmMapSink;
+ typedef std::unordered_map<am_sourceID_t, CAmSource> CAmMapSource;
+ typedef std::unordered_map<am_gatewayID_t, CAmGateway> CAmMapGateway;
+ typedef std::unordered_map<am_converterID_t, CAmConverter> CAmMapConverter;
+ typedef std::unordered_map<am_crossfaderID_t, CAmCrossfader> CAmMapCrossfader;
+ typedef std::unordered_map<am_connectionID_t, CAmConnection> CAmMapConnection;
+ typedef std::unordered_map<am_mainConnectionID_t, CAmMainConnection> CAmMapMainConnection;
+ typedef std::vector<am_SystemProperty_s> CAmVectorSystemProperties;
+ /**
+ * The following structure groups the map objects needed for the implementation.
+ * Every map object is coupled with an identifier, which hold the current value.
+ * DYNAMIC_ID_BOUNDARY is used as initial value everywhere a dynamic id is considered .
+ * The IDs can be increased through the method increaseID(...), which follows the AudioManager logic.
+ * For more information about the static and dynamic IDs, please see the documentation.
+ */
+ typedef struct CAmMappedData
+ {
+ /**
+ * The structure encapsulates the id boundary and the current id value.
+ * It defines a range within the id can vary.
+ */
+ struct am_Identifier_s
+ {
+ int16_t mMin; //!< min possible value
+ int16_t mMax; //!< max possible value
+ int16_t mCurrentValue; //!< current value
+
+ am_Identifier_s():mMin(DYNAMIC_ID_BOUNDARY), mMax(SHRT_MAX), mCurrentValue(mMin){};
+ am_Identifier_s(const int16_t & min, const int16_t & max):mMin(min), mMax(max), mCurrentValue(mMin){assert(min<max);};
+ };
+
+ am_Identifier_s mCurrentDomainID; //!< domain ID
+ am_Identifier_s mCurrentSourceClassesID; //!< source classes ID
+ am_Identifier_s mCurrentSinkClassesID; //!< sink classes ID
+ am_Identifier_s mCurrentSinkID; //!< sink ID
+ am_Identifier_s mCurrentSourceID; //!< source ID
+ am_Identifier_s mCurrentGatewayID; //!< gateway ID
+ am_Identifier_s mCurrentConverterID; //!< converter ID
+ am_Identifier_s mCurrentCrossfaderID; //!< crossfader ID
+ am_Identifier_s mCurrentConnectionID; //!< connection ID
+ am_Identifier_s mCurrentMainConnectionID; //!< mainconnection ID
+
+ CAmVectorSystemProperties mSystemProperties; //!< vector with system properties
+ CAmMapDomain mDomainMap; //!< map for domain structures
+ CAmMapSourceClass mSourceClassesMap; //!< map for source classes structures
+ CAmMapSinkClass mSinkClassesMap; //!< map for sink classes structures
+ CAmMapSink mSinkMap; //!< map for sink structures
+ CAmMapSource mSourceMap; //!< map for source structures
+ CAmMapGateway mGatewayMap; //!< map for gateway structures
+ CAmMapConverter mConverterMap; //!< map for converter structures
+ CAmMapCrossfader mCrossfaderMap; //!< map for crossfader structures
+ CAmMapConnection mConnectionMap; //!< map for connection structures
+ CAmMapMainConnection mMainConnectionMap; //!< map for main connection structures
+
+ CAmMappedData(): //For Domain, MainConnections, Connections we don't have static IDs.
+ mCurrentDomainID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentSourceClassesID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentSinkClassesID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentSinkID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentSourceID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentGatewayID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentConverterID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentCrossfaderID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
+ mCurrentConnectionID(1, AM_MAX_CONNECTIONS),
+ mCurrentMainConnectionID(1, AM_MAX_MAIN_CONNECTIONS),
+
+ mSystemProperties(),
+ mDomainMap(),mSourceClassesMap(), mSinkClassesMap(), mSinkMap(AM_MAP_CAPACITY), mSourceMap(AM_MAP_CAPACITY),
+ mGatewayMap(), mConverterMap(), mCrossfaderMap(), mConnectionMap(), mMainConnectionMap()
+ {};
+ /**
+ * \brief Increases a given map ID.
+ *
+ * A common method implementing the logic for static and dynamic IDs except main connection ID.
+ *
+ * @param resultID Pointer to an output variable.
+ * @param sourceID Pointer to ID, which will be manipulated.
+ * @param desiredStaticID Not 0 for static IDs and 0 for dynamic IDs.
+ * Usually the static IDs are in interval [1 , DYNAMIC_ID_BOUNDARY]. Default is 0.
+ * @param preferedStaticIDBoundary A limit for a given dynamic ID. Default is DYNAMIC_ID_BOUNDARY.
+ * @return TRUE on successfully changed ID.
+ */
+ bool increaseID(int16_t & resultID, am_Identifier_s & sourceID, int16_t const desiredStaticID);
+ /**
+ * \brief Increases the main connection ID.
+ *
+ * @param resultID Pointer to an output variable.
+ * @return TRUE on successfully changed ID.
+ */
+ bool increaseMainConnectionID(int16_t & resultID);
+
+ /**
+ * \brief Increases the connection ID.
+ *
+ * @param resultID Pointer to an output variable.
+ * @return TRUE on successfully changed ID.
+ */
+ bool increaseConnectionID(int16_t & resultID);
+
+ template <class TPrintObject> static void print (const TPrintObject & t, std::ostream & output)
+ {
+ std::string description;
+ t.getDescription( description );
+ output << description;
+ }
+ template <typename TPrintMapKey,class TPrintMapObject> static void printMap (const std::unordered_map<TPrintMapKey, TPrintMapObject> & t, std::ostream & output)
+ {
+ typename std::unordered_map<TPrintMapKey, TPrintMapObject>::const_iterator iter = t.begin();
+ for(; iter!=t.end(); iter++)
+ CAmMappedData::print(iter->second, output);
+ }
+ private:
+ template <typename TMapKey,class TMapObject> bool getNextConnectionID(int16_t & resultID, am_Identifier_s & sourceID,
+ const std::unordered_map<TMapKey, TMapObject> & map);
+ } CAmMappedData;
+ /*
+ * Helper methods.
+ */
+ am_timeSync_t calculateMainConnectionDelay(const am_mainConnectionID_t mainConnectionID) const; //!< calculates a new main connection delay
+ int16_t calculateDelayForRoute(const std::vector<am_connectionID_t>& listConnectionID);
+ bool insertSinkDB(const am_Sink_s & sinkData, am_sinkID_t & sinkID);
+ bool insertCrossfaderDB(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID);
+ bool insertGatewayDB(const am_Gateway_s & gatewayData, am_gatewayID_t & gatewayID);
+ bool insertConverterDB(const am_Converter_s & converteData, am_converterID_t & converterID);
+ bool insertSourceDB(const am_Source_s & sourceData, am_sourceID_t & sourceID);
+ bool insertSinkClassDB(const am_SinkClass_s & sinkClass, am_sinkClass_t & sinkClassID);
+ bool insertSourceClassDB(am_sourceClass_t & sourceClassID, const am_SourceClass_s & sourceClass);
+ const am_Sink_Database_s * sinkWithNameOrID(const am_sinkID_t sinkID, const std::string & name) const;
+ const am_Source_Database_s * sourceWithNameOrID(const am_sourceID_t sourceID, const std::string & name) const;
+ template <class Component> bool isConnected(const Component & comp) const
+ {
+ return std::find_if(mMappedData.mConnectionMap.begin(), mMappedData.mConnectionMap.end(),[&](const std::pair<am_connectionID_t, am_Connection_Database_s>& rConnection){
+ return (rConnection.second.sinkID == comp.sinkID ||rConnection.second.sourceID ==comp.sourceID);})!=mMappedData.mConnectionMap.end();
+ }
+ void filterDuplicateNotificationConfigurationTypes(std::vector<am_NotificationConfiguration_s> & list)
+ {
+ std::vector<am_NotificationConfiguration_s> oldList(list);
+ list.clear();
+ std::for_each(oldList.begin(), oldList.end(), [&](am_NotificationConfiguration_s & provided) {
+ std::vector<am_NotificationConfiguration_s>::iterator found =
+ std::find_if(list.begin(), list.end(), [&](am_NotificationConfiguration_s & stored) {
+ if (provided.type == stored.type) {
+ stored = provided;
+ return true;
+ }
+ return false;
+ } );
+ if (found == list.end())
+ list.push_back(provided);
+ } );
+ }
+
+ CAmDatabaseObserver *mpDatabaseObserver; //!< pointer to the Observer
+ ListConnectionFormat mListConnectionFormat; //!< list of connection formats
+ CAmMappedData mMappedData; //!< Internal structure encapsulating all the maps used in this class
+#ifdef UNIT_TEST
+ public:
+ void setConnectionIDRange(const int16_t & min, const int16_t & max)
+ {
+ mMappedData.mCurrentConnectionID.mMin = min;
+ mMappedData.mCurrentConnectionID.mMax = max;
+ }
+ void setMainConnectionIDRange(const int16_t & min, const int16_t & max)
+ {
+ mMappedData.mCurrentMainConnectionID.mMin = min;
+ mMappedData.mCurrentMainConnectionID.mMax = max;
+ }
+ void setSinkIDRange(const int16_t & min, const int16_t & max)
+ {
+ mMappedData.mCurrentSinkID.mMin = min;
+ mMappedData.mCurrentSinkID.mMax = max;
+ }
+#endif
+};
+
+}
+
+#endif /* MAPHANDLER_H_ */
diff --git a/AudioManagerCore/include/CAmDatabaseObserver.h b/AudioManagerCore/include/CAmDatabaseObserver.h
new file mode 100644
index 0000000..7d18be4
--- /dev/null
+++ b/AudioManagerCore/include/CAmDatabaseObserver.h
@@ -0,0 +1,87 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef DATABASEOBSERVER_H_
+#define DATABASEOBSERVER_H_
+
+#include "audiomanagertypes.h"
+#include <queue>
+#include "CAmSerializer.h"
+
+namespace am
+{
+
+class CAmTelnetServer;
+class CAmCommandSender;
+class CAmRoutingSender;
+class CAmSocketHandler;
+
+/**
+ * This class observes the Database and notifies other classes about important events, mainly the CommandSender.
+ */
+class CAmDatabaseObserver
+{
+public:
+ CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler);
+ CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler, CAmTelnetServer *iTelnetServer);
+ ~CAmDatabaseObserver();
+ void numberOfSinkClassesChanged();
+ void numberOfSourceClassesChanged();
+ void newSink(const am_Sink_s& sink);
+ void newSource(const am_Source_s& source);
+ void newDomain(const am_Domain_s& domain);
+ void newGateway(const am_Gateway_s& gateway);
+ void newConverter(const am_Converter_s& coverter);
+ void newCrossfader(const am_Crossfader_s& crossfader);
+ void newMainConnection(const am_MainConnectionType_s& mainConnection);
+ void removedMainConnection(const am_mainConnectionID_t mainConnection);
+ void removedSink(const am_sinkID_t sinkID, const bool visible);
+ void removedSource(const am_sourceID_t sourceID, const bool visible);
+ void removeDomain(const am_domainID_t domainID);
+ void removeGateway(const am_gatewayID_t gatewayID);
+ void removeConverter(const am_converterID_t converterID);
+ void removeCrossfader(const am_crossfaderID_t crossfaderID);
+ void mainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState);
+ void mainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty);
+ void mainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty);
+ void sinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s& availability);
+ void sourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s& availability);
+ void volumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume);
+ void sinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState);
+ void systemPropertyChanged(const am_SystemProperty_s& SystemProperty);
+ void timingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time);
+ void sinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible);
+ void sourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible);
+ void sinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration);
+ void sourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration);
+
+private:
+ CAmCommandSender *mCommandSender; //!< pointer to the comandSender
+ CAmRoutingSender* mRoutingSender; //!< pointer to the routingSender
+ CAmTelnetServer* mTelnetServer; //!< pointer to the telnetserver
+ CAmSerializer mSerializer; //!< serializer to handle the CommandInterface via the mainloop
+};
+
+}
+
+#endif /* DATABASEOBSERVER_H_ */
diff --git a/AudioManagerCore/include/CAmGraph.h b/AudioManagerCore/include/CAmGraph.h
new file mode 100644
index 0000000..ff4a09c
--- /dev/null
+++ b/AudioManagerCore/include/CAmGraph.h
@@ -0,0 +1,630 @@
+/**
+ * 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 2014
+ *
+ * \file CAmGraph.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include <functional>
+#include <iostream>
+#include <vector>
+#include <map>
+#include <list>
+#include <stack>
+#include <queue>
+#include <algorithm>
+#include <limits.h>
+#include <iomanip>
+#include <cstring>
+#include <set>
+
+
+namespace am
+{
+ /**
+ * Graph element status.
+ */
+ typedef enum:uint8_t
+ {
+ GES_NOT_VISITED,
+ GES_IN_PROGRESS,
+ GES_VISITED
+ }am_GraphElementStatus_e;
+
+ /**
+ * Callback parameter telling on which position in the path we are.
+ */
+ typedef enum:uint8_t
+ {
+ GRAPH_PATH_START, //at the beginning of the path
+ GRAPH_PATH_MIDDLE, //in middle of the path
+ GRAPH_PATH_END //at the end of the path
+ }am_GraphPathPosition_e;
+
+
+ /**
+ * This class is base class for nodes and vertices.
+ */
+ class CAmGraphElement
+ {
+ am_GraphElementStatus_e mStatus; //!< item status
+ public:
+ CAmGraphElement(): mStatus(GES_NOT_VISITED) { };
+ ~CAmGraphElement() { };
+ /**
+ * Setter and getter.
+ */
+ void setStatus(const am_GraphElementStatus_e s) { mStatus = s; };
+ am_GraphElementStatus_e getStatus() const { return mStatus; };
+ };
+
+ template <class NodeData> class CAmNode : public CAmGraphElement
+ {
+ uint16_t mIndex; //!< uint16_t index used for direct access
+ NodeData mData; //!< NodeData user data
+ public:
+ CAmNode(const NodeData & in):CAmGraphElement(), mIndex(0), mData(in) { };
+ CAmNode(const NodeData & in, const uint16_t index):CAmGraphElement(), mIndex(index), mData(in) { };
+ ~CAmNode() { };
+ /**
+ * Setters and getters.
+ */
+ NodeData & getData() { return mData; }
+ uint16_t getIndex() const { return mIndex; }
+ void setIndex(uint16_t index) { mIndex = index; }
+ };
+
+ template <class NodeData, class VertexData> class CAmVertex : public CAmGraphElement
+ {
+ CAmNode<NodeData>* mpNode; //!< CAmNode<NodeData>* pointer to a node
+ VertexData mVertexData; //!< VertexData vertex user data
+ uint16_t mWeight; //!< uint16_t a positive value used in the shortest path algorithms
+ public:
+ CAmVertex(CAmNode<NodeData> *aNode, const VertexData & vertexData, const uint16_t weight):CAmGraphElement(),
+ mpNode(aNode), mVertexData(vertexData), mWeight(weight) { };
+ ~CAmVertex() { };
+ /**
+ * Setters and getters.
+ */
+ CAmNode<NodeData>* getNode() const { return mpNode; }
+ VertexData & getData() { return mVertexData; }
+ uint16_t getWeight() const { return mWeight; }
+ void setWeight(const uint16_t weight) { mWeight=weight; }
+ };
+
+ /**
+ * Class representing a directed or undirected graph. It contains nodes and connections.
+ * T, V are types for custom user data.
+ */
+ template <class T, class V> class CAmGraph
+ {
+ typedef typename std::vector<CAmNode<T>*> CAmListNodePtrs;
+ typedef typename std::list<CAmVertex<T,V>> CAmListVertices;
+ typedef typename std::list<CAmVertex<T,V>>::iterator CAmListVerticesItr;
+ typedef typename std::list<CAmVertex<T,V>>::const_iterator CAmListVerticesItrConst;
+ typedef typename std::list<CAmListVertices> CAmNodesAdjList;
+ typedef typename std::list<CAmListVertices>::iterator CAmNodesAdjListItr;
+ typedef typename std::list<CAmListVertices>::const_iterator CAmNodesAdjListItrConst;
+ typedef typename std::list<CAmNode<T>> CAmListNodes;
+ typedef typename std::list<CAmNode<T>>::iterator CAmListNodesItr;
+ typedef typename std::list<CAmNode<T>>::const_iterator CAmListNodesItrConst;
+ typedef typename std::vector<CAmNode<T>*> CAmNodeReferenceList;
+ typedef typename std::vector<CAmListVertices*> CAmVertexReferenceList;
+
+ CAmListNodes mStoreNodes; //!< CAmListNodes list with all nodes
+ CAmNodesAdjList mStoreAdjList; //!< CAmNodesAdjList adjacency list
+ CAmNodeReferenceList mPointersNodes; //!< CAmNodeReferenceList vector with pointers to nodes for direct access
+ CAmVertexReferenceList mPointersAdjList; //!< CAmVertexReferenceList vector with pointers to vertices for direct access
+ bool mIsCyclic; //!< bool the graph has cycles or not
+
+ /**
+ * Updates the node indexes after adding or removing nodes.
+ *
+ * @param fromIndex updates all nodes from given index.
+ */
+ void updateIndexes(const int16_t fromIndex)
+ {
+ if( fromIndex<mPointersNodes.size() )
+ {
+ for(auto iter = mPointersNodes.begin()+fromIndex; iter!=mPointersNodes.end(); iter++)
+ (*iter)->setIndex(iter-mPointersNodes.begin());
+ }
+ }
+
+
+ /**
+ * Finds the shortest path and the minimal weights from given node.
+ *
+ * @param node start node.
+ * @param minDistance vector with all result distances.
+ * @param previous vector with previous nodes.
+ */
+
+ typedef uint16_t vertex_t;
+ typedef uint16_t weight_t;
+
+ void findShortestsPathsFromNode(const CAmNode<T> & node, std::vector<weight_t> &minDistance, std::vector<CAmNode<T> *> &previous)
+ {
+ typename CAmListVertices::const_iterator nIter;
+ CAmListVertices * neighbors;
+ weight_t dist, weight, v, distanceThroughU;
+ CAmNode<T>* pU;
+ CAmVertex<T,V> * pVertex;
+ CAmNode<T> *pDstNode;
+
+ size_t n = mPointersAdjList.size();
+ std::set<std::pair<weight_t, CAmNode<T>*> > vertexQueue;
+
+ minDistance.clear();
+ minDistance.resize(n, std::numeric_limits<weight_t>::max());
+ minDistance[node.getIndex()] = 0;
+ previous.clear();
+ previous.resize(n, NULL);
+
+ vertexQueue.insert(std::make_pair(minDistance[node.getIndex()], (CAmNode<T>*)&node));
+
+ while (!vertexQueue.empty())
+ {
+ dist = vertexQueue.begin()->first;
+ pU = vertexQueue.begin()->second;
+ vertexQueue.erase(vertexQueue.begin());
+ //todo: terminate the search at this position if you want the path to a target node ( if(pU==target)break; )
+
+ // Visit each edge exiting u
+ neighbors = mPointersAdjList[pU->getIndex()];
+ nIter = neighbors->begin();
+ for (; nIter != neighbors->end(); nIter++)
+ {
+ pVertex = (CAmVertex<T,V> *)&(*nIter);
+ pDstNode = pVertex->getNode();
+
+ v = pDstNode->getIndex();
+ weight = pVertex->getWeight();
+ distanceThroughU = dist + weight;
+ if (distanceThroughU < minDistance[pDstNode->getIndex()])
+ {
+ vertexQueue.erase(std::make_pair(minDistance[v], pDstNode));
+ minDistance[v] = distanceThroughU;
+ previous[v] = pU;
+ vertexQueue.insert(std::make_pair(minDistance[v], pDstNode));
+ }
+ }
+ }
+ }
+
+ /**
+ * Constructs a path to given node after findShortestsPathsFromNode has been called.
+ *
+ * @param node end node.
+ * @param previous vector with previous nodes.
+ * @param result result path.
+ */
+ void constructShortestPathTo(const CAmNode<T> & node, const std::vector<CAmNode<T> *> &previous, CAmListNodePtrs & result)
+ {
+ CAmNode<T> * vertex = (CAmNode<T> *)&node;
+
+ int i=0;
+ while ( (vertex = previous[vertex->getIndex()])!=NULL )
+ {
+ result.insert(result.begin(), vertex);
+ i++;
+ }
+ if(i)
+ result.push_back((CAmNode<T> *)&node);
+ }
+
+ /**
+ * Calls a function with every node from this path after findShortestsPathsFromNode has been called.
+ * The construction of the path is delegated to the caller.
+ *
+ * @param node end node.
+ * @param previous vector with previous nodes.
+ * @param cb callback which is mostly used for constructing.
+ */
+ void constructShortestPathTo(const CAmNode<T> & node, const std::vector<CAmNode<T> *> &previous, std::function<void(const am_GraphPathPosition_e pos, CAmNode<T> &)> cb)
+ {
+ CAmNode<T> * vertex = (CAmNode<T> *)&node;
+ CAmNode<T> * prev = vertex;
+ int i=0;
+ while ( (vertex = previous[vertex->getIndex()])!=NULL )
+ {
+ cb(i==0?GRAPH_PATH_START:GRAPH_PATH_MIDDLE, *prev);
+ prev = vertex;
+ i++;
+ }
+ if(i)
+ cb(GRAPH_PATH_END, *prev);
+ }
+
+ /**
+ * Generates list with all possible paths to given destination node after findShortestsPathsFromNode has been called.
+ * Finding paths is observed through the callback. The caller is informed after a new path has been found.
+ *
+ * @param dst end node.
+ * @param visited vector with current path.
+ * @param cb callback which is mostly used for constructing.
+ */
+ void goThroughAllPaths(const CAmNode<T> & dst, std::vector<CAmNode<T>*> & visited, std::function<void(const CAmNodeReferenceList & path)> cb)
+ {
+ CAmListVertices * nodes = mPointersAdjList[visited.back()->getIndex()];
+ CAmListVerticesItrConst vItr(nodes->begin());
+ for (; vItr != nodes->end(); ++vItr)
+ {
+ const CAmVertex<T,V> & vertex = (*vItr);
+ if(vertex.getNode()->getStatus()!=GES_NOT_VISITED)
+ continue;
+ if (vertex.getNode()==&dst)
+ {
+ vertex.getNode()->setStatus(GES_IN_PROGRESS);
+ visited.push_back(vertex.getNode());
+ //notify observer
+ cb(visited);
+ //remove last node from the list
+ auto last = visited.end()-1;
+ visited.erase(last);
+ vertex.getNode()->setStatus(GES_NOT_VISITED);
+ break;
+ }
+ }
+ vItr = nodes->begin();
+ //bfs like loop
+ for (; vItr != nodes->end(); ++vItr)
+ {
+ const CAmVertex<T,V> & vertex = (*vItr);
+ if(vertex.getNode()->getStatus()!=GES_NOT_VISITED||vertex.getNode()==&dst)
+ continue;
+ vertex.getNode()->setStatus(GES_IN_PROGRESS);
+ visited.push_back(vertex.getNode());
+ goThroughAllPaths(dst, visited, cb);
+ //remove last node from the list
+ auto last = visited.end()-1;
+ visited.erase(last);
+ vertex.getNode()->setStatus(GES_NOT_VISITED);
+ }
+ }
+
+ public:
+ explicit CAmGraph(const std::vector<T> &v):mStoreNodes(), mStoreAdjList(), mPointersNodes(), mPointersAdjList()
+ {
+ typedef typename std::vector<T>::const_iterator inItr;
+ inItr itr(v.begin());
+
+ for (; itr != v.end(); ++itr)
+ {
+ addNode(*itr);
+ }
+
+ mIsCyclic = false;
+ };
+ CAmGraph():mStoreNodes(), mStoreAdjList(), mPointersNodes(), mPointersAdjList(), mIsCyclic(false){};
+ ~CAmGraph(){}
+
+ const CAmListNodes & getNodes() const
+ {
+ return mStoreNodes;
+ }
+
+ const CAmVertexReferenceList & getVertexList() const
+ {
+ return mPointersAdjList;
+ }
+
+ /**
+ * Returns pointer to a node which data is equal to the given.
+ * @return pointer to a node or NULL.
+ */
+ const CAmNode<T>* findNode(const T & in)
+ {
+ typename CAmNodeReferenceList::const_iterator itr (mPointersNodes.begin());
+
+ for (; itr != mPointersNodes.end(); ++itr)
+ {
+ if ((*itr)->getData() == in) {
+ return (*itr);
+ }
+ }
+ return NULL;
+ }
+
+ /**
+ * Returns pointer to a vertex which two ends are equal to the given nodes.
+ * @return pointer to a vertex or NULL.
+ */
+ const CAmVertex<T,V>* findVertex(const CAmNode<T> & edge1, const CAmNode<T> & edge2) const
+ {
+ const CAmNode<T> * pEdge2 = (CAmNode<T> *)&edge2;
+ const CAmListVertices * list = mPointersAdjList[edge1.getIndex()];
+ CAmListVerticesItrConst result = std::find_if(list->begin(), list->end(), [&](const CAmVertex<T,V> & refObject){
+ return refObject.getNode()==pEdge2;
+ });
+ if(result!=list->end())
+ return (CAmVertex<T,V>*)&(*result);
+
+ return NULL;
+ }
+
+ bool hasCycles() const
+ {
+ return mIsCyclic;
+ }
+
+
+ /**
+ * Adds a new node to the graph with given user data.
+ * @return reference to the newly inserted node.
+ */
+ CAmNode<T> & addNode(const T & in)
+ {
+ size_t index = mStoreNodes.size();
+ mStoreNodes.emplace_back(in, index);
+ mStoreAdjList.emplace_back();
+ mPointersNodes.push_back(&mStoreNodes.back());
+ mPointersAdjList.push_back(&mStoreAdjList.back());
+ return mStoreNodes.back();
+ }
+
+ /**
+ * Removes a vertex with two ends equal to the given nodes .
+ */
+ void removeVertex(const CAmNode<T> & edge1, const CAmNode<T> & edge2)
+ {
+ const CAmListVertices * list = mPointersAdjList[edge1.getIndex()];
+ CAmListVerticesItr iter = std::find_if(list->begin(), list->end(), [&edge2](const CAmVertex<T,V> & refVertex){
+ return (refVertex.getNode()==&edge2);
+ });
+ if(iter!=list->end())
+ list->erase(iter);
+ }
+
+ /**
+ * Removes all vertices to given node .
+ */
+ void removeAllVerticesToNode(const CAmNode<T> & node)
+ {
+ auto comparator = [&node](const CAmVertex<T,V> & refVertex){
+ return (refVertex.getNode()==&node);
+ };
+ auto itr = mPointersAdjList.begin();
+ for(;itr!=mPointersAdjList.end();itr++)
+ {
+ CAmListVertices * vertices = *itr;
+ auto iterVert = std::find_if(vertices->begin(), vertices->end(), comparator);
+ if(iterVert!=vertices->end())
+ vertices->erase(iterVert);
+ }
+ }
+
+ /**
+ * Removes a node with given user data .
+ */
+ void removeNode(const T & in)
+ {
+ CAmNode<T> * node = findNode(in);
+ if(node!=NULL)
+ removeNode(*node);
+ }
+
+ /**
+ * Removes the given node from the graph .
+ */
+ void removeNode(const CAmNode<T> & node)
+ {
+ uint16_t index = node.getIndex();
+ removeAllVerticesToNode(node);
+ mPointersAdjList.erase(mPointersAdjList.begin()+index);
+ mPointersNodes.erase(mPointersNodes.begin()+index);
+ auto iter = std::find_if(mStoreNodes.begin(), mStoreNodes.end(), [&node](const CAmNode<T> & otherNode){
+ return &otherNode==&node;
+ });
+ if(iter!=mStoreNodes.end())
+ mStoreNodes.erase(iter);
+ updateIndexes(index);
+ }
+
+ /**
+ * Connect first with last node and set user data and weight to the vertex.
+ */
+ void connectNodes(const CAmNode<T> & first, const CAmNode<T> & last, const V & vertexData, const int16_t weight = 1)
+ {
+ CAmListVertices * list = mPointersAdjList[first.getIndex()];
+ CAmNode<T> * node = mPointersNodes[last.getIndex()];
+ list->emplace_back(node, vertexData, weight);
+ }
+
+ /**
+ * Exists any vertex with two given ends.
+ * @return TRUE on successfully changed ID.
+ */
+ bool isAnyVertex(const CAmNode<T> & edge1, const CAmNode<T> & edge2) const
+ {
+ return findVertex(edge1, edge2)!=NULL;
+ }
+
+ /**
+ * Sets the status of all nodes and vertices to GES_NOT_VISITED.
+ */
+ void reset()
+ {
+ // set all nodes to GES_NOT_VISITED
+ std::for_each(mPointersNodes.begin(), mPointersNodes.end(), [](CAmNode<T> * refNode){
+ if(refNode->getStatus()!= GES_NOT_VISITED)
+ refNode->setStatus(GES_NOT_VISITED);
+ });
+ // set all vertices to GES_NOT_VISITED
+ auto action = [](CAmVertex<T,V> & refVertex){
+ if(refVertex.getStatus()!= GES_NOT_VISITED)
+ refVertex.setStatus(GES_NOT_VISITED);
+ };
+ auto itr1(mPointersAdjList.begin());
+ for (; itr1 != mPointersAdjList.end(); ++itr1)
+ {
+ CAmListVertices * vertices = *itr1;
+ std::for_each(vertices->begin(), vertices->end(), action);
+ }
+ }
+
+ /**
+ * Clears all nodes and vertices.
+ */
+ void clear()
+ {
+ mStoreNodes.clear();
+ mStoreAdjList.clear();
+ mPointersAdjList.clear();
+ mPointersNodes.clear();
+ mPointersAdjList.clear();
+ }
+
+ /**
+ * Goes through all nodes and vertices and calls the callback.
+ */
+ void trace(std::function<void(const CAmNode<T> &, const std::vector<CAmVertex<T,V>*> &)> cb)
+ {
+ std::for_each(mPointersNodes.begin(), mPointersNodes.end(), [&](CAmNode<T> * refNode){
+ CAmListVertices * vertices = this->mPointersAdjList[refNode->getIndex()];
+ std::vector<CAmVertex<T,V>*> list;
+ std::for_each(vertices->begin(), vertices->end(), [&list](CAmVertex<T,V> & refVertex){
+ list.push_back(&refVertex);
+ });
+ cb(*refNode, list);
+ });
+ }
+
+ /**
+ * Finds the shortest path from given node to all nodes in listTargets.
+ *
+ * @param source start node.
+ * @param listTargets destination nodes.
+ * @param resultPath list with all shortest paths.
+ */
+ void getShortestPath(const CAmNode<T> & source, const CAmListNodePtrs & listTargets, std::vector<CAmListNodePtrs> & resultPath )
+ {
+ const size_t numberOfNodes = mPointersNodes.size();
+ if(numberOfNodes==0)
+ return;
+
+ std::vector<weight_t> min_distance;
+ std::vector<CAmNode<T>*> previous;
+ findShortestsPathsFromNode(source, min_distance, previous);
+
+ for(auto it=listTargets.begin(); it!=listTargets.end(); it++)
+ {
+ CAmNode<T> *node = *it;
+ resultPath.emplace_back();
+ CAmListNodePtrs & path = resultPath.back();
+ constructShortestPathTo(*node, previous, path);
+ if(path.empty())
+ {
+ typename std::vector<CAmListNodePtrs>::iterator iter = resultPath.end();
+ resultPath.erase(--iter);
+ }
+ }
+ }
+
+ /**
+ * Finds the shortest path between two nodes.
+ *
+ * @param source start node.
+ * @param destination destination node.
+ * @param resultPath list with the found shortest paths.
+ */
+ void getShortestPath(const CAmNode<T> & source, const CAmNode<T> & destination, CAmListNodePtrs & resultPath )
+ {
+ const size_t numberOfNodes = mPointersNodes.size();
+ if(numberOfNodes==0)
+ return;
+ std::vector<weight_t> min_distance;
+ std::vector<CAmNode<T>*> previous;
+ findShortestsPathsFromNode(source, min_distance, previous);
+ constructShortestPathTo(destination, previous, resultPath);
+ }
+
+ /**
+ * Finds the shortest path from given node to all nodes in listTargets.
+ * Delegates the construction of the path to the caller.
+ *
+ * @param source start node.
+ * @param listTargets destination nodes.
+ * @param cb callabck.
+ */
+ void getShortestPath(const CAmNode<T> & source,
+ const CAmListNodePtrs & listTargets,
+ std::function<void(const am_GraphPathPosition_e, CAmNode<T> &)> cb )
+ {
+ const size_t numberOfNodes = mPointersNodes.size();
+ if(numberOfNodes==0)
+ return;
+
+ std::vector<weight_t> min_distance;
+ std::vector<CAmNode<T>*> previous;
+ findShortestsPathsFromNode(source, min_distance, previous);
+
+ for(auto it=listTargets.begin(); it!=listTargets.end(); it++)
+ {
+ CAmNode<T>* node = *it;
+ constructShortestPathTo(*node, previous, cb);
+ }
+ }
+
+ /**
+ * Finds the shortest path between two given nodes.
+ * Delegates the construction of the path to the caller.
+ *
+ * @param source start node.
+ * @param destination destination node.
+ * @param cb callabck.
+ */
+ void getShortestPath(const CAmNode<T> & source,
+ const CAmNode<T> & destination,
+ std::function<void(const am_GraphPathPosition_e, CAmNode<T> &)> cb )
+ {
+ const size_t numberOfNodes = mPointersNodes.size();
+ if(numberOfNodes==0)
+ return;
+
+ std::vector<weight_t> min_distance;
+ std::vector<CAmNode<T>*> previous;
+ findShortestsPathsFromNode(source, min_distance, previous);
+ constructShortestPathTo(destination, previous, cb);
+ }
+
+ /**
+ * Finds all possible paths between two given nodes.
+ * Delegates the construction of the path to the caller.
+ *
+ * @param src start node.
+ * @param dst destination node.
+ * @param cb callabck.
+ */
+ void getAllPaths(const CAmNode<T> & src, const CAmNode<T> & dst, std::function<void(const CAmNodeReferenceList & path)> cb)
+ {
+ CAmNodeReferenceList visited;
+ visited.push_back((CAmNode<T>*)&src);
+ ((CAmNode<T>*)&src)->setStatus(GES_VISITED);
+ goThroughAllPaths(dst, visited, cb);
+ reset();
+ }
+ };
+
+}
+
+#endif
diff --git a/AudioManagerCore/include/CAmLog.h b/AudioManagerCore/include/CAmLog.h
new file mode 100644
index 0000000..35c6a41
--- /dev/null
+++ b/AudioManagerCore/include/CAmLog.h
@@ -0,0 +1,129 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef CAMLOG_H_
+#define CAMLOG_H_
+
+#include <iostream>
+#include <iosfwd>
+#include <stdio.h>
+#include <stdexcept>
+#include <fstream>
+#include <stdlib.h>
+#include <sstream>
+#include <assert.h>
+
+/**
+ * Implements a basic logging mechanism that can be used to print debug information into a file or to the console.
+ * It can be used either as singleton through the appropriate method getDefaultLog() or as independent instantiated object.
+ * The default initializer sets the console as output for newly created objects.
+ * Example: CAmLogger << "Text"; //to print out through the singleton object directly to the console
+ */
+
+#define DEFAULT_LOG_FOLDER "/tmp/"
+#define DEFAULT_LOGFILE_PREFIX "am_dump_"
+#define DEFAULT_LOGFILE_EXT ".log"
+
+#define DEL( aPointer ) delete aPointer, aPointer = NULL;
+
+/* */
+typedef enum { eCAmLogNone = 0, eCAmLogStdout = 1, eCAmLogFile = 2 } eCAmLogType;
+
+class CAmLog
+{
+private:
+ /**
+ * Private classes which usually own (wrap) a stream object. They are responsible for creating and deleting it.
+ */
+ class CAmLogger
+ {
+ protected:
+ std::ostream* mOutputStream;
+ public:
+ CAmLogger ():mOutputStream(NULL) {};
+ virtual ~CAmLogger () { };
+ virtual void log(const std::string& _s)
+ {
+ (*mOutputStream) << _s;
+ mOutputStream->flush();
+ }
+ template <class T>
+ CAmLogger & operator << (const T & t)
+ {
+ (*mOutputStream) << t;
+ return (*this);
+ }
+ };
+
+ class CAmFileLogger : public CAmLogger
+ {
+ std::string mFilename;
+ public:
+ static void generateLogFilename(std::string &result);
+ explicit CAmFileLogger(const std::string& _s) : CAmLogger()
+ {
+ mFilename = _s;
+ mOutputStream = new std::ofstream(mFilename.c_str());
+ }
+ ~CAmFileLogger();
+ };
+
+ class CAmStdOutLogger : public CAmLogger
+ {
+ public:
+ CAmStdOutLogger()
+ {
+ mOutputStream = &std::cout;
+ }
+ };
+
+private:
+ eCAmLogType mLogType;
+ CAmLogger* mLogger;
+
+protected:
+ void releaseLogger();
+ void instantiateLogger( const eCAmLogType type);
+public:
+ CAmLog(const eCAmLogType type );
+ CAmLog();
+ ~CAmLog();
+
+ static CAmLog *getDefaultLog();
+
+ void setLogType( const eCAmLogType type);
+ eCAmLogType getLogType() const;
+
+ template <class T>
+ CAmLog & operator << (const T & t)
+ {
+ assert(mLogger!=NULL);
+ (*mLogger) << t;
+ return (*this);
+ }
+ };
+
+#define CAmLogger (*CAmLog::getDefaultLog())
+
+
+#endif /* CAMLOG_H_ */
diff --git a/AudioManagerCore/include/CAmRouter.h b/AudioManagerCore/include/CAmRouter.h
new file mode 100644
index 0000000..fe41049
--- /dev/null
+++ b/AudioManagerCore/include/CAmRouter.h
@@ -0,0 +1,317 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef ROUTER_H_
+#define ROUTER_H_
+
+#include <assert.h>
+#include <vector>
+#include <functional>
+#include "audiomanagertypes.h"
+#include "CAmGraph.h"
+#include "IAmDatabaseHandler.h"
+
+
+namespace am
+{
+/**
+ * Optimal path search between a source and a sink is implemented with a graph which contains nodes - sinks, sources, gateways, converters.
+ * The nodes are identified by sinkID, sourceID, gatewayID, converterID.
+ * A possible connection between two nodes represents the facts that the nodes can be connected with one or more connectionFormats (Node[id=1] ---> Node[id=2]).
+ * It is assumption that the two nodes can be connected. The controller itself decides later whether the connection is possible or not.
+ *
+ */
+
+/**
+ * Trace on/off.
+ */
+#if !defined(ROUTING_BUILD_CONNECTIONS)
+ #undef TRACE_GRAPH
+#endif
+
+/**
+ * Default behavior is to do the search in one step without connections, which are identified during the search.
+ * Alternatively the search can be done in two steps.
+ */
+#if !defined(ROUTING_BUILD_CONNECTIONS)
+ #undef ROUTING_BUILD_CONNECTIONS
+#endif
+
+#if defined(TRACE_GRAPH)
+#if !defined(ROUTING_BUILD_CONNECTIONS)
+#warning "You should define ROUTING_BUILD_CONNECTIONS in order to be able to see the connections in the trace."
+#endif
+#endif
+
+class CAmRouter;
+
+/**
+ * A structure used as user data in the graph nodes.
+ */
+struct am_RoutingNodeData_s
+{
+ typedef enum:uint8_t {SINK, SOURCE, GATEWAY, CONVERTER} am_NodeDataType_e;
+ am_NodeDataType_e type; //!< data type:sink, source, gateway or converter
+ union
+ {
+ am_Source_s *source;
+ am_Sink_s *sink;
+ am_Gateway_s *gateway;
+ am_Converter_s *converter;
+ } data; //!< union pointer to sink, source, gateway or converter
+
+ am_RoutingNodeData_s():type(SINK)
+ {}
+
+ bool operator==(const am_RoutingNodeData_s & anotherObject) const
+ {
+ bool result = false;
+ if(type==anotherObject.type)
+ {
+ result = true;
+ if(type==SINK)
+ result &= (data.sink->sinkID==anotherObject.data.sink->sinkID);
+ else if(type==SOURCE)
+ result &= (data.source->sourceID==anotherObject.data.source->sourceID);
+ else if(type==GATEWAY)
+ result &= (data.gateway->gatewayID==anotherObject.data.gateway->gatewayID);
+ else if(type==CONVERTER)
+ result &= (data.converter->converterID==anotherObject.data.converter->converterID);
+ }
+ return result;
+ };
+
+#ifdef TRACE_GRAPH
+ void trace() const
+ {
+ if(type==SINK)
+ std::cout << "[SINK:" << data.sink->sinkID << ":" << data.sink->name << "(" << data.sink->domainID << ")"
+ << "]";
+ else if(type==SOURCE)
+ std::cout << "[SOUR:" << data.source->sourceID << ":" << data.source->name << "(" << data.source->domainID << ")"
+ << "]";
+ else if(type==GATEWAY)
+ std::cout << "[GATE:" << data.gateway->gatewayID << ":" << data.gateway->name << "(" << data.gateway->controlDomainID << ")"
+ << "]";
+ else if(type==CONVERTER)
+ std::cout << "[CONV:" << data.converter->converterID << ":" << data.converter->name << "(" << data.converter->domainID << ")"
+ << "]";
+ };
+#endif
+
+ am_domainID_t domainID() const
+ {
+ if(type==SINK)
+ return data.sink->domainID;
+ else if(type==SOURCE)
+ return data.source->domainID;
+ else if(type==GATEWAY)
+ return data.gateway->controlDomainID;
+ else if(type==CONVERTER)
+ return data.converter->domainID;
+ return 0;
+ };
+};
+
+typedef am_RoutingNodeData_s::am_NodeDataType_e CAmNodeDataType;
+typedef CAmNode<am_RoutingNodeData_s> CAmRoutingNode;
+typedef CAmGraph<am_RoutingNodeData_s, uint16_t> CAmRoutingGraph;
+typedef CAmVertex<am_RoutingNodeData_s, uint16_t> CAmRoutingVertex;
+typedef std::list<CAmRoutingVertex> CAmRoutingListVertices;
+typedef std::vector<CAmRoutingListVertices*> CAmRoutingVertexReferenceList;
+
+class CAmControlSender;
+
+
+/**
+ * Implements an autorouting algorithm for connecting sinks and sources via different audio domains.
+ */
+class CAmRouter
+{
+ IAmDatabaseHandler* mpDatabaseHandler; //!< pointer to database handler
+ CAmControlSender* mpControlSender; //!< pointer the controlsender - is used to retrieve information for the optimal route
+ bool mOnlyFreeConversionNodes; //!< bool flag whether only disconnected elements should be considered or not
+ CAmRoutingGraph mRoutingGraph; //!< graph object
+ std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListSources; //!< map with pointers to nodes with sources, used for quick access
+ std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListSinks; //!< map with pointers to nodes with sinks, used for quick access
+ std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListGateways; //!< map with pointers to nodes with gateways, used for quick access
+ std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListConverters;//!< map with pointers to nodes with converters, used for quick access
+
+ am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes);
+ am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects,
+ std::vector<CAmRoutingNode*> & route,
+ std::vector<am_RoutingElement_s>::iterator routingElementIterator,
+ std::vector<CAmRoutingNode*>::iterator routeIterator);
+
+
+ /**
+ * Check whether given converter or gateway has been connected.
+ *
+ * @param comp converter or gateway .
+ */
+ template <class Component> bool isComponentConnected(const Component & comp)
+ {
+ return mpDatabaseHandler->isComponentConnected(comp);
+ }
+ void generateAllPaths(const CAmRoutingNode & src,
+ const CAmRoutingNode & dst,
+ const bool includeCycles,
+ std::function<void(const std::vector<CAmRoutingNode*> & path)> cb);
+ void goThroughAllPaths(const CAmRoutingNode & dst,
+ std::vector<CAmRoutingNode*> & visited,
+ std::vector<am_domainID_t> & visitedDomains,
+ std::function<void(const std::vector<CAmRoutingNode*> & path)> cb);
+
+#ifdef ROUTING_BUILD_CONNECTIONS
+ /**
+ * Connects all converters to its sink and sources if possible.
+ *
+ */
+ void constructConverterConnections();
+
+ /**
+ * Connects all gateways to its sink and sources if possible.
+ *
+ */
+ void constructGatewayConnections();
+
+ /**
+ * Connects all sources to the sinks if possible.
+ *
+ */
+ void constructSourceSinkConnections();
+#else
+ /**
+ * Construct a list with all vertices
+ */
+ void getVerticesForNode(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct a list with all vertices from given source.
+ */
+ void getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct a list with all vertices from given sink.
+ */
+ void getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct a list with all vertices from given converter.
+ */
+ void getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct a list with all vertices from given gateway.
+ */
+ void getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+#endif
+
+public:
+ CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender);
+ ~CAmRouter();
+
+ /**
+ * Finds all possible paths between given source and sink.
+ *
+ * @param onlyfree only disconnected elements should be included or not.
+ * @param sourceID starting point.
+ * @param sinkID ending point.
+ * @param returnList list with all possible paths
+ * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure.
+ */
+ am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
+ am_Error_e getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes);
+
+ am_Error_e getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink,
+ std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath,
+#if !defined(ROUTING_BUILD_CONNECTIONS)
+ __attribute__((unused))
+#endif
+ const bool includeCycles = false);
+#ifdef ROUTING_BUILD_CONNECTIONS
+ void getShortestPath(const CAmRoutingNode & source, const CAmRoutingNode & destination, std::vector<CAmRoutingNode*> & resultPath);
+ void getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, am_Route_s & resultPath, std::vector<CAmRoutingNode*> & resultNodesPath);
+#endif
+
+ static bool 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);
+ static void listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats,
+ std::vector<am_CustomConnectionFormat_t> & inListSinkFormats,
+ std::vector<am_CustomConnectionFormat_t> & outListFormats);
+ static bool 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);
+ static void getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource,
+ std::vector<CAmRoutingNode*>::iterator iteratorSink,
+ std::vector<am_CustomConnectionFormat_t> & outConnectionFormats);
+
+ static bool shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID);
+
+ /**
+ * Returns a sink node with given sinkID.
+ *
+ * @param sinkID sink id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID);
+ CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID);
+
+ /**
+ * Returns a source node with given sourceID.
+ *
+ * @param sourceID source id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID);
+ CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID);
+
+ /**
+ * Returns a converter node for given sinkID.
+ *
+ * @param sinkID sink id.
+ * @param domainID domain id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID);
+
+ /**
+ * Returns a gateway node for given sinkID.
+ *
+ * @param sinkID sink id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* gatewayNodeWithSinkID(const am_sinkID_t sinkID);
+
+ void load(const bool onlyFree);
+ void clear();
+};
+} /* namespace am */
+#endif /* ROUTER_H_ */
+
diff --git a/AudioManagerCore/include/CAmRoutingReceiver.h b/AudioManagerCore/include/CAmRoutingReceiver.h
new file mode 100644
index 0000000..82626c6
--- /dev/null
+++ b/AudioManagerCore/include/CAmRoutingReceiver.h
@@ -0,0 +1,127 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef ROUTINGRECEIVER_H_
+#define ROUTINGRECEIVER_H_
+
+#include "IAmRouting.h"
+
+namespace am
+{
+
+class CAmSocketHandler;
+class CAmDbusWrapper;
+class IAmDatabaseHandler;
+class CAmRoutingSender;
+class CAmControlSender;
+
+/**
+ * Implements the Receiving side of the RoutingPlugins.
+ */
+class CAmRoutingReceiver: public IAmRoutingReceive
+{
+public:
+ CAmRoutingReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmControlSender *iControlSender, CAmSocketHandler *iSocketHandler);
+ CAmRoutingReceiver(IAmDatabaseHandler *iDatabaseHandler, CAmRoutingSender *iRoutingSender, CAmControlSender *iControlSender, CAmSocketHandler *iSocketHandler, CAmDbusWrapper *iDBusWrapper);
+ ~CAmRoutingReceiver();
+ void ackConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error);
+ void ackDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error);
+ void ackSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error);
+ void ackSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error);
+ void ackSetSourceState(const am_Handle_s handle, const am_Error_e error);
+ void ackSetSinkSoundProperties(const am_Handle_s handle, const am_Error_e error);
+ void ackSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error);
+ void ackSetSourceSoundProperties(const am_Handle_s handle, const am_Error_e error);
+ void ackSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error);
+ void ackCrossFading(const am_Handle_s handle, const am_HotSink_e hotSink, const am_Error_e error);
+ void ackSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume);
+ void ackSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume);
+ am_Error_e peekDomain(const std::string& name, am_domainID_t& domainID);
+ am_Error_e registerDomain(const am_Domain_s& domainData, am_domainID_t& domainID);
+ am_Error_e deregisterDomain(const am_domainID_t domainID);
+ am_Error_e registerGateway(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID);
+ am_Error_e registerConverter(const am_Converter_s& converterData, am_converterID_t& converterID);
+ am_Error_e deregisterGateway(const am_gatewayID_t gatewayID);
+ am_Error_e deregisterConverter(const am_converterID_t converterID);
+ am_Error_e peekSink(const std::string& name, am_sinkID_t& sinkID);
+ am_Error_e registerSink(const am_Sink_s& sinkData, am_sinkID_t& sinkID);
+ am_Error_e deregisterSink(const am_sinkID_t sinkID);
+ am_Error_e peekSource(const std::string& name, am_sourceID_t& sourceID);
+ am_Error_e registerSource(const am_Source_s& sourceData, am_sourceID_t& sourceID);
+ am_Error_e deregisterSource(const am_sourceID_t sourceID);
+ am_Error_e registerCrossfader(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID);
+ am_Error_e deregisterCrossfader(const am_crossfaderID_t crossfaderID);
+ am_Error_e peekSourceClassID(const std::string& name, am_sourceClass_t& sourceClassID);
+ am_Error_e peekSinkClassID(const std::string& name, am_sinkClass_t& sinkClassID);
+ void hookInterruptStatusChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState);
+ void hookDomainRegistrationComplete(const am_domainID_t domainID);
+ void hookSinkAvailablityStatusChange(const am_sinkID_t sinkID, const am_Availability_s& availability);
+ void hookSourceAvailablityStatusChange(const am_sourceID_t sourceID, const am_Availability_s& availability);
+ void hookDomainStateChange(const am_domainID_t domainID, const am_DomainState_e domainState);
+ void hookTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t delay);
+ void sendChangedData(const std::vector<am_EarlyData_s>& earlyData);
+ am_Error_e getDBusConnectionWrapper(CAmDbusWrapper*& dbusConnectionWrapper) const;
+ am_Error_e getSocketHandler(CAmSocketHandler*& socketHandler) const;
+ void getInterfaceVersion(std::string& version) const;
+ void confirmRoutingReady(const uint16_t handle, const am_Error_e error);
+ void confirmRoutingRundown(const uint16_t handle, const am_Error_e error);
+ am_Error_e 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) ;
+ am_Error_e 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);
+ am_Error_e 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) ;
+ am_Error_e 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) ;
+ void ackSetVolumes(const am_Handle_s handle, const std::vector<am_Volumes_s>& listvolumes, const am_Error_e error) ;
+ void ackSinkNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) ;
+ void ackSourceNotificationConfiguration(const am_Handle_s handle, const am_Error_e error) ;
+ void hookSinkNotificationDataChange(const am_sinkID_t sinkID, const am_NotificationPayload_s& payload) ;
+ void hookSourceNotificationDataChange(const am_sourceID_t sourceID, const am_NotificationPayload_s& payload) ;
+ am_Error_e getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t& domainID) const;
+ am_Error_e getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t& domainID) const;
+ am_Error_e getDomainOfCrossfader(const am_crossfaderID_t crossfader, am_domainID_t& domainID) const;
+
+ uint16_t getStartupHandle(); //!< returns a startup handle
+ uint16_t getRundownHandle(); //!< returns a rundown handle
+
+ void waitOnStartup(bool startup); //!< tells the RoutingReceiver to start waiting for all handles to be confirmed
+ void waitOnRundown(bool rundown); //!< tells the RoutingReceiver to start waiting for all handles to be confirmed
+
+private:
+ IAmDatabaseHandler *mpDatabaseHandler; //!< pointer to the databaseHandler
+ CAmRoutingSender *mpRoutingSender; //!< pointer to the routingSender
+ CAmControlSender *mpControlSender; //!< pointer to the controlSender
+ CAmSocketHandler *mpSocketHandler; //!< pointer to sockethandler
+ CAmDbusWrapper *mpDBusWrapper; //!< pointer to dbuswrapper
+
+ std::vector<uint16_t> mListStartupHandles; //!< list of handles that wait for a confirm
+ std::vector<uint16_t> mListRundownHandles; //!< list of handles that wait for a confirm
+ uint16_t handleCount; //!< counts all handles
+ bool mWaitStartup; //!< if true confirmation will be sent if list of handles = 0
+ bool mWaitRundown; //!< if true confirmation will be sent if list of handles = 0
+
+ am_Error_e mLastStartupError;
+ am_Error_e mLastRundownError;
+
+};
+
+}
+
+#endif /* ROUTINGRECEIVER_H_ */
diff --git a/AudioManagerCore/include/CAmRoutingSender.h b/AudioManagerCore/include/CAmRoutingSender.h
new file mode 100644
index 0000000..4a23428
--- /dev/null
+++ b/AudioManagerCore/include/CAmRoutingSender.h
@@ -0,0 +1,155 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef ROUTINGSENDER_H_
+#define ROUTINGSENDER_H_
+
+#include "IAmRouting.h"
+#include <map>
+
+#ifdef UNIT_TEST //this is needed to test RoutingSender
+#include "../test/IAmRoutingBackdoor.h"
+#endif
+
+namespace am
+{
+
+class CAmRoutingReceiver;
+
+/**
+ * Implements the RoutingSendInterface. Loads all plugins and dispatches calls to the plugins
+ */
+class CAmRoutingSender
+{
+public:
+ CAmRoutingSender(const std::vector<std::string>& listOfPluginDirectories);
+ ~CAmRoutingSender();
+
+ am_Error_e removeHandle(const am_Handle_s& handle);
+ am_Error_e addDomainLookup(const am_Domain_s& domainData);
+ am_Error_e addSourceLookup(const am_Source_s& sourceData);
+ am_Error_e addSinkLookup(const am_Sink_s& sinkData);
+ am_Error_e addCrossfaderLookup(const am_Crossfader_s& crossfaderData);
+ am_Error_e removeDomainLookup(const am_domainID_t domainID);
+ am_Error_e removeSourceLookup(const am_sourceID_t sourceID);
+ am_Error_e removeSinkLookup(const am_sinkID_t sinkID);
+ am_Error_e removeCrossfaderLookup(const am_crossfaderID_t crossfaderID);
+ am_Error_e removeConnectionLookup(const am_connectionID_t connectionID);
+
+ am_Error_e startupInterfaces(CAmRoutingReceiver* iRoutingReceiver);
+ void setRoutingReady();
+ void setRoutingRundown();
+ am_Error_e asyncAbort(const am_Handle_s& handle);
+ am_Error_e 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_Error_e asyncDisconnect(am_Handle_s& handle, const am_connectionID_t connectionID);
+ am_Error_e asyncSetSinkVolume(am_Handle_s& handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time);
+ am_Error_e asyncSetSourceVolume(am_Handle_s& handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time);
+ am_Error_e asyncSetSourceState(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SourceState_e state);
+ am_Error_e asyncSetSinkSoundProperty(am_Handle_s& handle, const am_sinkID_t sinkID, const am_SoundProperty_s& soundProperty);
+ am_Error_e asyncSetSourceSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s>& listSoundProperties, const am_sourceID_t sourceID);
+ am_Error_e asyncSetSinkSoundProperties(am_Handle_s& handle, const std::vector<am_SoundProperty_s>& listSoundProperties, const am_sinkID_t sinkID);
+ am_Error_e asyncSetSourceSoundProperty(am_Handle_s& handle, const am_sourceID_t sourceID, const am_SoundProperty_s& soundProperty);
+ am_Error_e asyncCrossFade(am_Handle_s& handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_CustomRampType_t rampType, const am_time_t time);
+ am_Error_e setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState);
+ am_Error_e getListHandles(std::vector<am_Handle_s> & listHandles) const;
+ am_Error_e getListPlugins(std::vector<std::string>& interfaces) const;
+ void getInterfaceVersion(std::string& version) const;
+ am_Error_e asyncSetVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes);
+ am_Error_e asyncSetSinkNotificationConfiguration(am_Handle_s& handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration);
+ am_Error_e asyncSetSourceNotificationConfiguration(am_Handle_s& handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration);
+ am_Error_e resyncConnectionState(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections);
+
+ struct InterfaceNamePairs //!< is used to pair interfaces with busnames
+ {
+ IAmRoutingSend* routingInterface; //!< pointer to the routingInterface
+ std::string busName; //!< the busname
+ };
+
+ class am_handleData_c //!< is used to store data related to handles
+ {
+ public:
+ union
+ {
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ am_crossfaderID_t crossfaderID;
+ am_connectionID_t connectionID;
+ am_DataType_u volumeID;
+ };
+
+ union
+ {
+ am_SoundProperty_s soundPropery;
+ am_SourceState_e sourceState;
+ am_volume_t volume;
+ am_HotSink_e hotSink;
+ std::vector<am_SoundProperty_s>* soundProperties;
+ std::vector<am_Volumes_s>* listVolumes;
+ am_NotificationConfiguration_s* notificationConfiguration;
+ };
+
+ };
+
+ am_Error_e returnHandleData(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData) const; //!< returns the handle data associated with a handle
+ am_Error_e returnHandleDataAndRemove(const am_Handle_s handle,CAmRoutingSender::am_handleData_c& handleData); //!< returns the handle data associated with a handle and removes the handle
+
+#ifdef UNIT_TEST //this is needed to test RoutingSender
+ friend class IAmRoutingBackdoor;
+#endif
+
+private:
+ struct comparator //!< is needed to sort the handles in the map
+ {
+ bool operator()(const am_Handle_s& a, const am_Handle_s& b) const
+ {
+ return (a.handle<b.handle || (a.handle==b.handle && a.handleType<b.handleType));
+ }
+ };
+
+ am_Handle_s createHandle(const am_handleData_c& handleData, const am_Handle_e type); //!< creates a handle
+ void unloadLibraries(void); //!< unloads all loaded plugins
+
+ typedef std::map<am_domainID_t, IAmRoutingSend*> DomainInterfaceMap; //!< maps domains to interfaces
+ typedef std::map<am_sinkID_t, IAmRoutingSend*> SinkInterfaceMap; //!< maps sinks to interfaces
+ typedef std::map<am_sourceID_t, IAmRoutingSend*> SourceInterfaceMap; //!< maps sources to interfaces
+ typedef std::map<am_crossfaderID_t, IAmRoutingSend*> CrossfaderInterfaceMap; //!< maps crossfaders to interfaces
+ typedef std::map<am_connectionID_t, IAmRoutingSend*> ConnectionInterfaceMap; //!< maps connections to interfaces
+ typedef std::map<uint16_t, IAmRoutingSend*> HandleInterfaceMap; //!< maps handles to interfaces
+ typedef std::map<am_Handle_s, am_handleData_c, comparator> HandlesMap; //!< maps handleData to handles
+
+ int16_t mHandleCount; //!< is used to create handles
+ HandlesMap mlistActiveHandles; //!< list of all currently "running" handles.
+ std::vector<void*> mListLibraryHandles; //!< list of all loaded pluginInterfaces
+ std::vector<InterfaceNamePairs> mListInterfaces; //!< list of busname/interface relation
+ ConnectionInterfaceMap mMapConnectionInterface; //!< map of connection to interfaces
+ CrossfaderInterfaceMap mMapCrossfaderInterface; //!< map of crossfaders to interface
+ DomainInterfaceMap mMapDomainInterface; //!< map of domains to interfaces
+ SinkInterfaceMap mMapSinkInterface; //!< map of sinks to interfaces
+ SourceInterfaceMap mMapSourceInterface; //!< map of sources to interfaces
+ HandleInterfaceMap mMapHandleInterface; //!< map of handles to interfaces
+ CAmRoutingReceiver *mpRoutingReceiver; //!< pointer to routing receiver
+};
+
+}
+
+#endif /* ROUTINGSENDER_H_ */
diff --git a/AudioManagerCore/include/CAmTelnetMenuHelper.h b/AudioManagerCore/include/CAmTelnetMenuHelper.h
new file mode 100644
index 0000000..7038cb3
--- /dev/null
+++ b/AudioManagerCore/include/CAmTelnetMenuHelper.h
@@ -0,0 +1,204 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+// Local header
+#ifndef CAMTELNETMENUHELPER_H_
+#define CAMTELNETMENUHELPER_H_
+
+// Standard header
+#include <iostream>
+#include <queue>
+#include <map>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <sys/socket.h>
+#include "audiomanagertypes.h"
+
+namespace am
+{
+
+class CAmTelnetServer;
+class IAmDatabaseHandler;
+class CAmCommandSender;
+class CAmRoutingSender;
+class CAmControlSender;
+class CAmCommandReceiver;
+class CAmRoutingReceiver;
+class CAmControlReceiver;
+
+class CAmRouter;
+class CAmSocketHandler;
+
+/**
+ * helper class for CAmTelnetServer
+ */
+class CAmTelnetMenuHelper
+{
+public:
+
+ enum EMainState
+ {
+ eRootState = 0, eListState, eInfoState, eGetState, eSetState
+ };
+
+ CAmTelnetMenuHelper(CAmSocketHandler *iSocketHandler, CAmCommandSender *iCommandSender, CAmCommandReceiver *iCommandReceiver, CAmRoutingSender *iRoutingSender, CAmRoutingReceiver *iRoutingReceiver, CAmControlSender *iControlSender, CAmControlReceiver *iControlReceiver, IAmDatabaseHandler *iDatabasehandler, CAmRouter *iRouter, CAmTelnetServer *iTelnetServer);
+
+ ~CAmTelnetMenuHelper();
+
+ void newSocketConnection(int filedescriptor);
+
+ void socketConnectionsClosed(int filedescriptor);
+
+ void enterCmdQueue(std::queue<std::string> &CmdQueue, int &filedescriptor);
+
+private:
+
+ void createCommandMaps();
+ void sendError(int & filedescriptor, std::string error_string);
+ void sendTelnetLine(int & filedescriptor, std::stringstream &line);
+ void sendCurrentCmdPrompt(int &filedescriptor);
+
+ // COMMON commands
+ static void oneStepBackCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void oneStepBackCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void exitCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void exitCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void helpCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void helpCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+
+ // ROOT commands
+ static void rootGetCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void rootGetCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void rootSetCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void rootSetCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void rootListCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void rootListCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void rootInfoCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void rootInfoCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+
+ // LIST commands
+ static void listConnectionsCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listConnectionsCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listSourcesCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listSourcesCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listSinksCommands(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listSinksCommandsExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listCrossfaders(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listCrossfadersExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listDomainsCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listDomainsCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listGatewaysCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listGatewaysCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listPluginsCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listPluginsCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listMainConnectionsCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listMainConnectionsCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listMainSourcesCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listMainSourcesCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void listMainSinksCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void listMainSinksCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+
+ // SET commands
+ static void setRoutingCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setRoutingCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setConnection(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setConnectionExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setDisconnectConnId(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setDisconnectConnIdExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setSourceSoundProperties(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setSourceSoundPropertiesExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setSinkSoundProperty(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setSinkSoundPropertyExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setSinkVolume(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setSinkVolumeExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setVolumeStep(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setVolumeStepExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setSinkMuteState(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setSinkMuteStateExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void setSourceSoundProperty(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void setSourceSoundPropertyExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+
+ // GET commands
+ static void getRoutingCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void getRoutingCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void getSenderversionCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void getSenderversionCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void getReceiverversionCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void getReceiverversionCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+
+ // INFO commands
+ static void infoSystempropertiesCommand(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ void infoSystempropertiesCommandExec(std::queue<std::string> & CmdQueue, int & filedescriptor);
+ static void infoDumpCommand(std::queue<std::string>& CmdQueue, int& filedescriptor);
+ void infoDumpCommandExec(std::queue<std::string>& CmdQueue, int& filedescriptor);
+
+private:
+
+ typedef void (*pCommandPrototype)(std::queue<std::string>& msg, int & filedescriptor);
+
+ struct sCommandPrototypeInfo
+ {
+ std::string info;
+ pCommandPrototype CommandPrototype;
+
+ // default contructor to set NULL
+ sCommandPrototypeInfo() :
+ info(""), CommandPrototype(NULL)
+ {
+ }
+
+ // a small contructor
+ sCommandPrototypeInfo(std::string MyInfo, pCommandPrototype MyCommandPrototype) :
+ info(MyInfo), CommandPrototype(MyCommandPrototype)
+ {
+ }
+ };
+
+ typedef std::map<std::string, sCommandPrototypeInfo> tCommandMap;
+ std::map<int, EMainState> mCurrentMainStateMap; //!< int filedescriptor of socket connection; EMainState state of current telnet session
+
+ static CAmTelnetMenuHelper* instance;
+ CAmTelnetServer *mpTelenetServer;
+ CAmSocketHandler *mpSocketHandler;
+ CAmCommandSender *mpCommandSender;
+ CAmCommandReceiver *mpCommandReceiver;
+ CAmRoutingSender *mpRoutingSender;
+ CAmRoutingReceiver *mpRoutingReceiver;
+ CAmControlSender *mpControlSender;
+ CAmControlReceiver *mpControlReceiver;
+ IAmDatabaseHandler *mpDatabasehandler;
+ CAmRouter *mpRouter;
+
+ tCommandMap mRootCommands;
+ tCommandMap mListCommands;
+ tCommandMap mGetCommands;
+ tCommandMap mSetCommands;
+ tCommandMap mInfoCommands;
+
+};
+// class CAmTelnetMenuHelper
+}// namespace am
+
+#endif // CAMTELNETMENUHELPER_H_
diff --git a/AudioManagerCore/include/CAmTelnetServer.h b/AudioManagerCore/include/CAmTelnetServer.h
new file mode 100644
index 0000000..0e4c510
--- /dev/null
+++ b/AudioManagerCore/include/CAmTelnetServer.h
@@ -0,0 +1,100 @@
+/**
+ * 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.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef TELNETSERVER_H_
+#define TELNETSERVER_H_
+
+#include <queue>
+#include <map>
+#include "CAmSocketHandler.h"
+#include "CAmTelnetMenuHelper.h"
+
+namespace am
+{
+
+class IAmDatabaseHandler;
+class CAmCommandSender;
+class CAmRoutingSender;
+class CAmControlSender;
+class CAmCommandReceiver;
+class CAmRoutingReceiver;
+class CAmControlReceiver;
+class CAmRouter;
+class CAmTelnetMenuHelper;
+
+/**
+ * Implements a telnetserver that can be used to connect to the audiomanager, retrieve some information and use it. For debugging purposes.
+ * For example, launch a telnet session on port 6060:
+ * \code telnet localhost 6060 \endcode
+ * more details can be found at the README
+ */
+class CAmTelnetServer
+{
+public:
+ 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);
+ ~CAmTelnetServer();
+ void connectSocket(const pollfd pfd, const sh_pollHandle_t handle, void* userData);
+ void disconnectClient(int filedescriptor);
+ void receiveData(const pollfd pfd, const sh_pollHandle_t handle, void* userData);
+ bool dispatchData(const sh_pollHandle_t handle, void* userData);
+ bool check(const sh_pollHandle_t handle, void* userData);
+ TAmShPollFired<CAmTelnetServer> telnetConnectFiredCB;
+ TAmShPollFired<CAmTelnetServer> telnetReceiveFiredCB;
+ TAmShPollDispatch<CAmTelnetServer> telnetDispatchCB;
+ TAmShPollCheck<CAmTelnetServer> telnetCheckCB;
+private:
+
+ typedef void (*CommandPrototype)(std::vector<std::string>& msg, int filedescriptor);
+ typedef std::map<std::string, CommandPrototype> mMapCommand_t;
+
+ void sliceCommand(const std::string& string, std::string& command, std::queue<std::string>& msg);
+ mMapCommand_t createCommandMap();
+ struct connection_s
+ {
+ int filedescriptor;
+ sh_pollHandle_t handle;
+ };
+
+ static CAmTelnetServer* mpInstance;
+ CAmSocketHandler *mpSocketHandler;
+ CAmCommandSender *mpCommandSender;
+ CAmCommandReceiver *mpCommandReceiver;
+ CAmRoutingSender *mpRoutingSender;
+ CAmRoutingReceiver *mpRoutingReceiver;
+ CAmControlSender *mpControlSender;
+ CAmControlReceiver *mpControlReceiver;
+ IAmDatabaseHandler *mpDatabasehandler;
+ CAmRouter *mpRouter;
+ sh_pollHandle_t mConnecthandle;
+ std::queue<std::string> mListMessages;
+ std::vector<connection_s> mListConnections;
+ int mConnectFD;
+ unsigned int mServerPort;
+ unsigned int mMaxConnections;
+ CAmTelnetMenuHelper mTelnetMenuHelper;
+
+};
+
+} /* namespace am */
+#endif /* TELNETSERVER_H_ */
diff --git a/AudioManagerCore/include/IAmDatabaseHandler.h b/AudioManagerCore/include/IAmDatabaseHandler.h
new file mode 100644
index 0000000..30c1aaf
--- /dev/null
+++ b/AudioManagerCore/include/IAmDatabaseHandler.h
@@ -0,0 +1,200 @@
+/**
+ * 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 IAmDatabaseHandler.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef DATABASEHANDLERINTERFACE_H_
+#define DATABASEHANDLERINTERFACE_H_
+
+#include "audiomanagertypes.h"
+#include <map>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <functional>
+#include "audiomanagerconfig.h"
+
+namespace am
+{
+
+class CAmDatabaseObserver;
+class CAmRoutingTree;
+class CAmRoutingTreeItem;
+
+
+//enum { DYNAMIC_ID_BOUNDARY = 100 }; //!< the value below is reserved for staticIDs, the value above will be assigned to dynamically registered items
+
+//todo: check the enum values before entering & changing in the database.
+//todo: change asserts for dynamic boundary checks into failure answers.#
+//todo: check autoincrement boundary and set to 16bit limits
+//todo: If the sink is part of a gateway, the listconnectionFormats is copied to the gatewayInformation. Check this statement for sinks & sources
+//todo: exchange last_insert_row id to be more safe
+//todo: create test to ensure uniqueness of names throughout the database
+//todo: enforce the uniqueness of names
+
+typedef std::map<am_gatewayID_t, std::vector<bool> > ListConnectionFormat; //!< type for list of connection formats
+
+/**
+ * This class handles and abstracts the database
+ */
+
+class IAmDatabaseHandler
+{
+public:
+ IAmDatabaseHandler () {};
+ virtual ~IAmDatabaseHandler () {};
+ virtual am_Error_e enterDomainDB(const am_Domain_s& domainData, am_domainID_t& domainID) = 0;
+ virtual am_Error_e enterMainConnectionDB(const am_MainConnection_s& mainConnectionData, am_mainConnectionID_t& connectionID) = 0;
+ virtual am_Error_e enterSinkDB(const am_Sink_s& sinkData, am_sinkID_t& sinkID) = 0;
+ virtual am_Error_e enterCrossfaderDB(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID) = 0;
+ virtual am_Error_e enterGatewayDB(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID) = 0;
+ virtual am_Error_e enterConverterDB(const am_Converter_s & converteData, am_converterID_t & converterID) = 0;
+ virtual am_Error_e enterSourceDB(const am_Source_s& sourceData, am_sourceID_t& sourceID) = 0;
+ virtual am_Error_e enterConnectionDB(const am_Connection_s& connection, am_connectionID_t& connectionID) = 0;
+ virtual am_Error_e enterSinkClassDB(const am_SinkClass_s& sinkClass, am_sinkClass_t& sinkClassID) = 0;
+ virtual am_Error_e enterSourceClassDB(am_sourceClass_t& sourceClassID, const am_SourceClass_s& sourceClass) = 0;
+ virtual am_Error_e enterSystemProperties(const std::vector<am_SystemProperty_s>& listSystemProperties) = 0;
+ virtual am_Error_e changeMainConnectionRouteDB(const am_mainConnectionID_t mainconnectionID, const std::vector<am_connectionID_t>& listConnectionID) = 0;
+ virtual am_Error_e changeMainConnectionStateDB(const am_mainConnectionID_t mainconnectionID, const am_ConnectionState_e connectionState) = 0;
+ virtual am_Error_e changeSinkMainVolumeDB(const am_mainVolume_t mainVolume, const am_sinkID_t sinkID) = 0;
+ virtual am_Error_e changeSinkAvailabilityDB(const am_Availability_s& availability, const am_sinkID_t sinkID) = 0;
+ virtual am_Error_e changDomainStateDB(const am_DomainState_e domainState, const am_domainID_t domainID) = 0;
+ virtual am_Error_e changeSinkMuteStateDB(const am_MuteState_e muteState, const am_sinkID_t sinkID) = 0;
+ virtual am_Error_e changeMainSinkSoundPropertyDB(const am_MainSoundProperty_s& soundProperty, const am_sinkID_t sinkID) = 0;
+ virtual am_Error_e changeMainSourceSoundPropertyDB(const am_MainSoundProperty_s& soundProperty, const am_sourceID_t sourceID) = 0;
+ virtual am_Error_e changeSourceSoundPropertyDB(const am_SoundProperty_s& soundProperty, const am_sourceID_t sourceID) = 0;
+ virtual am_Error_e changeSinkSoundPropertyDB(const am_SoundProperty_s& soundProperty, const am_sinkID_t sinkID) = 0;
+ virtual am_Error_e changeSourceAvailabilityDB(const am_Availability_s& availability, const am_sourceID_t sourceID) = 0;
+ virtual am_Error_e changeSystemPropertyDB(const am_SystemProperty_s& property) = 0;
+ virtual am_Error_e changeDelayMainConnection(const am_timeSync_t & delay, const am_mainConnectionID_t & connectionID) = 0;
+ virtual am_Error_e changeSinkClassInfoDB(const am_SinkClass_s& sinkClass) = 0;
+ virtual am_Error_e changeSourceClassInfoDB(const am_SourceClass_s& sourceClass) = 0;
+ virtual am_Error_e changeConnectionTimingInformation(const am_connectionID_t connectionID, const am_timeSync_t delay) = 0;
+ virtual am_Error_e changeConnectionFinal(const am_connectionID_t connectionID) = 0;
+ virtual am_Error_e changeSourceState(const am_sourceID_t sourceID, const am_SourceState_e sourceState) = 0;
+ virtual am_Error_e changeSinkVolume(const am_sinkID_t sinkID, const am_volume_t volume) = 0;
+ virtual am_Error_e changeSourceVolume(const am_sourceID_t sourceID, const am_volume_t volume) = 0;
+ virtual am_Error_e changeCrossFaderHotSink(const am_crossfaderID_t crossfaderID, const am_HotSink_e hotsink) = 0;
+ virtual am_Error_e removeMainConnectionDB(const am_mainConnectionID_t mainConnectionID) = 0;
+ virtual am_Error_e removeSinkDB(const am_sinkID_t sinkID) = 0;
+ virtual am_Error_e removeSourceDB(const am_sourceID_t sourceID) = 0;
+ virtual am_Error_e removeGatewayDB(const am_gatewayID_t gatewayID) = 0;
+ virtual am_Error_e removeConverterDB(const am_converterID_t converterID) = 0;
+ virtual am_Error_e removeCrossfaderDB(const am_crossfaderID_t crossfaderID) = 0;
+ virtual am_Error_e removeDomainDB(const am_domainID_t domainID) = 0;
+ virtual am_Error_e removeSinkClassDB(const am_sinkClass_t sinkClassID) = 0;
+ virtual am_Error_e removeSourceClassDB(const am_sourceClass_t sourceClassID) = 0;
+ virtual am_Error_e removeConnection(const am_connectionID_t connectionID) = 0;
+ virtual am_Error_e getSourceClassInfoDB(const am_sourceID_t sourceID, am_SourceClass_s& classInfo) const = 0;
+ virtual am_Error_e getSinkClassInfoDB(const am_sinkID_t sinkID, am_SinkClass_s& sinkClass) const = 0;
+ virtual am_Error_e getGatewayInfoDB(const am_gatewayID_t gatewayID, am_Gateway_s& gatewayData) const = 0;
+ virtual am_Error_e getConverterInfoDB(const am_converterID_t converterID, am_Converter_s& converterData) const = 0;
+ virtual am_Error_e getSinkInfoDB(const am_sinkID_t sinkID, am_Sink_s& sinkData) const = 0;
+ virtual am_Error_e getSourceInfoDB(const am_sourceID_t sourceID, am_Source_s& sourceData) const = 0;
+ virtual am_Error_e getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s& crossfaderData) const = 0;
+ virtual am_Error_e getMainConnectionInfoDB(const am_mainConnectionID_t mainConnectionID, am_MainConnection_s& mainConnectionData) const = 0;
+ virtual am_Error_e getSinkMainVolume(const am_sinkID_t sinkID, am_mainVolume_t& mainVolume) const = 0;
+ virtual am_Error_e getSinkVolume(const am_sinkID_t sinkID, am_volume_t& volume) const = 0;
+ virtual am_Error_e getSourceVolume(const am_sourceID_t sourceID, am_volume_t& volume) const = 0;
+ virtual am_Error_e getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const = 0;
+ virtual am_Error_e getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const = 0;
+ virtual am_Error_e getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const =0;
+ virtual am_Error_e getListSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_SoundProperty_s>& listSoundproperties) const =0;
+ virtual am_Error_e getMainSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const = 0;
+ virtual am_Error_e getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const = 0;
+ virtual am_Error_e getListSinksOfDomain(const am_domainID_t domainID, std::vector<am_sinkID_t>& listSinkID) const = 0;
+ virtual am_Error_e getListSourcesOfDomain(const am_domainID_t domainID, std::vector<am_sourceID_t>& listSourceID) const = 0;
+ virtual am_Error_e getListCrossfadersOfDomain(const am_domainID_t domainID, std::vector<am_crossfaderID_t>& listGatewaysID) const = 0;
+ virtual am_Error_e getListGatewaysOfDomain(const am_domainID_t domainID, std::vector<am_gatewayID_t>& listGatewaysID) const = 0;
+ virtual am_Error_e getListConvertersOfDomain(const am_domainID_t domainID, std::vector<am_converterID_t>& listConvertersID) const = 0;
+ virtual am_Error_e getListMainConnections(std::vector<am_MainConnection_s>& listMainConnections) const = 0;
+ virtual am_Error_e getListDomains(std::vector<am_Domain_s>& listDomains) const = 0;
+ virtual am_Error_e getListConnections(std::vector<am_Connection_s>& listConnections) const = 0;
+ virtual am_Error_e getListSinks(std::vector<am_Sink_s>& listSinks) const = 0;
+ virtual am_Error_e getListSources(std::vector<am_Source_s>& lisSources) const = 0;
+ virtual am_Error_e getListSourceClasses(std::vector<am_SourceClass_s>& listSourceClasses) const = 0;
+ virtual am_Error_e getListCrossfaders(std::vector<am_Crossfader_s>& listCrossfaders) const = 0;
+ virtual am_Error_e getListGateways(std::vector<am_Gateway_s>& listGateways) const = 0;
+ virtual am_Error_e getListConverters(std::vector<am_Converter_s> & listConverters) const = 0;
+ virtual am_Error_e getListSinkClasses(std::vector<am_SinkClass_s>& listSinkClasses) const = 0;
+ virtual am_Error_e getListVisibleMainConnections(std::vector<am_MainConnectionType_s>& listConnections) const = 0;
+ virtual am_Error_e getListMainSinks(std::vector<am_SinkType_s>& listMainSinks) const = 0;
+ virtual am_Error_e getListMainSources(std::vector<am_SourceType_s>& listMainSources) const = 0;
+ virtual am_Error_e getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s>& listSoundProperties) const = 0;
+ virtual am_Error_e getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s>& listSourceProperties) const = 0;
+ virtual am_Error_e getListSystemProperties(std::vector<am_SystemProperty_s>& listSystemProperties) const = 0;
+ virtual am_Error_e getListSinkConnectionFormats(const am_sinkID_t sinkID, std::vector<am_CustomConnectionFormat_t> & listConnectionFormats) const = 0;
+ virtual am_Error_e getListSourceConnectionFormats(const am_sourceID_t sourceID, std::vector<am_CustomConnectionFormat_t> & listConnectionFormats) const = 0;
+ virtual am_Error_e getListGatewayConnectionFormats(const am_gatewayID_t gatewayID, std::vector<bool> & listConnectionFormat) const = 0;
+ virtual am_Error_e getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t& delay) const = 0;
+ virtual am_Error_e getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t& domainID) const = 0;
+ virtual am_Error_e getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t& domainID) const = 0;
+ virtual am_Error_e getDomainOfCrossfader(const am_crossfaderID_t crossfader, am_domainID_t& domainID) const = 0;
+ virtual am_Error_e getSoureState(const am_sourceID_t sourceID, am_SourceState_e& sourceState) const = 0;
+ virtual am_Error_e getDomainState(const am_domainID_t domainID, am_DomainState_e& state) const = 0;
+ virtual am_Error_e peekDomain(const std::string& name, am_domainID_t& domainID) = 0;
+ virtual am_Error_e peekSink(const std::string& name, am_sinkID_t& sinkID) = 0;
+ virtual am_Error_e peekSource(const std::string& name, am_sourceID_t& sourceID) = 0;
+ virtual am_Error_e peekSinkClassID(const std::string& name, am_sinkClass_t& sinkClassID) = 0;
+ virtual am_Error_e peekSourceClassID(const std::string& name, am_sourceClass_t& sourceClassID) = 0;
+ virtual am_Error_e 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) = 0;
+ virtual am_Error_e 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) = 0;
+ virtual am_Error_e getListMainSinkNotificationConfigurations(const am_sinkID_t sinkID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations) = 0;
+ virtual am_Error_e getListMainSourceNotificationConfigurations(const am_sourceID_t sourceID, std::vector<am_NotificationConfiguration_s>& listMainNotificationConfigurations) = 0;
+ virtual am_Error_e changeMainSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) = 0;
+ virtual am_Error_e changeMainSourceNotificationConfigurationDB(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) = 0;
+ virtual am_Error_e 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) = 0;
+ virtual am_Error_e 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) = 0;
+ virtual am_Error_e changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID,const am_NotificationConfiguration_s notificationConfiguration) = 0;
+ virtual am_Error_e changeSourceNotificationConfigurationDB(const am_sourceID_t sourceID,const am_NotificationConfiguration_s notificationConfiguration) = 0;
+
+ virtual bool existMainConnection(const am_mainConnectionID_t mainConnectionID) const = 0;
+ virtual bool existCrossFader(const am_crossfaderID_t crossfaderID) const = 0;
+ virtual bool existConnection(const am_Connection_s & connection) const = 0;
+ virtual bool existConnectionID(const am_connectionID_t connectionID) const = 0;
+ virtual bool existSource(const am_sourceID_t sourceID) const = 0;
+ virtual bool existSourceNameOrID(const am_sourceID_t sourceID, const std::string& name) const = 0;
+ virtual bool existSourceName(const std::string& name) const = 0;
+ virtual bool existSink(const am_sinkID_t sinkID) const = 0;
+ virtual bool existSinkNameOrID(const am_sinkID_t sinkID, const std::string& name) const = 0;
+ virtual bool existSinkName(const std::string& name) const = 0;
+ virtual bool existDomain(const am_domainID_t domainID) const = 0;
+ virtual bool existGateway(const am_gatewayID_t gatewayID) const = 0;
+ virtual bool existSinkClass(const am_sinkClass_t sinkClassID) const = 0;
+ virtual bool existSourceClass(const am_sourceClass_t sourceClassID) const = 0;
+ virtual void registerObserver(CAmDatabaseObserver *iObserver) = 0;
+ virtual bool sourceVisible(const am_sourceID_t sourceID) const = 0;
+ virtual bool sinkVisible(const am_sinkID_t sinkID) const = 0;
+ virtual bool isComponentConnected(const am_Gateway_s & gateway) const = 0;
+ virtual bool isComponentConnected(const am_Converter_s & converter) const = 0;
+ virtual am_timeSync_t calculateMainConnectionDelay(const am_mainConnectionID_t mainConnectionID) const = 0; //!< calculates a new main connection delay
+ virtual void dump( std::ostream & output) const = 0 ;
+ virtual am_Error_e enumerateSources(std::function<void(const am_Source_s & element)> cb) const = 0 ;
+ virtual am_Error_e enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const = 0 ;
+ virtual am_Error_e enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const = 0 ;
+ virtual am_Error_e enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const = 0 ;
+
+};
+
+
+}
+
+#endif /* DATABASEHANDLERINTERFACE_H_ */
diff --git a/AudioManagerCore/include/TAmPluginTemplate.h b/AudioManagerCore/include/TAmPluginTemplate.h
new file mode 100644
index 0000000..f000fbe
--- /dev/null
+++ b/AudioManagerCore/include/TAmPluginTemplate.h
@@ -0,0 +1,91 @@
+/**
+ * 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 TAmPluginTemplate.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef PLUGINTEMPLATE_H_
+#define PLUGINTEMPLATE_H_
+
+#include <dlfcn.h>
+#include <libgen.h>
+#include "CAmDltWrapper.h"
+
+namespace am
+{
+
+/**
+ * * This template tries to load a library and cast to a class
+ * @param libname the full path to the library to be loaded
+ * @param libraryHandle the handle to the library that gets returned
+ * @return returns the pointer to the class to be loaded
+ */
+template<class T> T* getCreateFunction(const std::string& libname, void*& libraryHandle)
+{
+
+ logInfo("getCreateFunction : Trying to load library with name: ",libname);
+
+ // cut off directories
+ char* fileWithPath = const_cast<char*>(libname.c_str());
+ std::string libFileName = basename(fileWithPath);
+
+ // cut off "lib" in front and cut off .so end"
+ std::string createFunctionName = libFileName.substr(3, libFileName.length() - 6) + "Factory";
+ // open library
+ dlerror(); // Clear any existing error
+ libraryHandle = dlopen(libname.c_str(), RTLD_LAZY );
+ const char* dlopen_error = dlerror();
+ if (!libraryHandle || dlopen_error)
+ {
+ logError("getCreateFunction : dlopen failed",dlopen_error);
+ return (0);
+ }
+
+ // get entry point from shared lib
+ dlerror(); // Clear any existing error
+
+ union
+ {
+ void* voidPointer;
+ T* typedPointer;
+ } functionPointer;
+
+ // Note: direct cast is not allowed by ISO C++. e.g.
+ // T* createFunction = reinterpret_cast<T*>(dlsym(libraryHandle, createFunctionName.c_str()));
+ // compiler warning: "forbids casting between pointer-to-function and pointer-to-object"
+
+ functionPointer.voidPointer = dlsym(libraryHandle, createFunctionName.c_str());
+ T* createFunction = functionPointer.typedPointer;
+
+ const char* dlsym_error = dlerror();
+ if (!createFunction || dlsym_error)
+ {
+ logError("getCreateFunction: Failed to load shared lib entry point",dlsym_error);
+ }
+ else
+ {
+ logInfo("getCreateFunction : loaded successfully plugin", createFunctionName);
+ }
+ return (createFunction);
+}
+
+}
+
+#endif /* PLUGINTEMPLATE_H_ */
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++;
+ }
+}
+}
+
diff --git a/AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp b/AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp
new file mode 100644
index 0000000..9008ce6
--- /dev/null
+++ b/AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp
@@ -0,0 +1,673 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmControlInterfaceTest.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <set>
+#include "CAmDltWrapper.h"
+#include "CAmCommandLineSingleton.h"
+
+using namespace am;
+using namespace testing;
+
+DLT_DECLARE_CONTEXT(AudioManager)
+TCLAP::SwitchArg enableNoDLTDebug ("V","logDlt","print DLT logs to stdout or dlt-daemon default off",false);
+
+ACTION(returnResyncConnection)
+{
+ std::vector<am_Connection_s> listConnections;
+ am_Connection_s conn;
+ conn.sinkID=1;
+ conn.sourceID=1;
+ conn.connectionFormat=CF_GENIVI_ANALOG;
+ listConnections.push_back(conn);
+ arg1=listConnections;
+}
+
+CAmControlInterfaceTest::CAmControlInterfaceTest() :
+ pSocketHandler(), //
+ plistCommandPluginDirs(), //
+ plistRoutingPluginDirs(), //
+ pDatabaseHandler(), //
+ pRoutingSender(plistRoutingPluginDirs), //RoutingReceiver
+ pCommandSender(plistCommandPluginDirs), //
+ pMockControlInterface(), //
+ pMockRoutingInterface(), //
+ pRoutingInterfaceBackdoor(), //
+ pCommandInterfaceBackdoor(), //
+ pControlInterfaceBackdoor(), //
+ pControlSender(), //
+ pRouter(&pDatabaseHandler,&pControlSender), //
+ pDatabaseObserver(&pCommandSender, &pRoutingSender, &pSocketHandler), //
+ pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender, &pSocketHandler, &pRouter), //
+ pRoutingReceiver(&pDatabaseHandler, &pRoutingSender, &pControlSender, &pSocketHandler)
+{
+ pDatabaseHandler.registerObserver(&pDatabaseObserver);
+ pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface);
+ pRoutingInterfaceBackdoor.injectInterface(&pRoutingSender, &pMockRoutingInterface, "mock");
+
+}
+
+CAmControlInterfaceTest::~CAmControlInterfaceTest()
+{
+ CAmDltWrapper::instance()->unregisterContext(AudioManager);
+}
+
+void CAmControlInterfaceTest::SetUp()
+{
+
+}
+
+void CAmControlInterfaceTest::TearDown()
+{
+}
+
+TEST_F(CAmControlInterfaceTest,registerDomain)
+{
+
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ pCF.createDomain(domain);
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemRegisterDomain(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
+ ASSERT_EQ(E_OK, pRoutingReceiver.registerDomain(domain,domainID));
+ ASSERT_EQ(domainID, 2);
+}
+
+TEST_F(CAmControlInterfaceTest,deregisterDomain)
+{
+ am_domainID_t domainID = 34;
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemDeregisterDomain(34)).WillRepeatedly(Return(E_OK));
+ ASSERT_EQ(E_OK, pRoutingReceiver.deregisterDomain(domainID));
+}
+
+TEST_F(CAmControlInterfaceTest,registerSink)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemRegisterSink(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
+ ASSERT_EQ(E_OK, pRoutingReceiver.registerSink(sink,sinkID));
+ ASSERT_EQ(sinkID, 2);
+}
+
+TEST_F(CAmControlInterfaceTest,deregisterSink)
+{
+ am_sinkID_t sinkID = 12;
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemDeregisterSink(12)).WillRepeatedly(Return(E_OK));
+ ASSERT_EQ(E_OK, pRoutingReceiver.deregisterSink(sinkID));
+}
+
+TEST_F(CAmControlInterfaceTest,registerSource)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemRegisterSource(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
+ ASSERT_EQ(E_OK, pRoutingReceiver.registerSource(source,sourceID));
+ ASSERT_EQ(sourceID, 2);
+}
+
+TEST_F(CAmControlInterfaceTest,deregisterSource)
+{
+ am_sourceID_t sourceID = 12;
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemDeregisterSource(12)).WillRepeatedly(Return(E_OK));
+ ASSERT_EQ(E_OK, pRoutingReceiver.deregisterSource(sourceID));
+}
+
+TEST_F(CAmControlInterfaceTest,registerGateway)
+{
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+ pCF.createGateway(gateway);
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemRegisterGateway(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
+ ASSERT_EQ(E_OK, pRoutingReceiver.registerGateway(gateway,gatewayID));
+ ASSERT_EQ(gatewayID, 2);
+}
+
+TEST_F(CAmControlInterfaceTest,deregisterGateway)
+{
+ am_gatewayID_t gatewayID = 12;
+
+ //When we run this test, we expect the call on the control interface
+ EXPECT_CALL(pMockControlInterface,hookSystemDeregisterGateway(12)).WillRepeatedly(Return(E_OK));
+ ASSERT_EQ(E_OK, pRoutingReceiver.deregisterGateway(gatewayID));
+}
+
+TEST_F(CAmControlInterfaceTest,ackConnect)
+{
+ am_connectionID_t connectionID;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Connection_s> connectionList;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //when asyncConnect is called, we expect a call on the routingInterface
+ EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_GENIVI_STEREO)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2));
+
+ //The handle should have the correct type
+ ASSERT_EQ(handle.handleType, H_CONNECT);
+ ASSERT_EQ(handle.handle, 1);
+ ASSERT_EQ(connectionID, 1);
+
+ //The list of handles shall have the handle inside
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_EQ(handlesList[0].handle, handle.handle);
+ ASSERT_EQ(handlesList[0].handleType, handle.handleType);
+
+ //we check the list of connections - but it must be empty because the ack did not arrive yet
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(connectionList.empty());
+
+ //finally we answer via the RoutingInterface and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
+ pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
+
+ //the list of handles must be empty now
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //but the connection must be in the connectionlist
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(!connectionList.empty());
+
+ //no we try the same, but do expect a no_change answer directly and no call because connection already exists
+ //ASSERT_EQ(E_ALREADY_EXISTS, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2));
+ //needed to be removed because logic changed here
+}
+
+TEST_F(CAmControlInterfaceTest,ackDisconnect)
+{
+ am_connectionID_t connectionID;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Connection_s> connectionList;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //now we first need to connect, we expect a call on the routing interface
+ EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_GENIVI_STEREO)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2));
+
+ //answer with an ack to insert the connection in the database
+ EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
+ pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
+
+ //now we can start to disconnect and expect a call on the routing interface
+ EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1));
+
+ //during the disconnection, the connection is still in the list!
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(!connectionList.empty());
+
+ //then we fire the ack and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckDisconnect(_,E_OK)).Times(1);
+ pRoutingReceiver.ackDisconnect(handle, connectionID, E_OK);
+
+ //make sure the handle is gone
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //make sure the connection is gone
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(connectionList.empty());
+
+ //Now let's try to disconnect what is not existing...
+ ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.disconnect(handle,2));
+}
+
+TEST_F(CAmControlInterfaceTest,ackDisconnectFailAndRetry)
+{
+ logInfo("ackDisconnectFailAndRetry test started");
+ am_connectionID_t connectionID;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Connection_s> connectionList;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //now we first need to connect, we expect a call on the routing interface
+ EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_GENIVI_STEREO)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2));
+
+ //answer with an ack to insert the connection in the database
+ EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
+ pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
+
+ //now we can start to disconnect and expect a call on the routing interface
+ EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1));
+
+ //during the disconnection, the connection is still in the list!
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(!connectionList.empty());
+
+ //then we fire the ack and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckDisconnect(_,E_NON_EXISTENT)).Times(1);
+ pRoutingReceiver.ackDisconnect(handle, connectionID+1, E_NON_EXISTENT);
+
+ //make sure the handle is gone
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //make sure the connection is still there
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_FALSE(connectionList.empty());
+
+ ASSERT_TRUE(pDatabaseHandler.existConnectionID(1));
+
+ //Now let's try to disconnect now
+ EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1));
+ logInfo("ackDisconnectFailAndRetry test finished");
+}
+
+TEST_F(CAmControlInterfaceTest,setSourceState)
+{
+
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ am_SourceState_e state;
+ pCF.createSource(source);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ source.sourceID = 2;
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ //we set the sourcestate and expect a call on the routingInterface
+ EXPECT_CALL(pMockRoutingInterface,asyncSetSourceState(_,2,SS_PAUSED)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSourceState(handle,source.sourceID,SS_PAUSED));
+
+ //we want our handle in the list and let the type be the right one
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_EQ(handlesList[0].handle, handle.handle);
+ ASSERT_EQ(handlesList[0].handleType, H_SETSOURCESTATE);
+
+ //the state must be unchanged because did not get the ack
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSoureState(source.sourceID,state));
+ ASSERT_EQ(state, SS_ON);
+
+ //now we sent out the ack and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckSetSourceState(_,E_OK)).Times(1);
+ pRoutingReceiver.ackSetSourceState(handle, E_OK);
+
+ //finally we need the sourcestate to be changed
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSoureState(source.sourceID,state));
+ ASSERT_EQ(state, SS_PAUSED);
+
+ //make sure the handle is gone
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //we try again but expect a no change error
+ //ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceState(handle,source.sourceID,SS_PAUSED));
+ //needed to be removed because logic changed here
+}
+
+TEST_F(CAmControlInterfaceTest,SetSinkVolumeChange)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_volume_t volume;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ sink.volume = 10;
+
+ //setup environment, we need a domain and a sink
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //set the volume and expect a call on the routing interface
+ EXPECT_CALL(pMockRoutingInterface,asyncSetSinkVolume(_,2,11,RAMP_GENIVI_DIRECT,23)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSinkVolume(handle,sinkID,11,RAMP_GENIVI_DIRECT,23));
+
+ //check the list of handles. The handle must be in there and have the right type
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_EQ(handlesList[0].handle, handle.handle);
+ ASSERT_EQ(handlesList[0].handleType, H_SETSINKVOLUME);
+
+ //now we read out the volume, but we expect no change because the ack did not arrive yet
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkVolume(sinkID,volume));
+ ASSERT_EQ(sink.volume, volume);
+
+ //lets send the answer and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckSetSinkVolumeChange(_,11,E_OK)).Times(1);
+ pRoutingReceiver.ackSetSinkVolumeChange(handle, 11, E_OK);
+
+ //finally, the new value must be in the database
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkVolume(sinkID,volume));
+ ASSERT_EQ(11, volume);
+
+ //and the handle must be destroyed
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //Now we try again, but the value is unchanged
+ //ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkVolume(handle,sinkID,11,RAMP_GENIVI_DIRECT,23));
+ //needed to be removed because logic changed here
+}
+
+TEST_F(CAmControlInterfaceTest,ackSetSourceVolumeChange)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_volume_t volume;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSource(source);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ source.sourceID = 2;
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+ source.volume = 12;
+
+ //prepare the scene
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ //change the sinkVolume, expect a call on the routingInterface
+ EXPECT_CALL(pMockRoutingInterface,asyncSetSourceVolume(_,2,11,RAMP_GENIVI_DIRECT,23)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSourceVolume(handle,source.sourceID,11,RAMP_GENIVI_DIRECT,23));
+
+ //check the list of handles. The handle must be in there and have the right type
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_EQ(handlesList[0].handle, handle.handle);
+ ASSERT_EQ(handlesList[0].handleType, H_SETSOURCEVOLUME);
+
+ //now we read out the volume, but we expect no change because the ack did not arrive yet
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceVolume(sourceID,volume));
+ ASSERT_EQ(source.volume, volume);
+
+ //lets send the answer and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckSetSourceVolumeChange(_,11,E_OK)).Times(1);
+ pRoutingReceiver.ackSetSourceVolumeChange(handle, 11, E_OK);
+
+ //finally, the new value must be in the database
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceVolume(sourceID,volume));
+ ASSERT_EQ(11, volume);
+
+ //and the handle must be destroyed
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //Now we try again, but the value is unchanged
+ //ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceVolume(handle,source.sourceID,11,RAMP_GENIVI_DIRECT,23));
+ //needed to be removed because logic changed here
+}
+
+TEST_F(CAmControlInterfaceTest,ackSetSinkSoundProperty)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ am_SoundProperty_s soundProperty;
+ int16_t oldvalue;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ soundProperty.type = SP_GENIVI_BASS;
+ soundProperty.value = 244;
+
+ //setup environment, we need a domain and a sink
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //change the soundproperty, expect a call on the routinginterface
+ EXPECT_CALL(pMockRoutingInterface,asyncSetSinkSoundProperty(_,2,_)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSinkSoundProperty(handle,sink.sinkID,soundProperty));
+
+ //check the list of handles. The handle must be in there and have the right type
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_EQ(handlesList[0].handle, handle.handle);
+ ASSERT_EQ(handlesList[0].handleType, H_SETSINKSOUNDPROPERTY);
+
+ //read out this property. There is no change, because the ack did not arrive yet.
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(2,SP_GENIVI_BASS,oldvalue));
+ ASSERT_EQ(sink.listSoundProperties[0].value, oldvalue);
+
+ //lets send the answer and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckSetSinkSoundProperty(_,E_OK)).Times(1);
+ pRoutingReceiver.ackSetSinkSoundProperty(handle, E_OK);
+
+ //finally, the new value must be in the database
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(sinkID,SP_GENIVI_BASS,oldvalue));
+ ASSERT_EQ(soundProperty.value, oldvalue);
+
+ //and the handle must be destroyed
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //Now we try again, but the value is unchanged
+ //ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkSoundProperty(handle,sink.sinkID,soundProperty));
+ //needed to be removed because logic changed here
+}
+
+TEST_F(CAmControlInterfaceTest,ackSetSourceSoundProperty)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ am_SoundProperty_s soundProperty;
+ int16_t oldvalue;
+ pCF.createSource(source);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ source.sourceID = 2;
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+ soundProperty.type = SP_GENIVI_BASS;
+ soundProperty.value = 244;
+
+ //prepare the scene
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ //we trigger the change and wait for a call on the routinginterface
+ EXPECT_CALL(pMockRoutingInterface,asyncSetSourceSoundProperty(_,2,_)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSourceSoundProperty(handle,source.sourceID,soundProperty));
+
+ //check the list of handles. The handle must be in there and have the right type
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_EQ(handlesList[0].handle, handle.handle);
+ ASSERT_EQ(handlesList[0].handleType, H_SETSOURCESOUNDPROPERTY);
+
+ //read out this property. There is no change, because the ack did not arrive yet.
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(2,SP_GENIVI_BASS,oldvalue));
+ ASSERT_EQ(source.listSoundProperties[0].value, oldvalue);
+
+ //lets send the answer and expect a call on the controlInterface
+ EXPECT_CALL(pMockControlInterface,cbAckSetSourceSoundProperty(_,E_OK)).Times(1);
+ pRoutingReceiver.ackSetSourceSoundProperty(handle, E_OK);
+
+ //finally, the new value must be in the database
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(sourceID,SP_GENIVI_BASS,oldvalue));
+ ASSERT_EQ(soundProperty.value, oldvalue);
+
+ //and the handle must be destroyed
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+ //Now we try again, but the value is unchanged
+ //ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceSoundProperty(handle,source.sourceID,soundProperty));
+ //needed to be removed because logic changed here
+}
+
+TEST_F(CAmControlInterfaceTest,crossFading)
+{
+ //todo: implement crossfading test
+}
+
+TEST_F(CAmControlInterfaceTest,resyncConnectionsTest)
+{
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+
+ //prepare the scene
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+
+ std::vector<am_Connection_s> listConnections;
+
+ EXPECT_CALL(pMockRoutingInterface,resyncConnectionState(domainID,_)).WillOnce(DoAll(returnResyncConnection(), Return(E_OK)));
+ ASSERT_EQ(am_Error_e::E_OK,pControlReceiver.resyncConnectionState(domainID,listConnections));
+ ASSERT_EQ(listConnections[0].sinkID,1);
+ ASSERT_EQ(listConnections[0].sourceID,1);
+ ASSERT_EQ(listConnections[0].connectionFormat,CF_GENIVI_ANALOG);
+}
+
+TEST_F(CAmControlInterfaceTest,ackConnectNotPossible)
+{
+ am_connectionID_t connectionID;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Connection_s> connectionList;
+ std::vector<am_Handle_s> handlesList;
+ am_Handle_s handle;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //when asyncConnect is called, we expect a call on the routingInterface
+ EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_GENIVI_STEREO)).WillOnce(Return(E_COMMUNICATION));
+ ASSERT_EQ(E_COMMUNICATION, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2));
+
+ //The list of handles shall be empty
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
+ ASSERT_TRUE(handlesList.empty());
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(connectionList.empty());
+
+}
+
+int main(int argc, char **argv)
+{
+ try
+ {
+ TCLAP::CmdLine* cmd(CAmCommandLineSingleton::instanciateOnce("The team of the AudioManager wishes you a nice day!",' ',DAEMONVERSION,true));
+ cmd->add(enableNoDLTDebug);
+ }
+ catch (TCLAP::ArgException &e) // catch any exceptions
+ { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
+ CAmCommandLineSingleton::instance()->preparse(argc,argv);
+ CAmDltWrapper::instance(enableNoDLTDebug.getValue())->registerApp("AudioManagerDeamon", "AudioManagerDeamon");
+ CAmDltWrapper::instance()->registerContext(AudioManager, "Main", "Main Context");
+ logInfo("RoutingSendInterface Test started");
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.h b/AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.h
new file mode 100644
index 0000000..b7fa27a
--- /dev/null
+++ b/AudioManagerCore/test/AmControlInterfaceTest/CAmControlInterfaceTest.h
@@ -0,0 +1,76 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef ROUTINGINTERFACETEST_H_
+#define ROUTINGINTERFACETEST_H_
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+//#include "CAmDatabaseHandlerSQLite.h"
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmControlReceiver.h"
+#include "CAmRoutingReceiver.h"
+#include "CAmDatabaseObserver.h"
+#include "CAmControlSender.h"
+#include "CAmRoutingSender.h"
+#include "CAmRouter.h"
+#include "../IAmRoutingBackdoor.h"
+#include "../IAmCommandBackdoor.h"
+#include "../IAmControlBackdoor.h"
+#include "../CAmCommonFunctions.h"
+#include "../MockIAmRoutingSend.h"
+#include "../MockIAmControlSend.h"
+#include "CAmSocketHandler.h"
+
+namespace am
+{
+
+class CAmControlInterfaceTest: public ::testing::Test
+{
+public:
+ CAmControlInterfaceTest();
+ ~CAmControlInterfaceTest();
+ CAmSocketHandler pSocketHandler;
+ std::vector<std::string> plistCommandPluginDirs;
+ std::vector<std::string> plistRoutingPluginDirs;
+ CAmDatabaseHandlerMap pDatabaseHandler;
+ CAmRoutingSender pRoutingSender;
+ CAmCommandSender pCommandSender;
+ MockIAmControlSend pMockControlInterface;
+ MockIAmRoutingSend pMockRoutingInterface;
+ IAmRoutingBackdoor pRoutingInterfaceBackdoor;
+ IAmCommandBackdoor pCommandInterfaceBackdoor;
+ IAmControlBackdoor pControlInterfaceBackdoor;
+ CAmControlSender pControlSender;
+ CAmRouter pRouter;
+ CAmDatabaseObserver pDatabaseObserver;
+ CAmControlReceiver pControlReceiver;
+ CAmRoutingReceiver pRoutingReceiver;
+ CAmCommonFunctions pCF;
+ void SetUp();
+ void TearDown();
+};
+
+}
+
+#endif /* ROUTINGINTERFACETEST_H_ */
diff --git a/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt b/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt
new file mode 100644
index 0000000..4f33ac5
--- /dev/null
+++ b/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt
@@ -0,0 +1,52 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmControlInterfaceTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+
+ file(GLOB CONTROL_INTERFACE_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+)
+
+add_executable(AmControlInterfaceTest ${CONTROL_INTERFACE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmControlInterfaceTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+add_test(AmControlInterfaceTest AmControlInterfaceTest)
+
+ADD_DEPENDENCIES(AmControlInterfaceTest AudioManagerCore)
+
+INSTALL(TARGETS AmControlInterfaceTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests)
+
+
+
+
diff --git a/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt~ b/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt~
new file mode 100644
index 0000000..5b71a59
--- /dev/null
+++ b/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt~
@@ -0,0 +1,50 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmControlInterfaceTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+
+ file(GLOB CONTROL_INTERFACE_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+)
+
+add_executable(AmControlInterfaceTest ${CONTROL_INTERFACE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmControlInterfaceTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmControlInterfaceTest AudioManagerCore)
+
+INSTALL(TARGETS AmControlInterfaceTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests)
+
+
+
+
diff --git a/AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.cpp b/AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.cpp
new file mode 100644
index 0000000..337ecb7
--- /dev/null
+++ b/AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.cpp
@@ -0,0 +1,3276 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmMapHandlerTest.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <set>
+#include <ios>
+#include "CAmDltWrapper.h"
+#include "CAmCommandLineSingleton.h"
+
+using namespace am;
+using namespace testing;
+
+
+extern bool equalMainSoundProperty(const am_MainSoundProperty_s a, const am_MainSoundProperty_s b);
+extern bool equalNotificationConfiguration(const am_NotificationConfiguration_s a, const am_NotificationConfiguration_s b);
+extern bool equalClassProperties(const am_ClassProperty_s a, const am_ClassProperty_s b);
+extern std::string int2string(int i);
+
+int16_t const TEST_MAX_CONNECTION_ID = 20;
+int16_t const TEST_MAX_MAINCONNECTION_ID = 20;
+int16_t const TEST_MAX_SINK_ID = 40;
+
+TCLAP::SwitchArg enableNoDLTDebug ("V","logDlt","print DLT logs to stdout or dlt-daemon default off",false);
+
+
+CAmMapBasicTest::CAmMapBasicTest() :
+ plistRoutingPluginDirs(), //
+ plistCommandPluginDirs(), //
+ pSocketHandler(),//
+ pDatabaseHandler(), //
+ pRoutingSender(plistRoutingPluginDirs), //
+ pCommandSender(plistCommandPluginDirs), //
+ pRoutingInterfaceBackdoor(), //
+ pCommandInterfaceBackdoor(), //
+ pControlSender(), //
+ pRouter(&pDatabaseHandler, &pControlSender), //
+ pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender, &pSocketHandler, &pRouter), //
+ pCF()
+{
+}
+
+CAmMapBasicTest::~CAmMapBasicTest()
+{
+}
+
+void CAmMapBasicTest::createMainConnectionSetup(am_mainConnectionID_t & mainConnectionID, am_MainConnection_s & mainConnection)
+{
+ //fill the connection database
+ am_Connection_s connection;
+ am_Source_s source;
+ am_Sink_s sink;
+ std::vector<am_connectionID_t> connectionList;
+
+ //we create 9 sources and sinks:
+
+ for (uint16_t i = 1; i < 10; i++)
+ {
+ am_sinkID_t forgetSink;
+ am_sourceID_t forgetSource;
+ am_connectionID_t connectionID;
+
+ pCF.createSink(sink);
+ sink.sinkID = i;
+ sink.name = "sink" + int2string(i);
+ sink.domainID = 4;
+ pCF.createSource(source);
+ source.sourceID = i;
+ source.name = "source" + int2string(i);
+ source.domainID = 4;
+
+ connection.sinkID = i;
+ connection.sourceID = i;
+ connection.delay = -1;
+ connection.connectionFormat = CF_GENIVI_ANALOG;
+ connection.connectionID = 0;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,forgetSink));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,forgetSource));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+ connectionList.push_back(connectionID);
+ }
+
+ //create a mainConnection
+ std::vector<am_MainConnection_s> mainConnectionList;
+ mainConnection.listConnectionID = connectionList;
+ mainConnection.mainConnectionID = 0;
+ mainConnection.sinkID = 1;
+ mainConnection.sourceID = 1;
+ mainConnection.connectionState = CS_CONNECTED;
+ mainConnection.delay = -1;
+
+ //enter mainconnection in database
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterMainConnectionDB(mainConnection,mainConnectionID));
+ ASSERT_NE(0, mainConnectionID);
+
+ //read out the mainconnections and check if they are equal to the data written.
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainConnections(mainConnectionList));
+ std::vector<am_MainConnection_s>::iterator listIterator = mainConnectionList.begin();
+ for (; listIterator < mainConnectionList.end(); ++listIterator)
+ {
+ if (listIterator->mainConnectionID == mainConnectionID)
+ {
+ ASSERT_EQ(listIterator->connectionState, mainConnection.connectionState);
+ ASSERT_EQ(listIterator->sinkID, mainConnection.sinkID);
+ ASSERT_EQ(listIterator->sourceID, mainConnection.sourceID);
+ ASSERT_EQ(listIterator->delay, mainConnection.delay);
+ ASSERT_TRUE(std::equal(listIterator->listConnectionID.begin(), listIterator->listConnectionID.end(), connectionList.begin()));
+ }
+ }
+}
+
+void CAmMapBasicTest::SetUp()
+{
+ ::testing::FLAGS_gmock_verbose = "error";
+}
+
+void CAmMapBasicTest::TearDown()
+{
+ ::testing::FLAGS_gmock_verbose = "warning";
+}
+
+
+
+CAmMapHandlerTest::CAmMapHandlerTest() :
+ pMockInterface(), //
+ pObserver(&pCommandSender,&pRoutingSender, &pSocketHandler)
+{
+ pDatabaseHandler.registerObserver(&pObserver);
+ pDatabaseHandler.setConnectionIDRange(1, TEST_MAX_CONNECTION_ID);
+ pDatabaseHandler.setMainConnectionIDRange(1, TEST_MAX_MAINCONNECTION_ID);
+ pDatabaseHandler.setSinkIDRange(DYNAMIC_ID_BOUNDARY, DYNAMIC_ID_BOUNDARY+TEST_MAX_SINK_ID);
+ pCommandInterfaceBackdoor.injectInterface(&pCommandSender, &pMockInterface);
+}
+
+CAmMapHandlerTest::~CAmMapHandlerTest()
+{
+}
+
+TEST_F(CAmMapHandlerTest,getMainConnectionInfo)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection, mainConnectionT;
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getMainConnectionInfoDB(mainConnectionID,mainConnectionT));
+ ASSERT_TRUE(mainConnection.connectionState == mainConnectionT.connectionState);
+ ASSERT_TRUE(mainConnection.delay == mainConnectionT.delay);
+ ASSERT_TRUE(std::equal(mainConnection.listConnectionID.begin(),mainConnection.listConnectionID.end(),mainConnectionT.listConnectionID.begin()));
+ ASSERT_TRUE(mainConnection.sinkID == mainConnectionT.sinkID);
+ ASSERT_TRUE(mainConnection.sourceID == mainConnectionT.sourceID);
+ ASSERT_TRUE(mainConnectionID == mainConnectionT.mainConnectionID);
+}
+
+TEST_F(CAmMapHandlerTest,getSinkInfo)
+{
+ //fill the connection database
+ am_Sink_s staticSink, firstDynamicSink, secondDynamicSink;
+ am_sinkID_t staticSinkID, firstDynamicSinkID, secondDynamicSinkID;
+ std::vector<am_Sink_s> sinkList;
+
+ pCF.createSink(staticSink);
+ staticSink.sinkID = 4;
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(staticSink,staticSinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(staticSink.sinkID,staticSinkID)
+ << "ERROR: ID not the one given in staticSink";
+
+ pCF.createSink(firstDynamicSink);
+ firstDynamicSink.name = "firstdynamic";
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(firstDynamicSink,firstDynamicSinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(firstDynamicSinkID,DYNAMIC_ID_BOUNDARY)
+ << "ERROR: ID not the one given in firstDynamicSink";
+
+ pCF.createSink(secondDynamicSink);
+ secondDynamicSink.name = "seconddynamic";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(secondDynamicSink,secondDynamicSinkID))
+ << "ERROR: database error";
+ ASSERT_NEAR(secondDynamicSinkID,DYNAMIC_ID_BOUNDARY,10)
+ << "ERROR: ID not the one given in secondDynamicSink";
+
+ //now read back and check the returns agains the given values
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinks(sinkList))
+ << "ERROR: database error";
+
+ std::vector<am_Sink_s>::iterator listIterator = sinkList.begin();
+ for (; listIterator < sinkList.end(); ++listIterator)
+ {
+ if (listIterator->sinkID == staticSinkID)
+ {
+ ASSERT_TRUE(pCF.compareSink(listIterator, staticSink));
+ }
+
+ if (listIterator->sinkID == firstDynamicSinkID)
+ {
+ ASSERT_TRUE(pCF.compareSink(listIterator, firstDynamicSink));
+ }
+
+ if (listIterator->sinkID == secondDynamicSinkID)
+ {
+ ASSERT_TRUE(pCF.compareSink(listIterator, secondDynamicSink));
+ }
+ }
+
+ am_Sink_s sinkData;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkInfoDB(secondDynamicSinkID,sinkData));
+ ASSERT_EQ(secondDynamicSink.available.availability, sinkData.available.availability);
+ ASSERT_EQ(secondDynamicSink.available.availabilityReason, sinkData.available.availabilityReason);
+ ASSERT_EQ(secondDynamicSink.sinkClassID, sinkData.sinkClassID);
+ ASSERT_EQ(secondDynamicSink.domainID, sinkData.domainID);
+ ASSERT_EQ(secondDynamicSink.visible, sinkData.visible);
+ ASSERT_EQ(0, secondDynamicSink.name.compare(sinkData.name));
+ ASSERT_EQ(secondDynamicSink.volume, sinkData.volume);
+ ASSERT_TRUE(std::equal(secondDynamicSink.listConnectionFormats.begin(), secondDynamicSink.listConnectionFormats.end(), sinkData.listConnectionFormats.begin()));
+ ASSERT_TRUE(std::equal(secondDynamicSink.listMainSoundProperties.begin(), secondDynamicSink.listMainSoundProperties.end(), sinkData.listMainSoundProperties.begin(), equalMainSoundProperty));
+ ASSERT_TRUE(std::equal(secondDynamicSink.listNotificationConfigurations.begin(), secondDynamicSink.listNotificationConfigurations.end(), sinkData.listNotificationConfigurations.begin(), equalNotificationConfiguration));
+ ASSERT_TRUE(std::equal(secondDynamicSink.listMainNotificationConfigurations.begin(), secondDynamicSink.listMainNotificationConfigurations.end(), sinkData.listMainNotificationConfigurations.begin(), equalNotificationConfiguration));
+}
+
+TEST_F(CAmMapHandlerTest,getSourceInfo)
+{
+ //fill the connection database
+ am_Source_s staticSource, firstDynamicSource, secondDynamicSource;
+ am_sourceID_t staticSourceID, firstDynamicSourceID, secondDynamicSourceID;
+ std::vector<am_Source_s> sourceList;
+
+ pCF.createSource(staticSource);
+ staticSource.sourceID = 4;
+ staticSource.name = "Static";
+
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(staticSource,staticSourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(staticSource.sourceID,staticSourceID)
+ << "ERROR: ID not the one given in staticSource";
+
+ pCF.createSource(firstDynamicSource);
+ firstDynamicSource.name = "firstDynamicSource";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(firstDynamicSource,firstDynamicSourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(firstDynamicSourceID,DYNAMIC_ID_BOUNDARY)
+ << "ERROR: ID not the one given in firstDynamicSink";
+
+
+ pCF.createSource(secondDynamicSource);
+ secondDynamicSource.name = "secondDynamicSource";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(secondDynamicSource,secondDynamicSourceID))
+ << "ERROR: database error";
+ ASSERT_NEAR(secondDynamicSourceID,DYNAMIC_ID_BOUNDARY,10)
+ << "ERROR: ID not the one given in secondDynamicSink";
+
+ //now read back and check the returns agains the given values
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSources(sourceList))
+ << "ERROR: database error";
+
+ std::vector<am_Source_s>::iterator listIterator = sourceList.begin();
+ for (; listIterator < sourceList.end(); ++listIterator)
+ {
+ if (listIterator->sourceID == staticSourceID)
+ {
+ ASSERT_TRUE(pCF.compareSource(listIterator, staticSource));
+ }
+
+ if (listIterator->sourceID == firstDynamicSourceID)
+ {
+ ASSERT_TRUE(pCF.compareSource(listIterator, firstDynamicSource));
+ }
+
+ if (listIterator->sourceID == secondDynamicSourceID)
+ {
+ ASSERT_TRUE(pCF.compareSource(listIterator, secondDynamicSource));
+ }
+ }
+
+ am_Source_s sourceData;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceInfoDB(secondDynamicSourceID,sourceData));
+ ASSERT_EQ(secondDynamicSource.available.availability, sourceData.available.availability);
+ ASSERT_EQ(secondDynamicSource.available.availabilityReason, sourceData.available.availabilityReason);
+ ASSERT_EQ(secondDynamicSource.sourceClassID, sourceData.sourceClassID);
+ ASSERT_EQ(secondDynamicSource.domainID, sourceData.domainID);
+ ASSERT_EQ(secondDynamicSource.interruptState, sourceData.interruptState);
+ ASSERT_EQ(secondDynamicSource.visible, sourceData.visible);
+ ASSERT_EQ(0, secondDynamicSource.name.compare(sourceData.name));
+ ASSERT_EQ(secondDynamicSource.volume, sourceData.volume);
+ ASSERT_TRUE(std::equal(secondDynamicSource.listConnectionFormats.begin(), secondDynamicSource.listConnectionFormats.end(), sourceData.listConnectionFormats.begin()));
+ ASSERT_TRUE(std::equal(secondDynamicSource.listMainSoundProperties.begin(), secondDynamicSource.listMainSoundProperties.end(), sourceData.listMainSoundProperties.begin(), equalMainSoundProperty));
+ ASSERT_TRUE(std::equal(secondDynamicSource.listMainNotificationConfigurations.begin(), secondDynamicSource.listMainNotificationConfigurations.end(), sourceData.listMainNotificationConfigurations.begin(), equalNotificationConfiguration));
+ ASSERT_TRUE(std::equal(secondDynamicSource.listNotificationConfigurations.begin(), secondDynamicSource.listNotificationConfigurations.end(), sourceData.listNotificationConfigurations.begin(), equalNotificationConfiguration));
+}
+
+TEST_F(CAmMapHandlerTest, peekSourceID)
+{
+
+ std::string sourceName("myClassID");
+ am_sourceClass_t sourceClassID, peekID;
+ am_SourceClass_s sourceClass;
+ am_ClassProperty_s classProperty;
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 13;
+ sourceClass.name = sourceName;
+ sourceClass.sourceClassID = 0;
+ sourceClass.listClassProperties.push_back(classProperty);
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.peekSourceClassID(sourceName,sourceClassID));
+
+ //now we enter the class into the database
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSourceClassID(sourceName,peekID));
+ ASSERT_EQ(sourceClassID, peekID);
+}
+
+TEST_F(CAmMapHandlerTest, peekSinkID)
+{
+
+ std::string sinkName("myClassID");
+ am_sinkClass_t sinkClassID, peekID;
+ am_SinkClass_s sinkClass;
+ am_ClassProperty_s classProperty;
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 13;
+ sinkClass.name = sinkName;
+ sinkClass.sinkClassID = 0;
+ sinkClass.listClassProperties.push_back(classProperty);
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.peekSinkClassID(sinkName,sinkClassID));
+
+ //now we enter the class into the database
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSinkClassID(sinkName,peekID));
+ ASSERT_EQ(sinkClassID, peekID);
+}
+
+TEST_F(CAmMapHandlerTest,crossfaders)
+{
+ am_Crossfader_s crossfader;
+ am_crossfaderID_t crossfaderID;
+ am_Sink_s sinkA, sinkB;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_sinkID_t sinkAID, sinkBID;
+ pCF.createSink(sinkA);
+ pCF.createSink(sinkB);
+ sinkB.name = "sinkB";
+ pCF.createSource(source);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sinkA,sinkAID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sinkB,sinkBID));
+
+ crossfader.crossfaderID = 0;
+ crossfader.hotSink = HS_SINKA;
+ crossfader.sinkID_A = sinkAID;
+ crossfader.sinkID_B = sinkBID;
+ crossfader.sourceID = sourceID;
+ crossfader.name = "Crossfader";
+ crossfader.hotSink = HS_UNKNOWN;
+
+ std::vector<am_Crossfader_s> listCrossfaders;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterCrossfaderDB(crossfader,crossfaderID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListCrossfaders(listCrossfaders));
+ ASSERT_EQ(crossfader.sinkID_A, listCrossfaders[0].sinkID_A);
+ ASSERT_EQ(crossfader.sinkID_B, listCrossfaders[0].sinkID_B);
+ ASSERT_EQ(crossfader.sourceID, listCrossfaders[0].sourceID);
+ ASSERT_EQ(crossfader.hotSink, listCrossfaders[0].hotSink);
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY, listCrossfaders[0].crossfaderID);
+ ASSERT_EQ(crossfader.name.compare(listCrossfaders[0].name), 0);
+}
+
+TEST_F(CAmMapHandlerTest,crossfadersGetFromDomain)
+{
+
+
+
+ am_Crossfader_s crossfader;
+ am_crossfaderID_t crossfaderID;
+ am_Sink_s sinkA, sinkB;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_sinkID_t sinkAID, sinkBID;
+ am_domainID_t domainID;
+ am_Domain_s domain;
+ pCF.createSink(sinkA);
+ pCF.createSink(sinkB);
+ pCF.createDomain(domain);
+ sinkB.name = "sinkB";
+ pCF.createSource(source);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ source.domainID = domainID;
+ sinkA.domainID = domainID;
+ sinkB.domainID = domainID;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sinkA,sinkAID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sinkB,sinkBID));
+
+ crossfader.crossfaderID = 0;
+ crossfader.hotSink = HS_SINKA;
+ crossfader.sinkID_A = sinkAID;
+ crossfader.sinkID_B = sinkBID;
+ crossfader.sourceID = sourceID;
+ crossfader.name = "Crossfader";
+ crossfader.hotSink = HS_UNKNOWN;
+
+ std::vector<am_crossfaderID_t> listCrossfaders;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterCrossfaderDB(crossfader,crossfaderID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListCrossfadersOfDomain(source.domainID,listCrossfaders));
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY, listCrossfaders[0]);
+
+}
+
+TEST_F(CAmMapHandlerTest,sourceState)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+ pCF.createSource(source);
+ source.sourceState = SS_OFF;
+
+ //prepare the test
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ //change the source state
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceState(sourceID,SS_ON));
+
+ //read out the changed values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(listSources[0].sourceState, SS_ON);
+}
+
+TEST_F(CAmMapHandlerTest,sinkVolumeChange)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+ pCF.createSink(sink);
+ sink.volume = 23;
+
+ //prepare the test
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //change the volume and check the read out
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkVolume(sinkID,34));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(listSinks[0].volume, 34);
+}
+
+TEST_F(CAmMapHandlerTest,sourceVolumeChange)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+ pCF.createSource(source);
+ source.volume = 23;
+
+ //prepare test
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ //change the volume and check the read out
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceVolume(sourceID,34));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(listSources[0].volume, 34);
+}
+
+TEST_F(CAmMapHandlerTest, peekSource)
+{
+ std::vector<am_SourceType_s> listSourceTypes;
+ std::vector<am_Source_s> listSources;
+ am_sourceID_t sourceID, source2ID, source3ID;
+ am_Source_s source;
+ pCF.createSource(source);
+
+ //peek a source that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSource(std::string("newsource"),sourceID));
+
+ //make sure it is not in the list
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_TRUE(listSources.empty());
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSources(listSourceTypes));
+ ASSERT_TRUE(listSourceTypes.empty());
+ ASSERT_EQ(sourceID, DYNAMIC_ID_BOUNDARY);
+
+ //now enter the source with the same name and make sure it does not get a new ID
+ source.name = "newsource";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,source2ID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(sourceID, source2ID);
+ ASSERT_FALSE(listSources.empty());
+ ASSERT_TRUE(listSources.at(0).sourceID==sourceID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSources(listSourceTypes));
+ ASSERT_FALSE(listSourceTypes.empty());
+ ASSERT_TRUE(listSourceTypes.at(0).sourceID==sourceID);
+
+ //now we peek again. This time, the source exists
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSource(source.name,source3ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_TRUE(listSources.size()==1);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSources(listSourceTypes));
+ ASSERT_TRUE(listSourceTypes.size()==1);
+ ASSERT_TRUE(listSourceTypes.at(0).sourceID==source3ID);
+ ASSERT_EQ(source3ID, source2ID);
+}
+
+TEST_F(CAmMapHandlerTest, peekSourceDouble)
+{
+ std::vector<am_SourceType_s> listSourceTypes;
+ std::vector<am_Source_s> listSources;
+ am_sourceID_t sourceID;
+ am_sourceID_t source2ID;
+ am_sourceID_t source3ID;
+ am_Source_s source;
+ pCF.createSource(source);
+
+ //peek a source that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSource(std::string("newsource"),sourceID));
+
+ //peek a second source that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSource(std::string("newsource2"),source2ID));
+
+ //make sure they are is not in the list
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_TRUE(listSources.empty());
+ ASSERT_EQ(sourceID, DYNAMIC_ID_BOUNDARY);
+ source.name = "newsource";
+
+ //now enter the source with the same name than the first peek and make sure it does not get a new ID
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,source3ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(sourceID, source3ID);
+ ASSERT_TRUE(listSources.size()==1);
+ ASSERT_TRUE(listSources[0].sourceID==sourceID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSources(listSourceTypes));
+ ASSERT_TRUE(listSourceTypes.size()==1);
+ ASSERT_TRUE(listSourceTypes[0].sourceID==source3ID);
+}
+
+TEST_F(CAmMapHandlerTest, peekSink)
+{
+ std::vector<am_SinkType_s> listSinkTypes;
+ std::vector<am_Sink_s> listSinks;
+ am_sinkID_t sinkID, sink2ID, sink3ID;
+ am_Sink_s sink;
+ pCF.createSink(sink);
+
+ //peek a sink that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSink(std::string("newsink"),sinkID));
+
+ //make sure it is not in the list
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_TRUE(listSinks.empty());
+ ASSERT_EQ(sinkID, DYNAMIC_ID_BOUNDARY);
+ sink.name = "newsink";
+
+ //now enter the source with the same name and make sure it does not get a new ID
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sink2ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(sinkID, sink2ID);
+ ASSERT_TRUE(listSinks[0].sinkID==sinkID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSinks(listSinkTypes));
+ ASSERT_FALSE(listSinkTypes.empty());
+ ASSERT_TRUE(listSinkTypes.at(0).sinkID==sinkID);
+
+ //now we peek again, this time, the sink exists
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSink(sink.name,sink3ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_TRUE(listSinks.size()==1);
+ ASSERT_EQ(sink3ID, sink2ID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSinks(listSinkTypes));
+ ASSERT_TRUE(listSinkTypes.size()==1);
+ ASSERT_TRUE(listSinkTypes.at(0).sinkID==sink3ID);
+}
+
+TEST_F(CAmMapHandlerTest, peekSinkDouble)
+{
+ std::vector<am_SinkType_s> listSinkTypes;
+ std::vector<am_Sink_s> listSinks;
+ am_sinkID_t sinkID;
+ am_sinkID_t sink2ID;
+ am_sinkID_t sink3ID;
+ am_Sink_s sink;
+ pCF.createSink(sink);
+
+ //peek a sink that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSink(std::string("newsink"),sinkID));
+
+ //peek again
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSink(std::string("nextsink"),sink2ID));
+
+ //make sure they are is not in the list
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_TRUE(listSinks.empty());
+ ASSERT_EQ(sinkID, DYNAMIC_ID_BOUNDARY);
+ sink.name = "newsink";
+
+ //now enter the sink with the same name than the first peek and make sure it does not get a new ID
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sink3ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(sinkID, sink3ID);
+ ASSERT_TRUE(listSinks[0].sinkID==sinkID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSinks(listSinkTypes));
+ ASSERT_TRUE(listSinkTypes.size()==1);
+ ASSERT_TRUE(listSinkTypes[0].sinkID==sink3ID);
+}
+
+TEST_F(CAmMapHandlerTest,changeConnectionTimingInformationCheckMainConnection)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ std::vector<am_Connection_s> connectionList;
+ std::vector<am_MainConnectionType_s> mainList;
+
+ //prepare the test, it is one mainconnection, so we expect one callback
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ //first get all visible mainconnections and make sure, the delay is set to -1 for the first entry
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListVisibleMainConnections(mainList));
+ ASSERT_EQ(mainList[0].delay, -1);
+
+ //no go through all connections and set the delay time to 24 for each connection
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ std::vector<am_Connection_s>::iterator iteratorConnectionList = connectionList.begin();
+ for (; iteratorConnectionList < connectionList.end(); ++iteratorConnectionList)
+ {
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionTimingInformation(iteratorConnectionList->connectionID,24));
+ }
+
+ //we read the result again and expect that the value is now different from -1
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListVisibleMainConnections(mainList));
+ ASSERT_EQ(mainList[0].delay, 216);
+}
+
+TEST_F(CAmMapHandlerTest,changeConnectionTimingInformation)
+{
+ am_Connection_s connection;
+ am_connectionID_t connectionID;
+ std::vector<am_Connection_s> connectionList;
+ pCF.createConnection(connection);
+
+ //enter a connection
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+
+ //change the timing and check it
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionTimingInformation(connectionID, 24));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_TRUE(connectionList[0].delay == 24);
+}
+
+TEST_F(CAmMapHandlerTest,getSinkClassOfSink)
+{
+ std::vector<am_SinkClass_s> sinkClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SinkClass_s sinkClass, returnClass;
+ am_ClassProperty_s classProperty;
+ am_sinkClass_t sinkClassID;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sinkClass.name = "test";
+ sinkClass.sinkClassID = 4;
+ sinkClass.listClassProperties = classPropertyList;
+ pCF.createSink(sink);
+ sink.sinkClassID = 4;
+
+ //prepare test
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //enter a new sinkclass, read out again and check
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_EQ(sinkClassList[0].name, sinkClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, 4);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkClassInfoDB(sinkID,returnClass));
+ ASSERT_EQ(sinkClassList[0].name, returnClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, returnClass.sinkClassID);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),returnClass.listClassProperties.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,getSourceClassOfSource)
+{
+ std::vector<am_SourceClass_s> sourceClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SourceClass_s sourceClass, sinkSourceClass;
+ am_ClassProperty_s classProperty;
+ am_sourceClass_t sourceClassID;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sourceClass.name = "test";
+ sourceClass.sourceClassID = 1;
+ sourceClass.listClassProperties = classPropertyList;
+ pCF.createSource(source);
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_EQ(sourceClassList[0].name, sourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, 1);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceClassInfoDB(sourceID,sinkSourceClass));
+ ASSERT_EQ(sourceClassList[0].name, sinkSourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, sinkSourceClass.sourceClassID);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),sinkSourceClass.listClassProperties.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,removeSourceClass)
+{
+ std::vector<am_SourceClass_s> sourceClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SourceClass_s sourceClass;
+ am_ClassProperty_s classProperty;
+ am_sourceClass_t sourceClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sourceClass.name = "test";
+ sourceClass.sourceClassID = 3;
+ sourceClass.listClassProperties = classPropertyList;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_EQ(sourceClassList[0].name, sourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, 3);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeSourceClassDB(3));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_TRUE(sourceClassList.empty());
+}
+
+TEST_F(CAmMapHandlerTest,updateSourceClass)
+{
+ std::vector<am_SourceClass_s> sourceClassList;
+ std::vector<am_ClassProperty_s> classPropertyList, changedPropertyList;
+ am_SourceClass_s sourceClass, changedClass;
+ am_ClassProperty_s classProperty;
+ am_sourceClass_t sourceClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sourceClass.name = "test";
+ sourceClass.sourceClassID = 0;
+ sourceClass.listClassProperties = classPropertyList;
+ changedClass = sourceClass;
+ changedClass.listClassProperties[1].value = 6;
+ changedPropertyList = changedClass.listClassProperties;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+ changedClass.sourceClassID = sourceClassID;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_EQ(sourceClassList[0].name, sourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceClassInfoDB(changedClass));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_EQ(sourceClassList[0].name, sourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),changedPropertyList.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,enterSourceClass)
+{
+ std::vector<am_SourceClass_s> sourceClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SourceClass_s sourceClass;
+ am_ClassProperty_s classProperty;
+ am_sourceClass_t sourceClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sourceClass.name = "test";
+ sourceClass.sourceClassID = 0;
+ sourceClass.listClassProperties = classPropertyList;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_EQ(sourceClassList[0].name, sourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,enterSourceClassStatic)
+{
+ std::vector<am_SourceClass_s> sourceClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SourceClass_s sourceClass;
+ am_ClassProperty_s classProperty;
+ am_sourceClass_t sourceClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sourceClass.name = "test";
+ sourceClass.sourceClassID = 3;
+ sourceClass.listClassProperties = classPropertyList;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSourceClasses(sourceClassList));
+ ASSERT_EQ(sourceClassList[0].name, sourceClass.name);
+ ASSERT_EQ(sourceClassList[0].sourceClassID, 3);
+ ASSERT_TRUE(std::equal(sourceClassList[0].listClassProperties.begin(),sourceClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,removeSinkClass)
+{
+ std::vector<am_SinkClass_s> sinkClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SinkClass_s sinkClass;
+ am_ClassProperty_s classProperty;
+ am_sinkClass_t sinkClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sinkClass.name = "test";
+ sinkClass.sinkClassID = 0;
+ sinkClass.listClassProperties = classPropertyList;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_EQ(sinkClassList[0].name, sinkClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeSinkClassDB(sinkClassID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_TRUE(sinkClassList.empty());
+}
+
+TEST_F(CAmMapHandlerTest,updateSinkClass)
+{
+ std::vector<am_SinkClass_s> sinkClassList;
+ std::vector<am_ClassProperty_s> classPropertyList, changedPropertyList;
+ am_SinkClass_s sinkClass, changedClass;
+ am_ClassProperty_s classProperty;
+ am_sinkClass_t sinkClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sinkClass.name = "test";
+ sinkClass.sinkClassID = 0;
+ sinkClass.listClassProperties = classPropertyList;
+ changedClass = sinkClass;
+ changedClass.listClassProperties[1].value = 6;
+ changedPropertyList = changedClass.listClassProperties;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+ changedClass.sinkClassID = sinkClassID;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_EQ(sinkClassList[0].name, sinkClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkClassInfoDB(changedClass));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_EQ(sinkClassList[0].name, sinkClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),changedPropertyList.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,enterSinkClass)
+{
+ std::vector<am_SinkClass_s> sinkClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SinkClass_s sinkClass;
+ am_ClassProperty_s classProperty;
+ am_sinkClass_t sinkClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sinkClass.name = "test";
+ sinkClass.sinkClassID = 0;
+ sinkClass.listClassProperties = classPropertyList;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_EQ(sinkClassList[0].name, sinkClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, DYNAMIC_ID_BOUNDARY);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest,enterSinkClassStatic)
+{
+ std::vector<am_SinkClass_s> sinkClassList;
+ std::vector<am_ClassProperty_s> classPropertyList;
+ am_SinkClass_s sinkClass;
+ am_ClassProperty_s classProperty;
+ am_sinkClass_t sinkClassID;
+ classProperty.classProperty = CP_GENIVI_SINK_TYPE;
+ classProperty.value = 1;
+ classPropertyList.push_back(classProperty);
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 4;
+ classPropertyList.push_back(classProperty);
+ sinkClass.name = "test";
+ sinkClass.sinkClassID = 4;
+ sinkClass.listClassProperties = classPropertyList;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinkClasses(sinkClassList));
+ ASSERT_EQ(sinkClassList[0].name, sinkClass.name);
+ ASSERT_EQ(sinkClassList[0].sinkClassID, 4);
+ ASSERT_TRUE(std::equal(sinkClassList[0].listClassProperties.begin(),sinkClassList[0].listClassProperties.end(),classPropertyList.begin(),equalClassProperties));
+}
+
+TEST_F(CAmMapHandlerTest, changeSystemProperty)
+{
+ std::vector<am_SystemProperty_s> listSystemProperties, listReturn;
+ am_SystemProperty_s systemProperty;
+
+ systemProperty.type = SYP_UNKNOWN;
+ systemProperty.value = 33;
+ listSystemProperties.push_back(systemProperty);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSystemProperties(listSystemProperties));
+ systemProperty.value = 444;
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSystemPropertyDB(systemProperty));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSystemProperties(listReturn));
+ ASSERT_EQ(listReturn[0].type, systemProperty.type);
+ ASSERT_EQ(listReturn[0].value, systemProperty.value);
+}
+
+TEST_F(CAmMapHandlerTest, systemProperties)
+{
+ std::vector<am_SystemProperty_s> listSystemProperties, listReturn;
+ am_SystemProperty_s systemProperty;
+
+ systemProperty.type = SYP_UNKNOWN;
+ systemProperty.value = 33;
+ listSystemProperties.push_back(systemProperty);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSystemProperties(listSystemProperties));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSystemProperties(listReturn));
+ ASSERT_EQ(listReturn[0].type, systemProperty.type);
+ ASSERT_EQ(listReturn[0].value, systemProperty.value);
+}
+
+TEST_F(CAmMapHandlerTest,enterSourcesCorrect)
+{
+ //fill the connection database
+ am_Source_s staticSource, firstDynamicSource, secondDynamicSource;
+ am_sourceID_t staticSourceID, firstDynamicSourceID, secondDynamicSourceID;
+ std::vector<am_Source_s> sourceList;
+
+ pCF.createSource(staticSource);
+ staticSource.sourceID = 4;
+ staticSource.name = "Static";
+
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(staticSource,staticSourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(staticSource.sourceID,staticSourceID)
+ << "ERROR: ID not the one given in staticSource";
+
+ pCF.createSource(firstDynamicSource);
+ firstDynamicSource.name = "firstDynamicSource";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(firstDynamicSource,firstDynamicSourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(firstDynamicSourceID,DYNAMIC_ID_BOUNDARY)
+ << "ERROR: ID not the one given in firstDynamicSink";
+
+ pCF.createSource(secondDynamicSource);
+ secondDynamicSource.name = "secondDynamicSource";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(secondDynamicSource,secondDynamicSourceID))
+ << "ERROR: database error";
+ ASSERT_NEAR(secondDynamicSourceID,DYNAMIC_ID_BOUNDARY,10)
+ << "ERROR: ID not the one given in secondDynamicSink";
+
+ //now read back and check the returns agains the given values
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSources(sourceList))
+ << "ERROR: database error";
+
+ std::vector<am_Source_s>::iterator listIterator = sourceList.begin();
+ for (; listIterator < sourceList.end(); ++listIterator)
+ {
+ if (listIterator->sourceID == staticSourceID)
+ {
+ ASSERT_TRUE(pCF.compareSource(listIterator, staticSource));
+ }
+
+ if (listIterator->sourceID == firstDynamicSourceID)
+ {
+ ASSERT_TRUE(pCF.compareSource(listIterator, firstDynamicSource));
+ }
+
+ if (listIterator->sourceID == secondDynamicSourceID)
+ {
+ ASSERT_TRUE(pCF.compareSource(listIterator, secondDynamicSource));
+ }
+
+ }
+}
+
+TEST_F(CAmMapHandlerTest, changeSinkMuteState)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ am_MuteState_e muteState = MS_MUTED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkMuteStateDB(muteState,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(muteState, listSinks[0].muteState);
+}
+
+TEST_F(CAmMapHandlerTest, changeSourceMainSoundProperty)
+{
+ std::vector<am_Source_s> listSources;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+ am_MainSoundProperty_s property;
+ property.type = MSP_UNKNOWN;
+ property.value = 33;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeMainSourceSoundPropertyDB(property,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+
+ std::vector<am_MainSoundProperty_s>::iterator listIterator = listSources[0].listMainSoundProperties.begin();
+ for (; listIterator < listSources[0].listMainSoundProperties.end(); ++listIterator)
+ {
+ if (listIterator->type == property.type)
+ ASSERT_EQ(listIterator->value, property.value);
+ }
+ int16_t value;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getMainSourceSoundPropertyValue(sourceID, property.type, value));
+ ASSERT_EQ(value, property.value);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeMainSourceSoundPropertyDB({property.type, 34},sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getMainSourceSoundPropertyValue(sourceID, property.type, value));
+ ASSERT_EQ(value, 34);
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.getMainSourceSoundPropertyValue(sourceID, 1000, value));
+}
+
+TEST_F(CAmMapHandlerTest, changeSinkMainSoundProperty)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ am_MainSoundProperty_s property;
+ property.type = MSP_UNKNOWN;
+ property.value = 33;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeMainSinkSoundPropertyDB(property,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ std::vector<am_MainSoundProperty_s>::iterator listIterator = listSinks[0].listMainSoundProperties.begin();
+ for (; listIterator < listSinks[0].listMainSoundProperties.end(); ++listIterator)
+ {
+ if (listIterator->type == property.type)
+ ASSERT_EQ(listIterator->value, property.value);
+ }
+
+ int16_t value;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getMainSinkSoundPropertyValue(sinkID, property.type, value));
+ ASSERT_EQ(value, property.value);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeMainSinkSoundPropertyDB({property.type, 34},sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getMainSinkSoundPropertyValue(sinkID, property.type, value));
+ ASSERT_EQ(value, 34);
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.getMainSinkSoundPropertyValue(sinkID, 1000, value));
+}
+
+TEST_F(CAmMapHandlerTest, changeSourceSoundProperty)
+{
+ std::vector<am_Source_s> listSources;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+ am_SoundProperty_s property;
+ property.type = SP_GENIVI_MID;
+ property.value = 33;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceSoundPropertyDB(property,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+
+ std::vector<am_SoundProperty_s>::iterator listIterator = listSources[0].listSoundProperties.begin();
+ for (; listIterator < listSources[0].listSoundProperties.end(); ++listIterator)
+ {
+ if (listIterator->type == property.type)
+ ASSERT_EQ(listIterator->value, property.value);
+ }
+ int16_t value;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(sourceID, property.type, value));
+ ASSERT_EQ(value, property.value);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceSoundPropertyDB({property.type, 34},sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(sourceID, property.type, value));
+ ASSERT_EQ(value, 34);
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.getSourceSoundPropertyValue(sourceID, 1000, value));
+}
+
+TEST_F(CAmMapHandlerTest, changeSinkSoundProperty)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ am_SoundProperty_s property;
+ property.type = SP_GENIVI_MID;
+ property.value = 33;
+
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkSoundPropertyDB(property,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ std::vector<am_SoundProperty_s>::iterator listIterator = listSinks[0].listSoundProperties.begin();
+ for (; listIterator < listSinks[0].listSoundProperties.end(); ++listIterator)
+ {
+ if (listIterator->type == property.type)
+ ASSERT_EQ(listIterator->value, property.value);
+ }
+
+ int16_t value;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(sinkID, property.type, value));
+ ASSERT_EQ(value, property.value);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkSoundPropertyDB({property.type, 34},sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(sinkID, property.type, value));
+ ASSERT_EQ(value, 34);
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.getSinkSoundPropertyValue(sinkID, 1000, value));
+}
+
+TEST_F(CAmMapHandlerTest, peekDomain)
+{
+ std::vector<am_Domain_s> listDomains;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_domainID_t domain2ID;
+ pCF.createDomain(domain);
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekDomain(std::string("newdomain"),domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_TRUE(listDomains.empty());
+ ASSERT_EQ(domainID, DYNAMIC_ID_BOUNDARY);
+ domain.name = "newdomain";
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domain2ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_EQ(domainID, domain2ID);
+ ASSERT_TRUE(listDomains[0].domainID==domainID);
+}
+
+TEST_F(CAmMapHandlerTest, peekDomainFirstEntered)
+{
+ std::vector<am_Domain_s> listDomains;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_domainID_t domain2ID;
+ pCF.createDomain(domain);
+ domain.name = "newdomain";
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekDomain(std::string("newdomain"),domain2ID));
+ ASSERT_EQ(domainID, domain2ID);
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_TRUE(listDomains.size()==1);
+}
+
+TEST_F(CAmMapHandlerTest, changeDomainState)
+{
+ std::vector<am_Domain_s> listDomains;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ pCF.createDomain(domain);
+ am_DomainState_e newState = DS_INDEPENDENT_STARTUP;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changDomainStateDB(newState,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_EQ(newState, listDomains[0].state);
+}
+
+TEST_F(CAmMapHandlerTest, changeMainConnectionState)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ std::vector<am_MainConnection_s> listMainConnections;
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeMainConnectionStateDB(1,CS_DISCONNECTING));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainConnections(listMainConnections));
+ ASSERT_EQ(CS_DISCONNECTING, listMainConnections[0].connectionState);
+}
+
+TEST_F(CAmMapHandlerTest, changeSinkAvailability)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ am_Availability_s availability;
+ availability.availability = A_UNKNOWN;
+ availability.availabilityReason = AR_GENIVI_TEMPERATURE;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkAvailabilityDB(availability,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(availability.availability, listSinks[0].available.availability);
+ ASSERT_EQ(availability.availabilityReason, listSinks[0].available.availabilityReason);
+}
+
+TEST_F(CAmMapHandlerTest, changeSourceAvailability)
+{
+ std::vector<am_Source_s> listSources;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+ am_Availability_s availability;
+ availability.availability = A_UNKNOWN;
+ availability.availabilityReason = AR_GENIVI_TEMPERATURE;
+ source.visible = true;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceAvailabilityDB(availability,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(availability.availability, listSources[0].available.availability);
+ ASSERT_EQ(availability.availabilityReason, listSources[0].available.availabilityReason);
+}
+
+TEST_F(CAmMapHandlerTest,changeMainConnectionRoute)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ std::vector<am_MainConnection_s> originalList;
+ std::vector<am_MainConnection_s> newList;
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ //fill the connection database
+ am_Connection_s connection;
+ am_Source_s source;
+ am_Sink_s sink;
+ std::vector<am_connectionID_t> listConnectionID;
+
+ uint16_t i = 1;
+ for (; i < 10; i++)
+ {
+ am_sinkID_t forgetSink;
+ am_sourceID_t forgetSource;
+ am_connectionID_t connectionID;
+
+ connection.sinkID = i + 20;
+ connection.sourceID = i + 20;
+ connection.delay = -1;
+ connection.connectionFormat = CF_GENIVI_ANALOG;
+ connection.connectionID = 0;
+
+ pCF.createSink(sink);
+ sink.sinkID = i + 20;
+ sink.name = "sink" + int2string(i + 20);
+ sink.domainID = 4;
+ pCF.createSource(source);
+ source.sourceID = i + 20;
+ source.name = "source" + int2string(i + 30);
+ source.domainID = 4;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,forgetSink));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,forgetSource));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ listConnectionID.push_back(connectionID);
+ }
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainConnections(originalList));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeMainConnectionRouteDB(mainConnectionID,listConnectionID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainConnections(newList));
+ ASSERT_FALSE(std::equal(newList[0].listConnectionID.begin(),newList[0].listConnectionID.end(),originalList[0].listConnectionID.begin()));
+}
+
+TEST_F(CAmMapHandlerTest,changeMainSinkVolume)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_mainVolume_t newVol = 20;
+ std::vector<am_Sink_s> listSinks;
+ pCF.createSink(sink);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkMainVolumeDB(newVol,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(listSinks[0].mainVolume, newVol);
+}
+
+TEST_F(CAmMapHandlerTest,getMainSourceSoundProperties)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+ std::vector<am_MainSoundProperty_s> mainSoundProperties = source.listMainSoundProperties;
+ std::vector<am_MainSoundProperty_s> listMainSoundProperties;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSourceSoundProperties(sourceID,listMainSoundProperties));
+ ASSERT_TRUE(std::equal(mainSoundProperties.begin(),mainSoundProperties.end(),listMainSoundProperties.begin(),equalMainSoundProperty));
+}
+
+TEST_F(CAmMapHandlerTest,getMainSinkSoundProperties)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ std::vector<am_MainSoundProperty_s> mainSoundProperties = sink.listMainSoundProperties;
+ std::vector<am_MainSoundProperty_s> listMainSoundProperties;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSinkSoundProperties(sinkID,listMainSoundProperties));
+ ASSERT_TRUE(std::equal(mainSoundProperties.begin(),mainSoundProperties.end(),listMainSoundProperties.begin(),equalMainSoundProperty));
+}
+
+TEST_F(CAmMapHandlerTest,getMainSources)
+{
+ am_Source_s source, source1, source2;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+ pCF.createSource(source1);
+ pCF.createSource(source2);
+ source1.name = "source1";
+ source2.name = "source2";
+ bool equal = true;
+ source1.visible = false;
+ std::vector<am_SourceType_s> listMainSources;
+ std::vector<am_Source_s> listSources;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ source.sourceID = sourceID;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source1,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source2,sourceID));
+ source2.sourceID = sourceID;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSources(listMainSources));
+ listSources.push_back(source);
+ listSources.push_back(source2);
+ std::vector<am_SourceType_s>::iterator listIterator = listMainSources.begin();
+ for (; listIterator < listMainSources.end(); ++listIterator)
+ {
+ equal = equal && pCF.compareSinkMainSource(listIterator, listSources);
+ }
+ ASSERT_TRUE(equal);
+}
+
+TEST_F(CAmMapHandlerTest,getMainSinks)
+{
+ am_Sink_s sink, sink1, sink2;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ pCF.createSink(sink1);
+ pCF.createSink(sink2);
+ sink1.name = "sink1";
+ sink2.name = "sink2";
+ sink1.visible = false;
+ std::vector<am_SinkType_s> listMainSinks;
+ std::vector<am_Sink_s> listSinks;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ sink.sinkID = sinkID;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink1,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink2,sinkID));
+ sink2.sinkID = sinkID;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainSinks(listMainSinks));
+ listSinks.push_back(sink);
+ listSinks.push_back(sink2);
+
+ std::vector<am_SinkType_s>::iterator listIterator = listMainSinks.begin();
+ for (; listIterator < listMainSinks.end(); ++listIterator)
+ {
+ ASSERT_TRUE(pCF.compareSinkMainSink(listIterator, listSinks));
+ }
+}
+
+TEST_F(CAmMapHandlerTest,getVisibleMainConnections)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ std::vector<am_MainConnectionType_s> listVisibleMainConnections;
+ std::vector<am_MainConnection_s> listMainConnections;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListVisibleMainConnections(listVisibleMainConnections));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListMainConnections(listMainConnections));
+ ASSERT_EQ(listMainConnections[0].mainConnectionID, listVisibleMainConnections[0].mainConnectionID);
+ ASSERT_EQ(listMainConnections[0].connectionState, listVisibleMainConnections[0].connectionState);
+ ASSERT_EQ(listMainConnections[0].delay, listVisibleMainConnections[0].delay);
+ ASSERT_EQ(listMainConnections[0].sinkID, listVisibleMainConnections[0].sinkID);
+ ASSERT_EQ(listMainConnections[0].sourceID, listVisibleMainConnections[0].sourceID);
+}
+
+TEST_F(CAmMapHandlerTest,getListSourcesOfDomain)
+{
+ am_Source_s source, source2;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_sourceID_t sourceID;
+ std::vector<am_sourceID_t> sourceList, sourceCheckList;
+ pCF.createSource(source);
+ source.sourceID = 1;
+ source.name = "testSource";
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+ pCF.createSource(source2);
+ source2.sourceID = 0;
+ source2.name = "testSource2";
+ source2.domainID = 5;
+ pCF.createDomain(domain);
+ sourceCheckList.push_back(1); //sink.sinkID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(source,sourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(source2,sourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.getListSourcesOfDomain(2,sourceList))
+ << "ERROR: database error";ASSERT_TRUE(sourceList.empty());
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSourcesOfDomain(DYNAMIC_ID_BOUNDARY,sourceList))
+ << "ERROR: database error";
+ ASSERT_TRUE(std::equal(sourceList.begin(),sourceList.end(),sourceCheckList.begin()) && !sourceList.empty());
+}
+
+TEST_F(CAmMapHandlerTest,getListSinksOfDomain)
+{
+ am_Sink_s sink, sink2;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_sinkID_t sinkID;
+ std::vector<am_sinkID_t> sinkList, sinkCheckList;
+ pCF.createSink(sink);
+ sink.sinkID = 1;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ pCF.createSink(sink2);
+ sink2.domainID = 5;
+ sink2.name = "sink2";
+ pCF.createDomain(domain);
+ sinkCheckList.push_back(1); //sink.sinkID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(sink,sinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(sink2,sinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.getListSinksOfDomain(DYNAMIC_ID_BOUNDARY+1,sinkList))
+ << "ERROR: database error";ASSERT_TRUE(sinkList.empty());
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinksOfDomain(DYNAMIC_ID_BOUNDARY,sinkList))
+ << "ERROR: database error";
+ ASSERT_TRUE(std::equal(sinkList.begin(),sinkList.end(),sinkCheckList.begin()) && !sinkList.empty());
+}
+
+TEST_F(CAmMapHandlerTest,getListGatewaysOfDomain)
+{
+ am_Gateway_s gateway, gateway2;
+ am_gatewayID_t gatewayID1, gatewayID2;
+ am_domainID_t domainID;
+ am_Domain_s domain;
+ std::vector<am_gatewayID_t> gatewayList, gatewayCheckList;
+
+ pCF.createDomain(domain);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+
+ pCF.createGateway(gateway);
+ gateway.gatewayID = 1;
+ gateway.name = "testGateway";
+ gateway.controlDomainID = domainID;
+ gateway.sourceID = 1;
+ gateway.sinkID = 1;
+ gateway.domainSinkID = 1;
+ gateway.domainSourceID = 1;
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway,gatewayID1))
+ << "ERROR: database error";
+ ASSERT_EQ(true, gatewayID1==1);
+
+ pCF.createGateway(gateway2);
+ gateway2.gatewayID = 2;
+ gateway2.name = "testGateway2";
+ gateway2.controlDomainID = 4;
+ gateway2.sourceID = 1;
+ gateway2.sinkID = 1;
+ gateway2.domainSinkID = 1;
+ gateway2.domainSourceID = 1;
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2))
+ << "ERROR: database error";
+ ASSERT_EQ(true, gatewayID2==2);
+ gatewayCheckList.push_back(gatewayID1);
+
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ sink.sinkID = sinkID;
+
+ pCF.createSource(source);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ source.sourceID = sourceID;
+
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.getListGatewaysOfDomain(2,gatewayList))
+ << "ERROR: database error";
+ ASSERT_TRUE(gatewayList.empty());
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListGatewaysOfDomain(domainID,gatewayList))
+ << "ERROR: database error";
+ ASSERT_TRUE(std::equal(gatewayList.begin(),gatewayList.end(),gatewayCheckList.begin()) && !gatewayList.empty());
+}
+
+TEST_F(CAmMapHandlerTest,getListConvertersOfDomain)
+{
+ am_Converter_s converter, converter2;
+ am_converterID_t converterID1, converterID2;
+ am_domainID_t domainID;
+ am_Domain_s domain;
+ std::vector<am_converterID_t> converterList, converterCheckList;
+
+ pCF.createDomain(domain);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+
+ pCF.createConverter(converter);
+ converter.converterID = 1;
+ converter.name = "testGateway";
+ converter.sourceID = 1;
+ converter.sinkID = 1;
+ converter.domainID = domainID;
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(converter,converterID1))
+ << "ERROR: database error";
+ ASSERT_EQ(true, converterID1==1);
+
+ pCF.createConverter(converter2);
+ converter2.converterID = 2;
+ converter2.name = "testGateway2";
+ converter2.domainID = 4;
+ converter2.sourceID = 1;
+ converter2.sinkID = 1;
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(converter2,converterID2))
+ << "ERROR: database error";
+ ASSERT_EQ(true, converterID2==2);
+ converterCheckList.push_back(converterID1);
+
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ sink.sinkID = sinkID;
+
+ pCF.createSource(source);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ source.sourceID = sourceID;
+
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.getListConvertersOfDomain(4,converterList))
+ << "ERROR: database error";
+ ASSERT_TRUE(converterList.empty());
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListConvertersOfDomain(domainID,converterList))
+ << "ERROR: database error";
+ ASSERT_TRUE(std::equal(converterList.begin(),converterList.end(),converterCheckList.begin()) && !converterList.empty());
+}
+
+TEST_F(CAmMapHandlerTest,removeDomain)
+{
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ std::vector<am_Domain_s> listDomains;
+ pCF.createDomain(domain);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterDomainDB(domain,domainID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeDomainDB(domainID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListDomains(listDomains))
+ << "ERROR: database error";
+ ASSERT_TRUE(listDomains.empty());
+}
+
+TEST_F(CAmMapHandlerTest,removeGateway)
+{
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+ std::vector<am_Gateway_s> listGateways;
+ pCF.createGateway(gateway);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway,gatewayID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeGatewayDB(gatewayID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListGateways(listGateways))
+ << "ERROR: database error";
+ ASSERT_TRUE(listGateways.empty());
+}
+
+TEST_F(CAmMapHandlerTest,removeConverter)
+{
+ am_Converter_s converter;
+ am_converterID_t converterID;
+ std::vector<am_Converter_s> listConverters;
+ pCF.createConverter(converter);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(converter,converterID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeConverterDB(converterID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListConverters(listConverters))
+ << "ERROR: database error";
+ ASSERT_TRUE(listConverters.empty());
+}
+
+TEST_F(CAmMapHandlerTest,removeSink)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+ pCF.createSink(sink);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(sink,sinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeSinkDB(sinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinks(listSinks))
+ << "ERROR: database error";
+ ASSERT_TRUE(listSinks.empty());
+}
+
+TEST_F(CAmMapHandlerTest,removeSource)
+{
+ //fill the connection database
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+ pCF.createSource(source);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(source,sourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeSourceDB(sourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSources(listSources))
+ << "ERROR: database error";
+ ASSERT_TRUE(listSources.empty());
+}
+
+TEST_F(CAmMapHandlerTest, removeMainConnection)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeMainConnectionDB(mainConnectionID))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,removeNonexistentMainConnectionFail)
+{
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.removeMainConnectionDB(34))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,removeNonexistentSource)
+{
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.removeSourceDB(3))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,removeNonexistentSink)
+{
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.removeSinkDB(2))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,removeNonexistentGateway)
+{
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.removeGatewayDB(12))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,removeNonexistentConverter)
+{
+ ASSERT_EQ(E_NON_EXISTENT,pDatabaseHandler.removeConverterDB(12))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,registerGatewayCorrect)
+{
+ //initialize gateway
+ std::vector<am_Gateway_s> returnList;
+ am_Gateway_s gateway, gateway1, gateway2;
+ am_gatewayID_t gatewayID = 0, gatewayID1 = 0, gatewayID2 = 0;
+
+ pCF.createGateway(gateway);
+ pCF.createGateway(gateway1);
+ gateway1.gatewayID = 20;
+ pCF.createGateway(gateway2);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway,gatewayID))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY,gatewayID)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1))
+ << "ERROR: database error";
+ ASSERT_EQ(gateway1.gatewayID,gatewayID1)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+1,gatewayID2)
+ << "ERROR: domainID zero";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListGateways(returnList));
+ std::vector<am_Gateway_s>::iterator listIterator = returnList.begin();
+
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->gatewayID == gatewayID)
+ {
+ ASSERT_TRUE(pCF.compareGateway(listIterator, gateway));
+ }
+
+ if (listIterator->gatewayID == gatewayID1)
+ {
+ ASSERT_TRUE(pCF.compareGateway(listIterator, gateway1));
+ }
+
+ if (listIterator->gatewayID == gatewayID2)
+ {
+ ASSERT_TRUE(pCF.compareGateway(listIterator, gateway2));
+ }
+ }
+}
+
+TEST_F(CAmMapHandlerTest,registerConverterCorrect)
+{
+ //initialize gateway
+ std::vector<am_Converter_s> returnList;
+ am_Converter_s gateway, gateway1, gateway2;
+ am_converterID_t gatewayID = 0, gatewayID1 = 0, gatewayID2 = 0;
+
+ pCF.createConverter(gateway);
+ pCF.createConverter(gateway1);
+ gateway1.converterID = 20;
+ pCF.createConverter(gateway2);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway,gatewayID))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY,gatewayID)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway1,gatewayID1))
+ << "ERROR: database error";
+ ASSERT_EQ(gateway1.converterID,gatewayID1)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway2,gatewayID2))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+1,gatewayID2)
+ << "ERROR: domainID zero";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConverters(returnList));
+ std::vector<am_Converter_s>::iterator listIterator = returnList.begin();
+
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->converterID == gatewayID)
+ {
+ ASSERT_TRUE(pCF.compareConverter(listIterator, gateway));
+ }
+
+ if (listIterator->converterID == gatewayID1)
+ {
+ ASSERT_TRUE(pCF.compareConverter(listIterator, gateway1));
+ }
+
+ if (listIterator->converterID == gatewayID2)
+ {
+ ASSERT_TRUE(pCF.compareConverter(listIterator, gateway2));
+ }
+ }
+}
+
+TEST_F(CAmMapHandlerTest,getGatewayInfo)
+{
+
+
+ //initialize gateway
+ std::vector<am_Gateway_s> returnList;
+ am_Gateway_s gateway, gateway1, gateway2;
+ am_gatewayID_t gatewayID = 0, gatewayID1 = 0, gatewayID2 = 0;
+
+ pCF.createGateway(gateway);
+ pCF.createGateway(gateway1);
+ gateway1.gatewayID = 20;
+ pCF.createGateway(gateway2);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway,gatewayID))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY,gatewayID)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1))
+ << "ERROR: database error";
+ ASSERT_EQ(gateway1.gatewayID,gatewayID1)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+1,gatewayID2)
+ << "ERROR: domainID zero";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListGateways(returnList));
+ std::vector<am_Gateway_s>::iterator listIterator = returnList.begin();
+
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->gatewayID == gatewayID)
+ {
+ ASSERT_TRUE(pCF.compareGateway(listIterator, gateway));
+ }
+
+ if (listIterator->gatewayID == gatewayID1)
+ {
+ ASSERT_TRUE(pCF.compareGateway(listIterator, gateway1));
+ }
+
+ if (listIterator->gatewayID == gatewayID2)
+ {
+ ASSERT_TRUE(pCF.compareGateway(listIterator, gateway2));
+ }
+ }
+
+ am_Gateway_s gatewayInfo;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getGatewayInfoDB(20,gatewayInfo));
+ ASSERT_TRUE(pCF.compareGateway1(gateway1,gatewayInfo));
+
+}
+
+TEST_F(CAmMapHandlerTest,getConverterInfo)
+{
+ //initialize gateway
+ std::vector<am_Converter_s> returnList;
+ am_Converter_s gateway, gateway1, gateway2;
+ am_converterID_t gatewayID = 0, gatewayID1 = 0, gatewayID2 = 0;
+
+ pCF.createConverter(gateway);
+ pCF.createConverter(gateway1);
+ gateway1.converterID = 20;
+ pCF.createConverter(gateway2);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway,gatewayID))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY,gatewayID)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway1,gatewayID1))
+ << "ERROR: database error";
+ ASSERT_EQ(gateway1.converterID,gatewayID1)
+ << "ERROR: domainID zero";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway2,gatewayID2))
+ << "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+1,gatewayID2)
+ << "ERROR: domainID zero";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConverters(returnList));
+ std::vector<am_Converter_s>::iterator listIterator = returnList.begin();
+
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->converterID == gatewayID)
+ {
+ ASSERT_TRUE(pCF.compareConverter(listIterator, gateway));
+ }
+
+ if (listIterator->converterID == gatewayID1)
+ {
+ ASSERT_TRUE(pCF.compareConverter(listIterator, gateway1));
+ }
+
+ if (listIterator->converterID == gatewayID2)
+ {
+ ASSERT_TRUE(pCF.compareConverter(listIterator, gateway2));
+ }
+ }
+
+ am_Converter_s gatewayInfo;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getConverterInfoDB(20,gatewayInfo));
+ ASSERT_TRUE(pCF.compareConverter1(gateway1,gatewayInfo));
+
+}
+
+TEST_F(CAmMapHandlerTest,enterSinkThatAlreadyExistFail)
+{
+ //fill the connection database
+ am_Sink_s staticSink, SecondSink;
+ am_sinkID_t staticSinkID, SecondSinkID;
+
+ pCF.createSink(staticSink);
+ staticSink.sinkID = 43;
+ staticSink.name = "Static";
+
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(staticSink,staticSinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(staticSink.sinkID,staticSinkID)
+ << "ERROR: ID not the one given in staticSink";
+
+ pCF.createSink(SecondSink);
+ SecondSink.sinkID = 43;
+ SecondSink.name = "SecondSink";
+
+ ASSERT_EQ(E_ALREADY_EXISTS,pDatabaseHandler.enterSinkDB(SecondSink,SecondSinkID))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,enterSourcesThatAlreadyExistFail)
+{
+ //fill the connection database
+ am_Source_s staticSource, SecondSource;
+ am_sourceID_t staticSourceID, SecondSourceID;
+ pCF.createSource(staticSource);
+ staticSource.sourceID = 4;
+
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(staticSource,staticSourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(staticSource.sourceID,staticSourceID)
+ << "ERROR: ID not the one given in staticSource";
+
+ pCF.createSource(SecondSource);
+ SecondSource.sourceID = 4;
+
+ ASSERT_EQ(E_ALREADY_EXISTS,pDatabaseHandler.enterSourceDB(SecondSource,SecondSourceID))
+ << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerTest,registerDomainCorrect)
+{
+ //initialize domain
+ std::vector<am_Domain_s> returnList;
+ am_Domain_s domain;
+ am_domainID_t domainID = 0;
+ pCF.createDomain(domain);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterDomainDB(domain,domainID))
+ << "ERROR: database error";
+ ASSERT_NE(0,domainID)
+ << "ERROR: domainID zero";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(returnList));
+ bool equal = true;
+ std::vector<am_Domain_s>::iterator listIterator = returnList.begin();
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->domainID == domainID)
+ {
+ equal = equal && (listIterator->name.compare(domain.name) == 0) && (listIterator->busname.compare(domain.busname) == 0) && (listIterator->complete == domain.complete) && (listIterator->early == domain.early) && (listIterator->state == domain.state);
+ }
+ }
+ ASSERT_EQ(true, equal);
+}
+
+TEST_F(CAmMapHandlerTest,registerDomainPredefined)
+{
+ //initialize domain
+ std::vector<am_Domain_s> returnList;
+ am_Domain_s domain;
+ am_domainID_t domainID = 10;
+ pCF.createDomain(domain);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterDomainDB(domain,domainID))
+ << "ERROR: database error";
+ ASSERT_NE(10,domainID)
+ << "ERROR: domainID not predefined one";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(returnList));
+ std::vector<am_Domain_s>::iterator listIterator = returnList.begin();
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->domainID == domainID)
+ {
+ ASSERT_EQ(0, listIterator->name.compare(domain.name));
+ ASSERT_EQ(0, listIterator->busname.compare(domain.busname));
+ ASSERT_EQ(domain.complete, listIterator->complete);
+ ASSERT_EQ(domain.early, listIterator->early);
+ ASSERT_EQ(domain.state, listIterator->state);
+ }
+ }
+}
+
+TEST_F(CAmMapHandlerTest,registerConnectionCorrect)
+{
+ am_Connection_s connection;
+ am_connectionID_t connectionID;
+ std::vector<am_Connection_s> returnList;
+ pCF.createConnection(connection);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConnectionDB(connection,connectionID))
+ << "ERROR: database error";;
+ ASSERT_NE(0,connectionID)
+ << "ERROR: connectionID zero";
+
+ //now check if we read out the correct values
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(returnList));
+ std::vector<am_Connection_s>::iterator listIterator = returnList.begin();
+ for (; listIterator < returnList.end(); ++listIterator)
+ {
+ if (listIterator->connectionID == connectionID)
+ {
+ ASSERT_EQ(connection.sourceID, listIterator->sourceID);
+ ASSERT_EQ(connection.sinkID, listIterator->sinkID);
+ ASSERT_EQ(connection.delay, listIterator->delay);
+ ASSERT_EQ(connection.connectionFormat, listIterator->connectionFormat);
+ }
+ }
+}
+
+TEST_F(CAmMapHandlerTest,enterMainConnectionCorrect)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+}
+
+TEST_F(CAmMapHandlerTest,enterSinksCorrect)
+{
+ //fill the connection database
+ am_Sink_s staticSink, firstDynamicSink, secondDynamicSink;
+ am_sinkID_t staticSinkID, firstDynamicSinkID, secondDynamicSinkID;
+ std::vector<am_Sink_s> sinkList;
+
+ pCF.createSink(staticSink);
+ staticSink.sinkID = 4;
+
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(staticSink,staticSinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(staticSink.sinkID,staticSinkID)
+ << "ERROR: ID not the one given in staticSink";
+
+ pCF.createSink(firstDynamicSink);
+ firstDynamicSink.name = "firstdynamic";
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(firstDynamicSink,firstDynamicSinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(firstDynamicSinkID,DYNAMIC_ID_BOUNDARY)
+ << "ERROR: ID not the one given in firstDynamicSink";
+
+ pCF.createSink(secondDynamicSink);
+ secondDynamicSink.name = "seconddynamic";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(secondDynamicSink,secondDynamicSinkID))
+ << "ERROR: database error";
+ ASSERT_NEAR(secondDynamicSinkID,DYNAMIC_ID_BOUNDARY,10)
+ << "ERROR: ID not the one given in secondDynamicSink";
+
+ //now read back and check the returns agains the given values
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinks(sinkList))
+ << "ERROR: database error";
+
+ std::vector<am_Sink_s>::iterator listIterator = sinkList.begin();
+ for (; listIterator < sinkList.end(); ++listIterator)
+ {
+ if (listIterator->sinkID == staticSinkID)
+ {
+ ASSERT_TRUE(pCF.compareSink(listIterator, staticSink));
+ }
+
+ if (listIterator->sinkID == firstDynamicSinkID)
+ {
+ ASSERT_TRUE(pCF.compareSink(listIterator, firstDynamicSink));
+ }
+
+ if (listIterator->sinkID == secondDynamicSinkID)
+ {
+ ASSERT_TRUE(pCF.compareSink(listIterator, secondDynamicSink));
+ }
+ }
+}
+
+TEST_F(CAmMapHandlerTest,enterNotificationConfigurationCorrect)
+{
+ am_Sink_s testSinkData, readoutData;
+ pCF.createSink(testSinkData);
+ testSinkData.sinkID = 4;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+ testSinkData.listNotificationConfigurations.push_back(notify);
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(testSinkData,sinkID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinks(listSinks))
+ << "ERROR: database error";
+
+ ASSERT_EQ(listSinks.begin()->listNotificationConfigurations[2].parameter,notify.parameter);
+ ASSERT_EQ(listSinks.begin()->listNotificationConfigurations[2].status,notify.status);
+ ASSERT_EQ(listSinks.begin()->listNotificationConfigurations[2].type,notify.type);
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.getSinkInfoDB(testSinkData.sinkID,readoutData))
+ << "ERROR: database error";
+
+ ASSERT_EQ(readoutData.listNotificationConfigurations[2].parameter,notify.parameter);
+ ASSERT_EQ(readoutData.listNotificationConfigurations[2].status,notify.status);
+ ASSERT_EQ(readoutData.listNotificationConfigurations[2].type,notify.type);
+
+}
+
+TEST_F(CAmMapHandlerTest,enterMainNotificationConfigurationCorrect)
+{
+ am_Sink_s testSinkData;
+ pCF.createSink(testSinkData);
+ testSinkData.sinkID = 4;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify);
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(testSinkData,sinkID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinks(listSinks))
+ << "ERROR: database error";
+
+ ASSERT_EQ(listSinks.begin()->listMainNotificationConfigurations[2].parameter,notify.parameter);
+ ASSERT_EQ(listSinks.begin()->listMainNotificationConfigurations[2].status,notify.status);
+ ASSERT_EQ(listSinks.begin()->listMainNotificationConfigurations[2].type,notify.type);
+}
+
+TEST_F(CAmMapHandlerTest,removeNotificationsSink)
+{
+ am_Sink_s testSinkData;
+ pCF.createSink(testSinkData);
+ testSinkData.sinkID = 4;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify);
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(testSinkData,sinkID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSinks(listSinks))
+ << "ERROR: database error";
+
+ ASSERT_EQ(listSinks.begin()->listMainNotificationConfigurations[2].parameter,notify.parameter);
+ ASSERT_EQ(listSinks.begin()->listMainNotificationConfigurations[2].status,notify.status);
+ ASSERT_EQ(listSinks.begin()->listMainNotificationConfigurations[2].type,notify.type);
+
+ //now we remove the sink
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeSinkDB(sinkID));
+}
+
+TEST_F(CAmMapHandlerTest,removeNotificationsSource)
+{
+ am_Source_s testSourceData;
+ pCF.createSource(testSourceData);
+ testSourceData.sourceID = 4;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSourceData.listMainNotificationConfigurations.push_back(notify);
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(testSourceData,sourceID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListSources(listSources))
+ << "ERROR: database error";
+
+ ASSERT_EQ(listSources.begin()->listMainNotificationConfigurations[2].parameter,notify.parameter);
+ ASSERT_EQ(listSources.begin()->listMainNotificationConfigurations[2].status,notify.status);
+ ASSERT_EQ(listSources.begin()->listMainNotificationConfigurations[2].type,notify.type);
+
+ //now we remove the sink
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeSourceDB(sourceID));
+}
+
+TEST_F(CAmMapHandlerTest,getMainNotificationsSink)
+{
+ am_Sink_s testSinkData;
+ pCF.createSink(testSinkData);
+ testSinkData.sinkID = 4;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+ std::vector<am_NotificationConfiguration_s>returnList;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify);
+
+ am_NotificationConfiguration_s notify1;
+ notify1.type=NT_UNKNOWN;
+ notify1.status=NS_PERIODIC;
+ notify1.parameter=5;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify1);
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(testSinkData,sinkID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSinkNotificationConfigurations(sinkID,returnList))
+ << "ERROR: database error";
+
+ std::equal(testSinkData.listMainNotificationConfigurations.begin(),testSinkData.listMainNotificationConfigurations.end(),returnList.begin(),equalNotificationConfiguration);
+
+}
+
+TEST_F(CAmMapHandlerTest,getMainNotificationsSources)
+{
+ am_Source_s testSourceData;
+ pCF.createSource(testSourceData);
+ testSourceData.sourceID = 4;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+ std::vector<am_NotificationConfiguration_s>returnList;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSourceData.listMainNotificationConfigurations.push_back(notify);
+
+ am_NotificationConfiguration_s notify1;
+ notify1.type=NT_UNKNOWN;
+ notify1.status=NS_PERIODIC;
+ notify1.parameter=5;
+
+ testSourceData.listMainNotificationConfigurations.push_back(notify1);
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(testSourceData,sourceID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSourceNotificationConfigurations(sourceID,returnList))
+ << "ERROR: database error";
+
+ std::equal(testSourceData.listMainNotificationConfigurations.begin(),testSourceData.listMainNotificationConfigurations.end(),returnList.begin(),equalNotificationConfiguration);
+
+}
+
+TEST_F(CAmMapHandlerTest,changeMainNotificationsSources)
+{
+ am_Source_s testSourceData;
+ pCF.createSource(testSourceData);
+ testSourceData.sourceID = 4;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+ std::vector<am_NotificationConfiguration_s>returnList,returnList1;
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(testSourceData,sourceID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSourceNotificationConfigurations(sourceID,returnList))
+ << "ERROR: database error";
+
+ ASSERT_EQ(true, std::equal(testSourceData.listMainNotificationConfigurations.begin(),
+ testSourceData.listMainNotificationConfigurations.end(),
+ returnList.begin(),
+ equalNotificationConfiguration));
+
+ //change notification which is not available
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=10;
+ ASSERT_EQ(E_NO_CHANGE,pDatabaseHandler.changeMainSourceNotificationConfigurationDB(sourceID,notify));
+ //change a setting
+ notify.type=NT_TEST_2;
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeMainSourceNotificationConfigurationDB(sourceID,notify));
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSourceNotificationConfigurations(sourceID,returnList1))
+ << "ERROR: database error";
+
+ ASSERT_EQ(returnList1[1].parameter,notify.parameter);
+ ASSERT_EQ(returnList1[1].status,notify.status);
+ ASSERT_EQ(returnList1[1].type,notify.type);
+
+}
+
+TEST_F(CAmMapHandlerTest,changeMainNotificationsSink)
+{
+ am_Sink_s testSinkData;
+ pCF.createSink(testSinkData);
+ testSinkData.sinkID = 4;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+ std::vector<am_NotificationConfiguration_s>returnList,returnList1;
+
+ //enter the sink in the database
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(testSinkData,sinkID))
+ << "ERROR: database error";
+
+ //read it again
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSinkNotificationConfigurations(sinkID,returnList))
+ << "ERROR: database error";
+
+ std::equal(testSinkData.listMainNotificationConfigurations.begin(),testSinkData.listMainNotificationConfigurations.end(),returnList.begin(),equalNotificationConfiguration);
+
+ //change notification which is not available
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_UNKNOWN;
+ notify.status=NS_CHANGE;
+ notify.parameter=27;
+ ASSERT_EQ(E_NO_CHANGE,pDatabaseHandler.changeMainSinkNotificationConfigurationDB(sinkID,notify))
+ << "ERROR: database error";
+ //change a setting
+ notify.type=NT_TEST_2;
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeMainSinkNotificationConfigurationDB(sinkID,notify))
+ << "ERROR: database error";
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSinkNotificationConfigurations(sinkID,returnList1))
+ << "ERROR: database error";
+
+ ASSERT_EQ(returnList1[1].parameter,notify.parameter);
+ ASSERT_EQ(returnList1[1].status,notify.status);
+ ASSERT_EQ(returnList1[1].type,notify.type);
+}
+
+TEST_F(CAmMapHandlerTest, peekDomain_2)
+{
+ std::vector<am_Domain_s> listDomains;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_domainID_t domain2ID;
+ pCF.createDomain(domain);
+ ASSERT_EQ(E_OK,pDatabaseHandler.peekDomain(std::string("newdomain"),domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_TRUE(listDomains.empty());
+ ASSERT_EQ(domainID, DYNAMIC_ID_BOUNDARY);
+
+ domain.name = "anotherdomain";
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domain2ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_EQ(domain2ID, DYNAMIC_ID_BOUNDARY+1);
+
+ domain.name = "newdomain";
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domain2ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_EQ(domainID, domain2ID); // FAILS, ID is 2 instead of 1
+ bool containsDomainID = std::find_if(listDomains.begin(), listDomains.end(), [&](const am_Domain_s & ref) {
+ return ref.domainID==domainID;
+ })!=listDomains.end();
+ ASSERT_TRUE(containsDomainID);
+}
+
+TEST_F(CAmMapHandlerTest, connectionIDBoundary)
+{
+ am_Sink_s sink;
+ am_Source_s source;
+ am_Connection_s connection;
+ connection.delay = -1;
+ connection.connectionFormat = CF_GENIVI_ANALOG;
+ connection.connectionID = 0;
+ am_sinkID_t forgetSink;
+ am_sourceID_t forgetSource;
+ am_connectionID_t connectionID;
+ for (uint16_t i = 1; i < TEST_MAX_SINK_ID; i++)
+ {
+ pCF.createSink(sink);
+ sink.sinkID = 0;
+ sink.name = "sink" + int2string(i);
+ sink.domainID = 4;
+ pCF.createSource(source);
+ source.sourceID = 0;
+ source.name = "source" + int2string(i);
+ source.domainID = 4;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink, forgetSink));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source, forgetSource));
+ connection.sinkID = forgetSink;
+ connection.sourceID = forgetSource;
+ if( i < TEST_MAX_CONNECTION_ID )
+ {
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+ ASSERT_EQ(i, connectionID);
+ }
+ }
+ std::vector<am_Connection_s> connectionList;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_EQ(TEST_MAX_CONNECTION_ID-1, static_cast<int>(connectionList.size()));
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ logInfo("here");
+ ASSERT_EQ(0, connectionID);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeConnection(10));
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeConnection(12));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(10, connectionID);
+ connection.sinkID = 77;
+ connection.sourceID = 77;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(12, connectionID);
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(0, connectionID);
+}
+
+TEST_F(CAmMapHandlerTest, mainConnectionIDBoundary)
+{
+ am_Sink_s sink;
+ am_Source_s source;
+ am_Connection_s connection;
+ connection.delay = -1;
+ connection.connectionFormat = CF_GENIVI_ANALOG;
+ connection.connectionID = 0;
+ am_sinkID_t forgetSink;
+ am_sourceID_t forgetSource;
+ am_connectionID_t connectionID;
+ std::vector<am_connectionID_t> connectionIDList;
+ for (uint16_t i = 1; i < TEST_MAX_SINK_ID; i++)
+ {
+ pCF.createSink(sink);
+ sink.sinkID = 0;
+ sink.name = "sink" + int2string(i);
+ sink.domainID = 4;
+ pCF.createSource(source);
+ source.sourceID = 0;
+ source.name = "source" + int2string(i);
+ source.domainID = 4;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink, forgetSink));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source, forgetSource));
+ connection.sinkID = forgetSink;
+ connection.sourceID = forgetSource;
+ if( i < TEST_MAX_CONNECTION_ID )
+ {
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConnectionDB(connection,connectionID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+ ASSERT_EQ(i, connectionID);
+ connectionIDList.push_back(i);
+ }
+ }
+ std::vector<am_Connection_s> connectionList;
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
+ ASSERT_EQ(TEST_MAX_CONNECTION_ID-1, static_cast<int>(connectionList.size()));
+
+ //create a mainConnection
+
+ am_MainConnection_s mainConnection;
+ am_mainConnectionID_t mainConnectionID;
+ mainConnection.listConnectionID = connectionIDList;
+ mainConnection.mainConnectionID = 0;
+ mainConnection.connectionState = CS_CONNECTED;
+ mainConnection.delay = -1;
+
+ for (uint16_t i = 1; i < TEST_MAX_MAINCONNECTION_ID; i++)
+ {
+ mainConnection.sinkID = DYNAMIC_ID_BOUNDARY + i;
+ mainConnection.sourceID = DYNAMIC_ID_BOUNDARY + i;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterMainConnectionDB(mainConnection,mainConnectionID));
+ ASSERT_EQ(i, mainConnectionID);
+ }
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeMainConnectionDB(10));
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeMainConnectionDB(12));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterMainConnectionDB(mainConnection,mainConnectionID));
+ ASSERT_EQ(10, mainConnectionID);
+ mainConnection.sinkID = 77;
+ mainConnection.sourceID = 77;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterMainConnectionDB(mainConnection,mainConnectionID));
+ ASSERT_EQ(12, mainConnectionID);
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterMainConnectionDB(mainConnection,mainConnectionID));
+ ASSERT_EQ(0, mainConnectionID);
+}
+
+TEST_F(CAmMapHandlerTest, increaseID)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ for (uint16_t i = 0; i < TEST_MAX_SINK_ID; i++)
+ {
+ pCF.createSink(sink);
+ sink.sinkID = 0;
+ sink.name = "sink" + int2string(i);
+ sink.domainID = 4;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink, sinkID));
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+i, sinkID);
+ }
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterSinkDB(sink, sinkID));
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeSinkDB(DYNAMIC_ID_BOUNDARY+10));
+ ASSERT_EQ(E_OK, pDatabaseHandler.removeSinkDB(DYNAMIC_ID_BOUNDARY+12));
+
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterSinkDB(sink, sinkID));
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterSinkDB(sink, sinkID));
+ ASSERT_EQ(E_UNKNOWN, pDatabaseHandler.enterSinkDB(sink, sinkID));
+}
+
+
+CAmMapHandlerObserverCallbacksTest::CAmMapHandlerObserverCallbacksTest() :
+ mMockObserver(&pCommandSender, &pRoutingSender, &pSocketHandler)
+{
+ pDatabaseHandler.registerObserver(&mMockObserver);
+}
+
+CAmMapHandlerObserverCallbacksTest::~CAmMapHandlerObserverCallbacksTest()
+{
+}
+
+MATCHER_P(IsDomainDataEqualTo, value, "") {
+ auto lh = arg;
+ return lh.domainID == value.domainID &&
+ lh.name == value.name &&
+ lh.nodename == value.nodename &&
+ lh.early == value.early &&
+ lh.complete == value.complete &&
+ lh.state == value.state;
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, peek_enter_removeDomain)
+{
+ std::vector<am_Domain_s> listDomains;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_domainID_t domain2ID;
+ pCF.createDomain(domain);
+ ASSERT_EQ(E_OK,pDatabaseHandler.peekDomain(std::string("newdomain"), domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_TRUE(listDomains.empty());
+ ASSERT_EQ(domainID, DYNAMIC_ID_BOUNDARY);
+
+ domain.name = "anotherdomain";
+ const am_Domain_s expDomain1 = {DYNAMIC_ID_BOUNDARY+1, domain.name, domain.busname, domain.nodename, domain.early, domain.complete, domain.state};
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newDomain(IsDomainDataEqualTo(expDomain1))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domain2ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_EQ(domain2ID, DYNAMIC_ID_BOUNDARY+1);
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(MockDatabaseObserver::getMockObserverObject()));
+ domain.name = "newdomain";
+ const am_Domain_s expDomain2 = {DYNAMIC_ID_BOUNDARY, domain.name, domain.busname, domain.nodename, domain.early, domain.complete, domain.state};
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newDomain(IsDomainDataEqualTo(expDomain2))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domain2ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListDomains(listDomains));
+ ASSERT_EQ(domainID, domain2ID); // FAILS, ID is 2 instead of 1
+ bool containsDomainID = std::find_if(listDomains.begin(), listDomains.end(), [&](const am_Domain_s & ref) {
+ return ref.domainID==domainID;
+ })!=listDomains.end();
+ ASSERT_TRUE(containsDomainID);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removeDomain(domainID)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeDomainDB(domainID))<< "ERROR: database error";
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(MockDatabaseObserver::getMockObserverObject()));
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, peek_enter_update_removeSource)
+{
+ std::vector<am_Source_s> listSources;
+ am_sourceID_t sourceID;
+ am_sourceID_t source2ID;
+ am_sourceID_t source3ID;
+ am_Source_s source;
+ pCF.createSource(source);
+
+ //peek a source that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSource(std::string("newsource"),sourceID));
+
+ //peek a second source that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSource(std::string("newsource2"),source2ID));
+
+ //make sure they are is not in the list
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_TRUE(listSources.empty());
+ ASSERT_EQ(sourceID, DYNAMIC_ID_BOUNDARY);
+
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(Field(&am_Source_s::sourceID, DYNAMIC_ID_BOUNDARY+2))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,source3ID));
+ ASSERT_EQ(source3ID, DYNAMIC_ID_BOUNDARY+2);
+
+ source.name = "newsource";
+ //now enter the source with the same name than the first peek and make sure it does not get a new ID
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(Field(&am_Source_s::sourceID, DYNAMIC_ID_BOUNDARY))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,source3ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(sourceID, source3ID);
+ bool containsSourceID = std::find_if(listSources.begin(), listSources.end(), [&](const am_Source_s & ref) {
+ return ref.sourceID==sourceID;
+ })!=listSources.end();
+ ASSERT_TRUE(containsSourceID);
+
+ std::vector<am_SoundProperty_s> listSoundProperties;
+ std::vector<am_CustomAvailabilityReason_t> listConnectionFormats;
+ std::vector<am_MainSoundProperty_s> listMainSoundProperties;
+#ifndef WITH_DATABASE_CHANGE_CHECK
+ //check no change
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceUpdated(sourceID, _, _, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSourceDB(sourceID, source.sourceClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+#else
+ //check no change
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceUpdated(sourceID, _, _, _)).Times(0);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSourceDB(sourceID, source.sourceClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+ //check change of class id
+ source.sourceClassID++;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceUpdated(sourceID, source.sourceClassID, _, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSourceDB(sourceID, source.sourceClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+ //check change of main sound properties
+ am_MainSoundProperty_s mainSoundProperties;
+ mainSoundProperties.type = MSP_GENIVI_TREBLE;
+ mainSoundProperties.value = 0;
+ listMainSoundProperties.push_back(mainSoundProperties);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceUpdated(sourceID, _, _, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSourceDB(sourceID, source.sourceClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+#endif
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removedSource(sourceID, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeSourceDB(sourceID))<< "ERROR: database error";
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(MockDatabaseObserver::getMockObserverObject()));
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, peek_enter_update_removeSink)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_sinkID_t sinkID;
+ am_sinkID_t sink2ID;
+ am_sinkID_t sink3ID;
+ am_Sink_s sink;
+ pCF.createSink(sink);
+
+ //peek a sink that does not exits
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSink(std::string("newsink"),sinkID));
+
+ //peek again
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSink(std::string("nextsink"),sink2ID));
+
+ //make sure they are is not in the list
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_TRUE(listSinks.empty());
+ ASSERT_EQ(sinkID, DYNAMIC_ID_BOUNDARY);
+
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(Field(&am_Sink_s::sinkID, DYNAMIC_ID_BOUNDARY+2))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sink3ID));
+ ASSERT_EQ(sink3ID, DYNAMIC_ID_BOUNDARY+2);
+
+ sink.name = "newsink";
+ //now enter the sink with the same name than the first peek and make sure it does not get a new ID
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(Field(&am_Sink_s::sinkID, DYNAMIC_ID_BOUNDARY))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sink3ID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(sinkID, sink3ID);
+ bool containsSourceID = std::find_if(listSinks.begin(), listSinks.end(), [&](const am_Sink_s & ref) {
+ return ref.sinkID==sinkID;
+ })!=listSinks.end();
+ ASSERT_TRUE(containsSourceID);
+
+ std::vector<am_SoundProperty_s> listSoundProperties;
+ std::vector<am_CustomAvailabilityReason_t> listConnectionFormats;
+ std::vector<am_MainSoundProperty_s> listMainSoundProperties;
+#ifndef WITH_DATABASE_CHANGE_CHECK
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkUpdated(sinkID, _, _, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSinkDB(sinkID, sink.sinkClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+#else
+ //check no change
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkUpdated(sinkID, _, _, _)).Times(0);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSinkDB(sinkID, sink.sinkClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+ //check change of class id
+ sink.sinkClassID++;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkUpdated(sinkID, sink.sinkClassID, _, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSinkDB(sinkID, sink.sinkClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+ //check change of main sound properties
+ am_MainSoundProperty_s mainSoundProperties;
+ mainSoundProperties.type = MSP_GENIVI_TREBLE;
+ mainSoundProperties.value = 0;
+ listMainSoundProperties.push_back(mainSoundProperties);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkUpdated(sinkID, _, _, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeSinkDB(sinkID, sink.sinkClassID, listSoundProperties, listConnectionFormats, listMainSoundProperties))<< "ERROR: database error";
+#endif
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removedSink(sinkID, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeSinkDB(sinkID))<< "ERROR: database error";
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(MockDatabaseObserver::getMockObserverObject()));
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, peekSourceClassID)
+{
+ std::string sourceName("myClassID");
+ am_sourceClass_t sourceClassID, peekID;
+ am_SourceClass_s sourceClass;
+ am_ClassProperty_s classProperty;
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 13;
+ sourceClass.name = sourceName;
+ sourceClass.sourceClassID = 0;
+ sourceClass.listClassProperties.push_back(classProperty);
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.peekSourceClassID(sourceName,sourceClassID));
+
+ //now we enter the class into the database
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), numberOfSourceClassesChanged()).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceClassID,sourceClass));
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSourceClassID(sourceName,peekID));
+ ASSERT_EQ(sourceClassID, peekID);
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, peekSinkClassID)
+{
+ std::string sinkName("myClassID");
+ am_sinkClass_t sinkClassID, peekID;
+ am_SinkClass_s sinkClass;
+ am_ClassProperty_s classProperty;
+ classProperty.classProperty = CP_GENIVI_SOURCE_TYPE;
+ classProperty.value = 13;
+ sinkClass.name = sinkName;
+ sinkClass.sinkClassID = 0;
+ sinkClass.listClassProperties.push_back(classProperty);
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_NON_EXISTENT, pDatabaseHandler.peekSinkClassID(sinkName,sinkClassID));
+
+ //now we enter the class into the database
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), numberOfSinkClassesChanged()).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkClass,sinkClassID));
+
+ //first we peek without an existing class
+ ASSERT_EQ(E_OK, pDatabaseHandler.peekSinkClassID(sinkName,peekID));
+ ASSERT_EQ(sinkClassID, peekID);
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, enter_removeGateway)
+{
+ //initialize gateway
+ std::vector<am_Gateway_s> returnList;
+ am_Gateway_s gateway, gateway1, gateway2;
+ am_gatewayID_t gatewayID = 0, gatewayID1 = 0, gatewayID2 = 0;
+ pCF.createGateway(gateway);
+ pCF.createGateway(gateway1);
+ gateway1.gatewayID = 20;
+ pCF.createGateway(gateway2);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newGateway(Field(&am_Gateway_s::gatewayID, DYNAMIC_ID_BOUNDARY))).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway,gatewayID))<< "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY,gatewayID)<< "ERROR: domainID zero";
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newGateway(Field(&am_Gateway_s::gatewayID, 20))).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1))<< "ERROR: database error";
+ ASSERT_EQ(gateway1.gatewayID,gatewayID1)<< "ERROR: domainID zero";
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newGateway(Field(&am_Gateway_s::gatewayID, DYNAMIC_ID_BOUNDARY+1))).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2))<< "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+1,gatewayID2)<< "ERROR: domainID zero";
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removeGateway(gatewayID2)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeGatewayDB(gatewayID2))<< "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, enter_removeConverter)
+{
+ //initialize gateway
+ std::vector<am_Converter_s> returnList;
+ am_Converter_s gateway, gateway1, gateway2;
+ am_converterID_t gatewayID = 0, gatewayID1 = 0, gatewayID2 = 0;
+ pCF.createConverter(gateway);
+ pCF.createConverter(gateway1);
+ gateway1.converterID = 20;
+ pCF.createConverter(gateway2);
+ am_Sink_s sink;
+ am_Source_s source;
+ am_sinkID_t sinkID;
+ am_sourceID_t sourceID;
+ pCF.createSink(sink);
+ pCF.createSource(source);
+ sink.sinkID = 1;
+ source.sourceID = 2;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newConverter(Field(&am_Converter_s::converterID, DYNAMIC_ID_BOUNDARY))).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway,gatewayID))<< "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY,gatewayID)<< "ERROR: domainID zero";
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newConverter(Field(&am_Converter_s::converterID, 20))).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway1,gatewayID1))<< "ERROR: database error";
+ ASSERT_EQ(gateway1.converterID,gatewayID1)<< "ERROR: domainID zero";
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newConverter(Field(&am_Converter_s::converterID, DYNAMIC_ID_BOUNDARY+1))).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConverterDB(gateway2,gatewayID2))<< "ERROR: database error";
+ ASSERT_EQ(DYNAMIC_ID_BOUNDARY+1,gatewayID2)<< "ERROR: domainID zero";
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removeConverter(gatewayID2)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeConverterDB(gatewayID2))<< "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, enter_removeCrossfader)
+{
+ am_Crossfader_s crossfader;
+ am_crossfaderID_t crossfaderID;
+ am_Sink_s sinkA, sinkB;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_sinkID_t sinkAID, sinkBID;
+ pCF.createSink(sinkA);
+ pCF.createSink(sinkB);
+ sinkB.name = "sinkB";
+ pCF.createSource(source);
+
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sinkA,sinkAID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sinkB,sinkBID));
+
+ crossfader.crossfaderID = 0;
+ crossfader.hotSink = HS_SINKA;
+ crossfader.sinkID_A = sinkAID;
+ crossfader.sinkID_B = sinkBID;
+ crossfader.sourceID = sourceID;
+ crossfader.name = "Crossfader";
+ crossfader.hotSink = HS_UNKNOWN;
+
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newCrossfader(Field(&am_Crossfader_s::crossfaderID, DYNAMIC_ID_BOUNDARY))).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterCrossfaderDB(crossfader,crossfaderID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removeCrossfader(crossfaderID)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeCrossfaderDB(crossfaderID))<< "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, enter_update_removeMainConnection)
+{
+ am_mainConnectionID_t mainConnectionID;
+ am_MainConnection_s mainConnection;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(9);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(_)).Times(9);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newMainConnection(Field(&am_MainConnectionType_s::mainConnectionID, 1))).Times(1);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), mainConnectionStateChanged(1, CS_CONNECTED)).Times(1);
+#ifndef WITH_DATABASE_CHANGE_CHECK
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), timingInformationChanged(1, _)).Times(1);
+#else
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), timingInformationChanged(1, _)).Times(0);
+#endif
+ createMainConnectionSetup(mainConnectionID, mainConnection);
+
+ //change delay of first connection
+ am_timeSync_t delay = 20;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), timingInformationChanged(mainConnectionID, 20)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionTimingInformation(mainConnection.listConnectionID[0], delay));
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeConnectionTimingInformation(mainConnection.listConnectionID[0], delay));
+#endif
+
+ //change delay of route
+ delay = 40;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), timingInformationChanged(mainConnectionID, 40)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeDelayMainConnection(delay, mainConnectionID));
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeDelayMainConnection(delay, mainConnectionID));
+#endif
+
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), removedMainConnection(1)).Times(1);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), mainConnectionStateChanged(1, _)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.removeMainConnectionDB(mainConnectionID)) << "ERROR: database error";
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, changeSinkAvailability)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ am_Availability_s availability;
+ availability.availability = A_UNKNOWN;
+ availability.availabilityReason = AR_GENIVI_TEMPERATURE;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkAvailabilityChanged(_, _)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkAvailabilityDB(availability,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(availability.availability, listSinks[0].available.availability);
+ ASSERT_EQ(availability.availabilityReason, listSinks[0].available.availabilityReason);
+
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkAvailabilityChanged(_, _)).Times(1);
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeSinkAvailabilityDB(availability,sinkID));
+ availability.availability = A_AVAILABLE;
+ availability.availabilityReason = AR_GENIVI_TEMPERATURE;
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkAvailabilityDB(availability,sinkID));
+#endif
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, changeSourceAvailability)
+{
+ std::vector<am_Source_s> listSources;
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ pCF.createSource(source);
+ am_Availability_s availability;
+ availability.availability = A_UNKNOWN;
+ availability.availabilityReason = AR_GENIVI_TEMPERATURE;
+ source.visible = true;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceAvailabilityChanged(_, _)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceAvailabilityDB(availability,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSources(listSources));
+ ASSERT_EQ(availability.availability, listSources[0].available.availability);
+ ASSERT_EQ(availability.availabilityReason, listSources[0].available.availabilityReason);
+
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceAvailabilityChanged(_, _)).Times(1);
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeSourceAvailabilityDB(availability,sourceID));
+ availability.availability = A_AVAILABLE;
+ availability.availabilityReason = AR_GENIVI_TEMPERATURE;
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSourceAvailabilityDB(availability,sourceID));
+#endif
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest,changeMainSinkVolume)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_mainVolume_t newVol = 20;
+ std::vector<am_Sink_s> listSinks;
+ pCF.createSink(sink);
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), volumeChanged(sinkID, newVol)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkMainVolumeDB(newVol,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(listSinks[0].mainVolume, newVol);
+
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ am_mainVolume_t incVol = 21;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), volumeChanged( sinkID, incVol)).Times(1);
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeSinkMainVolumeDB(newVol,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkMainVolumeDB(incVol,sinkID));
+#endif
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, changeSinkMuteState)
+{
+ std::vector<am_Sink_s> listSinks;
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ pCF.createSink(sink);
+ am_MuteState_e muteState = MS_MUTED;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkMuteStateChanged(sinkID, muteState)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkMuteStateDB(muteState,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSinks(listSinks));
+ ASSERT_EQ(muteState, listSinks[0].muteState);
+
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ am_MuteState_e newMuteState = MS_UNMUTED;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkMuteStateChanged(sinkID, newMuteState)).Times(1);
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeSinkMuteStateDB(muteState,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSinkMuteStateDB(newMuteState,sinkID));
+#endif
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, changeSystemProperty)
+{
+ std::vector<am_SystemProperty_s> listSystemProperties, listReturn;
+ am_SystemProperty_s systemProperty;
+
+ systemProperty.type = SYP_UNKNOWN;
+ systemProperty.value = 33;
+ listSystemProperties.push_back(systemProperty);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSystemProperties(listSystemProperties));
+ systemProperty.value = 444;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), systemPropertyChanged(_)).Times(1);
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSystemPropertyDB(systemProperty));
+ ASSERT_EQ(E_OK, pDatabaseHandler.getListSystemProperties(listReturn));
+ ASSERT_EQ(listReturn[0].type, systemProperty.type);
+ ASSERT_EQ(listReturn[0].value, systemProperty.value);
+
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), systemPropertyChanged(_)).Times(1);
+ ASSERT_EQ(E_NO_CHANGE, pDatabaseHandler.changeSystemPropertyDB(systemProperty));
+ systemProperty.value = 33;
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeSystemPropertyDB(systemProperty));
+#endif
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, changeMainNotificationsSink)
+{
+ am_Sink_s testSinkData;
+ pCF.createSink(testSinkData);
+ testSinkData.sinkID = 4;
+ am_sinkID_t sinkID;
+ std::vector<am_Sink_s> listSinks;
+ std::vector<am_NotificationConfiguration_s>returnList;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_TEST_1;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify);
+
+ am_NotificationConfiguration_s notify1;
+ notify1.type=NT_TEST_1;
+ notify1.status=NS_PERIODIC;
+ notify1.parameter=5;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify1);
+
+ am_NotificationConfiguration_s notify2;
+ notify2.type=NT_TEST_2;
+ notify2.status=NS_CHANGE;
+ notify2.parameter=27;
+
+ testSinkData.listMainNotificationConfigurations.push_back(notify2);
+
+ //enter the sink in the database
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSink(_)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSinkDB(testSinkData,sinkID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSinkNotificationConfigurations(sinkID, returnList))
+ << "ERROR: database error";
+ ASSERT_EQ(2, returnList.size()) << "ERROR: database error";
+
+ //change a setting
+ notify2.parameter++;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sinkMainNotificationConfigurationChanged(sinkID, _)).Times(1);
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ ASSERT_EQ(E_NO_CHANGE,pDatabaseHandler.changeMainSinkNotificationConfigurationDB(sinkID,notify1));
+#endif
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeMainSinkNotificationConfigurationDB(sinkID,notify2));
+}
+
+TEST_F(CAmMapHandlerObserverCallbacksTest, changeMainNotificationsSources)
+{
+
+ am_Source_s testSourceData;
+ pCF.createSource(testSourceData);
+ testSourceData.sourceID = 4;
+ am_sourceID_t sourceID;
+ std::vector<am_Source_s> listSources;
+ std::vector<am_NotificationConfiguration_s>returnList;
+
+ am_NotificationConfiguration_s notify;
+ notify.type=NT_TEST_1;
+ notify.status=NS_CHANGE;
+ notify.parameter=25;
+
+ testSourceData.listMainNotificationConfigurations.push_back(notify);
+
+ am_NotificationConfiguration_s notify1;
+ notify1.type=NT_TEST_1;
+ notify1.status=NS_PERIODIC;
+ notify1.parameter=5;
+
+ testSourceData.listMainNotificationConfigurations.push_back(notify1);
+
+ am_NotificationConfiguration_s notify2;
+ notify2.type=NT_TEST_2;
+ notify2.status=NS_CHANGE;
+ notify2.parameter=10;
+
+ testSourceData.listMainNotificationConfigurations.push_back(notify2);
+
+ //enter the sink in the database
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), newSource(_)).Times(1);
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterSourceDB(testSourceData,sourceID))
+ << "ERROR: database error";
+ ASSERT_EQ(E_OK,pDatabaseHandler.getListMainSourceNotificationConfigurations(sourceID,returnList))
+ << "ERROR: database error";
+ ASSERT_EQ(2, returnList.size()) << "ERROR: database error";
+
+ //change a setting
+ notify2.parameter++;
+ EXPECT_CALL(*MockDatabaseObserver::getMockObserverObject(), sourceMainNotificationConfigurationChanged(sourceID, _)).Times(1);
+#ifdef WITH_DATABASE_CHANGE_CHECK
+ ASSERT_EQ(E_NO_CHANGE,pDatabaseHandler.changeMainSourceNotificationConfigurationDB(sourceID,notify1));
+#endif
+ ASSERT_EQ(E_OK,pDatabaseHandler.changeMainSourceNotificationConfigurationDB(sourceID,notify2));
+}
+
+int main(int argc, char **argv)
+{
+ try
+ {
+ TCLAP::CmdLine* cmd(CAmCommandLineSingleton::instanciateOnce("The team of the AudioManager wishes you a nice day!",' ',DAEMONVERSION,true));
+ cmd->add(enableNoDLTDebug);
+ }
+ catch (TCLAP::ArgException &e) // catch any exceptions
+ { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
+ CAmCommandLineSingleton::instance()->preparse(argc,argv);
+ CAmDltWrapper::instance(enableNoDLTDebug.getValue())->registerApp("databse", "databasetest");
+ logInfo("Database Test started ");
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
+
diff --git a/AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.h b/AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.h
new file mode 100644
index 0000000..e3cc0ef
--- /dev/null
+++ b/AudioManagerCore/test/AmMapHandlerTest/CAmMapHandlerTest.h
@@ -0,0 +1,92 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef MAPHANDLERTEST_H_
+#define MAPHANDLERTEST_H_
+
+#define UNIT_TEST 1
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "CAmSocketHandler.h"
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmControlReceiver.h"
+#include "CAmControlSender.h"
+#include "CAmDatabaseObserver.h"
+#include "CAmRoutingSender.h"
+#include "CAmRouter.h"
+#include "CAmControlSender.h"
+#include "../IAmControlBackdoor.h"
+#include "../IAmCommandBackdoor.h"
+#include "../CAmCommonFunctions.h"
+#include "../MockIAmControlSend.h"
+#include "../MockIAmCommandSend.h"
+#include "MockDatabaseObserver.h"
+
+namespace am
+{
+
+class CAmMapBasicTest : public ::testing::Test
+{
+public:
+ CAmMapBasicTest();
+ ~CAmMapBasicTest();
+ std::vector<std::string> plistRoutingPluginDirs;
+ std::vector<std::string> plistCommandPluginDirs;
+ CAmRoutingSender pRoutingSender;
+ CAmCommandSender pCommandSender;
+ IAmRoutingBackdoor pRoutingInterfaceBackdoor;
+ IAmCommandBackdoor pCommandInterfaceBackdoor;
+ CAmSocketHandler pSocketHandler;
+ CAmDatabaseHandlerMap pDatabaseHandler;
+ CAmControlSender pControlSender;
+ CAmRouter pRouter;
+ CAmControlReceiver pControlReceiver;
+ CAmCommonFunctions pCF;
+ void SetUp();
+ void TearDown();
+ void createMainConnectionSetup(am_mainConnectionID_t & mainConnectionID, am_MainConnection_s & mainConnection);
+};
+
+class CAmMapHandlerTest: public CAmMapBasicTest
+{
+public:
+ CAmMapHandlerTest();
+ ~CAmMapHandlerTest();
+ MockIAmCommandSend pMockInterface;
+ CAmDatabaseObserver pObserver;
+};
+
+class CAmMapHandlerObserverCallbacksTest : public CAmMapBasicTest
+{
+public:
+ CAmMapHandlerObserverCallbacksTest();
+ ~CAmMapHandlerObserverCallbacksTest();
+ CAmDatabaseObserver mMockObserver;
+};
+
+
+}
+
+#endif /* MAPHANDLERTEST_H_ */
diff --git a/AudioManagerCore/test/AmMapHandlerTest/CAmTestDatabaseObserver.cpp b/AudioManagerCore/test/AmMapHandlerTest/CAmTestDatabaseObserver.cpp
new file mode 100644
index 0000000..a035cee
--- /dev/null
+++ b/AudioManagerCore/test/AmMapHandlerTest/CAmTestDatabaseObserver.cpp
@@ -0,0 +1,98 @@
+/**
+ * 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 CAmTestDatabaseObserver.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmDatabaseObserver.h"
+#include "MockDatabaseObserver.h"
+
+namespace am {
+
+CAmDatabaseObserver::CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler) :
+mCommandSender(iCommandSender), //
+mRoutingSender(iRoutingSender), //
+mTelnetServer(NULL), //
+mSerializer(iSocketHandler) //
+{}
+
+CAmDatabaseObserver::~CAmDatabaseObserver() {}
+
+
+void CAmDatabaseObserver::numberOfSinkClassesChanged()
+{ MockDatabaseObserver::getMockObserverObject()->numberOfSinkClassesChanged(); }
+void CAmDatabaseObserver::numberOfSourceClassesChanged()
+{ MockDatabaseObserver::getMockObserverObject()->numberOfSourceClassesChanged(); }
+void CAmDatabaseObserver::newSink(const am_Sink_s& sink)
+{ MockDatabaseObserver::getMockObserverObject()->newSink(sink); }
+void CAmDatabaseObserver::newSource(const am_Source_s& source)
+{ MockDatabaseObserver::getMockObserverObject()->newSource(source); }
+void CAmDatabaseObserver::newDomain(const am_Domain_s& domain)
+{ MockDatabaseObserver::getMockObserverObject()->newDomain(domain); }
+void CAmDatabaseObserver::newGateway(const am_Gateway_s& gateway)
+{ MockDatabaseObserver::getMockObserverObject()->newGateway(gateway); }
+void CAmDatabaseObserver::newConverter(const am_Converter_s& coverter)
+{ MockDatabaseObserver::getMockObserverObject()->newConverter(coverter); }
+void CAmDatabaseObserver::newCrossfader(const am_Crossfader_s& crossfader)
+{ MockDatabaseObserver::getMockObserverObject()->newCrossfader(crossfader); }
+void CAmDatabaseObserver::newMainConnection(const am_MainConnectionType_s& mainConnection)
+{ MockDatabaseObserver::getMockObserverObject()->newMainConnection(mainConnection); }
+void CAmDatabaseObserver::removedMainConnection(const am_mainConnectionID_t mainConnection)
+{ MockDatabaseObserver::getMockObserverObject()->removedMainConnection(mainConnection); }
+void CAmDatabaseObserver::removedSink(const am_sinkID_t sinkID, const bool visible)
+{ MockDatabaseObserver::getMockObserverObject()->removedSink(sinkID, visible); }
+void CAmDatabaseObserver::removedSource(const am_sourceID_t sourceID, const bool visible)
+{ MockDatabaseObserver::getMockObserverObject()->removedSource(sourceID, visible); }
+void CAmDatabaseObserver::removeDomain(const am_domainID_t domainID)
+{ MockDatabaseObserver::getMockObserverObject()->removeDomain(domainID); }
+void CAmDatabaseObserver::removeGateway(const am_gatewayID_t gatewayID)
+{ MockDatabaseObserver::getMockObserverObject()->removeGateway(gatewayID); }
+void CAmDatabaseObserver::removeConverter(const am_converterID_t converterID)
+{ MockDatabaseObserver::getMockObserverObject()->removeConverter(converterID); }
+void CAmDatabaseObserver::removeCrossfader(const am_crossfaderID_t crossfaderID)
+{ MockDatabaseObserver::getMockObserverObject()->removeCrossfader(crossfaderID); }
+void CAmDatabaseObserver::mainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState)
+{ MockDatabaseObserver::getMockObserverObject()->mainConnectionStateChanged(connectionID, connectionState); }
+void CAmDatabaseObserver::mainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty)
+{ MockDatabaseObserver::getMockObserverObject()->mainSinkSoundPropertyChanged(sinkID, SoundProperty); }
+void CAmDatabaseObserver::mainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty)
+{ MockDatabaseObserver::getMockObserverObject()->mainSourceSoundPropertyChanged(sourceID, SoundProperty); }
+void CAmDatabaseObserver::sinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s& availability)
+{ MockDatabaseObserver::getMockObserverObject()->sinkAvailabilityChanged(sinkID, availability); }
+void CAmDatabaseObserver::sourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s& availability)
+{ MockDatabaseObserver::getMockObserverObject()->sourceAvailabilityChanged(sourceID, availability); }
+void CAmDatabaseObserver::volumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume)
+{ MockDatabaseObserver::getMockObserverObject()->volumeChanged(sinkID, volume); }
+void CAmDatabaseObserver::sinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState)
+{ MockDatabaseObserver::getMockObserverObject()->sinkMuteStateChanged(sinkID, muteState); }
+void CAmDatabaseObserver::systemPropertyChanged(const am_SystemProperty_s& SystemProperty)
+{ MockDatabaseObserver::getMockObserverObject()->systemPropertyChanged(SystemProperty); }
+void CAmDatabaseObserver::timingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time)
+{ MockDatabaseObserver::getMockObserverObject()->timingInformationChanged(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)
+{ MockDatabaseObserver::getMockObserverObject()->sinkUpdated(sinkID,sinkClassID,listMainSoundProperties, visible); }
+void CAmDatabaseObserver::sourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible)
+{ MockDatabaseObserver::getMockObserverObject()->sourceUpdated(sourceID,sourceClassID,listMainSoundProperties, visible); }
+void CAmDatabaseObserver::sinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration)
+{ MockDatabaseObserver::getMockObserverObject()->sinkMainNotificationConfigurationChanged(sinkID,mainNotificationConfiguration); }
+void CAmDatabaseObserver::sourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration)
+{ MockDatabaseObserver::getMockObserverObject()->sourceMainNotificationConfigurationChanged(sourceID,mainNotificationConfiguration); }
+}
+
diff --git a/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt
new file mode 100644
index 0000000..6588710
--- /dev/null
+++ b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt
@@ -0,0 +1,49 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmMapHandlerTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_UTILITIES_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS}
+)
+
+file(GLOB DATABASE_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "CAmTestDatabaseObserver.cpp"
+ "*.cpp"
+ )
+
+ADD_EXECUTABLE( AmMapHandlerTest ${DATABASE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES( AmMapHandlerTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmMapHandlerTest AudioManagerCore)
+
+INSTALL(TARGETS AmMapHandlerTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt~ b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt~
new file mode 100644
index 0000000..05d2a05
--- /dev/null
+++ b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt~
@@ -0,0 +1,54 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmMapHandlerTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_UTILITIES_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+)
+
+if(WITH_DLT)
+ INCLUDE_DIRECTORIES(
+ ${INCLUDE_DIRECTORIES}
+ ${DLT_INCLUDE_DIRS})
+endif(WITH_DLT)
+
+file(GLOB DATABASE_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "CAmTestDatabaseObserver.cpp"
+ "*.cpp"
+ )
+
+ADD_EXECUTABLE( AmMapHandlerTest ${DATABASE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES( AmMapHandlerTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmMapHandlerTest AudioManagerCore)
+
+INSTALL(TARGETS AmMapHandlerTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmMapHandlerTest/MockDatabaseObserver.h b/AudioManagerCore/test/AmMapHandlerTest/MockDatabaseObserver.h
new file mode 100644
index 0000000..da1b3b4
--- /dev/null
+++ b/AudioManagerCore/test/AmMapHandlerTest/MockDatabaseObserver.h
@@ -0,0 +1,120 @@
+/**
+ * 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 MockDatabaseObserver.h
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+
+#ifndef MOCKDATABASEOBSERVER_H_
+#define MOCKDATABASEOBSERVER_H_
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "CAmDatabaseObserver.h"
+
+class CAmCommandSender;
+class CAmRoutingSender;
+class CAmSocketHandler;
+class CAmTelnetServer;
+
+namespace am {
+using namespace testing;
+
+class IAmDatabaseObserver
+{
+public:
+ IAmDatabaseObserver() {};
+ virtual ~IAmDatabaseObserver() {};
+
+ virtual void numberOfSinkClassesChanged() = 0;
+ virtual void numberOfSourceClassesChanged() = 0;
+ virtual void newSink(const am_Sink_s& sink) = 0;
+ virtual void newSource(const am_Source_s& source) = 0;
+ virtual void newDomain(const am_Domain_s& domain) = 0;
+ virtual void newGateway(const am_Gateway_s& gateway) = 0;
+ virtual void newConverter(const am_Converter_s& coverter) = 0;
+ virtual void newCrossfader(const am_Crossfader_s& crossfader) = 0;
+ virtual void newMainConnection(const am_MainConnectionType_s& mainConnection) = 0;
+ virtual void removedMainConnection(const am_mainConnectionID_t mainConnection) = 0;
+ virtual void removedSink(const am_sinkID_t sinkID, const bool visible) = 0;
+ virtual void removedSource(const am_sourceID_t sourceID, const bool visible) = 0;
+ virtual void removeDomain(const am_domainID_t domainID) = 0;
+ virtual void removeGateway(const am_gatewayID_t gatewayID) = 0;
+ virtual void removeConverter(const am_converterID_t converterID) = 0;
+ virtual void removeCrossfader(const am_crossfaderID_t crossfaderID) = 0;
+ virtual void mainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState) = 0;
+ virtual void mainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty) = 0;
+ virtual void mainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty) = 0;
+ virtual void sinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s& availability) = 0;
+ virtual void sourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s& availability) = 0;
+ virtual void volumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume) = 0;
+ virtual void sinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState) = 0;
+ virtual void systemPropertyChanged(const am_SystemProperty_s& SystemProperty) = 0;
+ virtual void timingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time) = 0;
+ virtual void sinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) = 0;
+ virtual void sourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) = 0;
+ virtual void sinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) = 0;
+ virtual void sourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) = 0;
+
+};
+
+class MockDatabaseObserver : public IAmDatabaseObserver{
+ public:
+ MOCK_METHOD0(numberOfSinkClassesChanged, void());
+ MOCK_METHOD0(numberOfSourceClassesChanged, void());
+ MOCK_METHOD1(newSink, void(const am_Sink_s& sink));
+ MOCK_METHOD1(newSource, void(const am_Source_s& source));
+ MOCK_METHOD1(newDomain, void(const am_Domain_s& domain));
+ MOCK_METHOD1(newGateway, void(const am_Gateway_s& gateway));
+ MOCK_METHOD1(newConverter, void(const am_Converter_s& converter));
+ MOCK_METHOD1(newCrossfader, void(const am_Crossfader_s& crossfader));
+ MOCK_METHOD1(newMainConnection, void(const am_MainConnectionType_s & mainConnection));
+ MOCK_METHOD1(removedMainConnection, void(const am_mainConnectionID_t mainConnection));
+ MOCK_METHOD2(removedSink, void(const am_sinkID_t sinkID, const bool visible));
+ MOCK_METHOD2(removedSource, void(const am_sourceID_t sourceID, const bool visible));
+ MOCK_METHOD1(removeDomain, void(const am_domainID_t domainID));
+ MOCK_METHOD1(removeGateway, void(const am_gatewayID_t gatewayID));
+ MOCK_METHOD1(removeConverter, void(const am_converterID_t converterID));
+ MOCK_METHOD1(removeCrossfader, void(const am_crossfaderID_t crossfaderID));
+ MOCK_METHOD2(mainConnectionStateChanged, void(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState));
+ MOCK_METHOD2(mainSinkSoundPropertyChanged, void(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty));
+ MOCK_METHOD2(mainSourceSoundPropertyChanged, void(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty));
+ MOCK_METHOD2(sinkAvailabilityChanged, void(const am_sinkID_t sinkID, const am_Availability_s& availability));
+ MOCK_METHOD2(sourceAvailabilityChanged, void(const am_sourceID_t sourceID, const am_Availability_s& availability));
+ MOCK_METHOD2(volumeChanged, void(const am_sinkID_t sinkID, const am_mainVolume_t volume));
+ MOCK_METHOD2(sinkMuteStateChanged, void(const am_sinkID_t sinkID, const am_MuteState_e muteState));
+ MOCK_METHOD1(systemPropertyChanged, void(const am_SystemProperty_s& SystemProperty));
+ MOCK_METHOD2(timingInformationChanged, void(const am_mainConnectionID_t mainConnection, const am_timeSync_t time));
+ MOCK_METHOD4(sinkUpdated, void(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible));
+ MOCK_METHOD4(sourceUpdated, void(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible));
+ MOCK_METHOD2(sinkMainNotificationConfigurationChanged, void(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration));
+ MOCK_METHOD2(sourceMainNotificationConfigurationChanged, void(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration));
+
+ static MockDatabaseObserver *getMockObserverObject()
+ {
+ static MockDatabaseObserver glMockObserverObject;
+ return &glMockObserverObject;
+ }
+};
+
+
+
+} // namespace am
+#endif /* MOCKDATABASEOBSERVER_H_ */
diff --git a/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.cpp b/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.cpp
new file mode 100644
index 0000000..f95a24a
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.cpp
@@ -0,0 +1,3183 @@
+/**
+ * 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, 2014
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <ctime>
+#include <chrono>
+#include "CAmRouterMapTest.h"
+#include <string.h>
+#include "CAmDltWrapper.h"
+#include "CAmCommandLineSingleton.h"
+
+TCLAP::SwitchArg enableNoDLTDebug ("V","logDlt","print DLT logs to stdout or dlt-daemon default off",false);
+
+
+using namespace am;
+using namespace testing;
+
+CAmRouterMapTest::CAmRouterMapTest() :
+ plistRoutingPluginDirs(), //
+ plistCommandPluginDirs(), //
+ pSocketHandler(), //
+ pControlSender(), //
+ pDatabaseHandler(),
+ pRouter(&pDatabaseHandler, &pControlSender), //
+ pRoutingSender(plistRoutingPluginDirs), //
+ pCommandSender(plistCommandPluginDirs), //
+ pMockInterface(), //
+ pMockControlInterface(), //
+ pRoutingInterfaceBackdoor(), //
+ pCommandInterfaceBackdoor(), //
+ pControlInterfaceBackdoor(), //
+ pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender,&pSocketHandler, &pRouter), //
+ pObserver(&pCommandSender, &pRoutingSender, &pSocketHandler)
+{
+ pDatabaseHandler.registerObserver(&pObserver);
+ pCommandInterfaceBackdoor.injectInterface(&pCommandSender, &pMockInterface);
+ pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface);
+}
+
+CAmRouterMapTest::~CAmRouterMapTest()
+{
+
+}
+
+void CAmRouterMapTest::SetUp()
+{
+ logInfo("Routing Test started ");
+}
+
+void CAmRouterMapTest::TearDown()
+{
+}
+
+ACTION(returnConnectionFormat){
+ arg4=arg3;
+}
+
+void CAmRouterMapTest::enterDomainDB(const std::string & domainName, am_domainID_t & domainID)
+{
+ am_Domain_s domain1;
+ domain1.domainID = 0;
+ domain1.name = domainName;
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID));
+}
+
+void CAmRouterMapTest::enterSourceDB(const std::string & sourceName, const am_domainID_t domainID, const std::vector<am_CustomConnectionFormat_t> & connectionFormats, am_sourceID_t & sourceID)
+{
+ am_Source_s source;
+ source.domainID = domainID;
+ source.name = sourceName;
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats = connectionFormats;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+}
+
+void CAmRouterMapTest::enterSinkDB(const std::string & sinkName, const am_domainID_t domainID, const std::vector<am_CustomConnectionFormat_t> & connectionFormats, am_sinkID_t & sinkID)
+{
+ am_Sink_s sink;
+ sink.domainID = domainID;
+ sink.name = sinkName;
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats = connectionFormats;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+}
+
+void CAmRouterMapTest::enterGatewayDB(const std::string & gwName,
+ const am_domainID_t domainSourceID,
+ const am_domainID_t domainSinkID,
+ const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats,
+ const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats,
+ const std::vector<bool> & matrix,
+ const am_sourceID_t & sourceID,
+ const am_sinkID_t & sinkID,
+ am_gatewayID_t & gatewayID)
+{
+ am_Gateway_s gateway;
+ gateway.controlDomainID = domainSourceID;
+ gateway.gatewayID = 0;
+ gateway.sinkID = sinkID;
+ gateway.sourceID = sourceID;
+ gateway.domainSourceID = domainSourceID;
+ gateway.domainSinkID = domainSinkID;
+ gateway.listSinkFormats = sinkConnectionFormats;
+ gateway.listSourceFormats = sourceConnectionFormats;
+ gateway.convertionMatrix = matrix;
+ gateway.name = gwName;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+}
+
+void CAmRouterMapTest::enterConverterDB(const std::string & gwName,
+ const am_domainID_t domainID,
+ const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats,
+ const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats,
+ const std::vector<bool> & matrix,
+ const am_sourceID_t & sourceID,
+ const am_sinkID_t & sinkID,
+ am_converterID_t & converterID)
+{
+ am_Converter_s converter;
+ converter.converterID = 0;
+ converter.sinkID = sinkID;
+ converter.sourceID = sourceID;
+ converter.domainID = domainID;
+ converter.listSinkFormats = sinkConnectionFormats;
+ converter.listSourceFormats = sourceConnectionFormats;
+ converter.convertionMatrix = matrix;
+ converter.name = gwName;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterConverterDB(converter,converterID));
+}
+
+void CAmRouterMapTest::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes)
+{
+ std::ios_base::fmtflags oldflags = std::cout.flags();
+ std::streamsize oldprecision = std::cout.precision();
+ auto t_start = std::chrono::high_resolution_clock::now();
+ ASSERT_EQ(E_OK, pRouter.getRoute(onlyfree, aSource, aSink, listRoutes));
+ auto t_end = std::chrono::high_resolution_clock::now();
+ std::cout << std::fixed << std::setprecision(2);
+ std::cout << "getRoute did find " << listRoutes.size() <<" routes from " << aSource.sourceID << " to " << aSink.sinkID;
+ std::cout << " in " << std::chrono::duration<double, std::milli>(t_end-t_start).count() << " ms\n";
+ std::cout.flags (oldflags);
+ std::cout.precision (oldprecision);
+}
+
+void CAmRouterMapTest::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList)
+{
+ std::ios_base::fmtflags oldflags = std::cout.flags();
+ std::streamsize oldprecision = std::cout.precision();
+ auto t_start = std::chrono::high_resolution_clock::now();
+ ASSERT_EQ(E_OK, pRouter.getRoute(onlyfree, sourceID, sinkID, returnList));
+ auto t_end = std::chrono::high_resolution_clock::now();
+ std::cout << std::fixed << std::setprecision(2);
+ std::cout << "getRoute by id did find " << returnList.size() <<" routes from " << sourceID << " to " << sinkID;
+ std::cout << " in " << std::chrono::duration<double, std::milli>(t_end-t_start).count() << " ms\n";
+ std::cout.flags (oldflags);
+ std::cout.precision (oldprecision);
+}
+
+void CAmRouterMapTest::getAllPaths(CAmRoutingNode & aSource,
+ CAmRoutingNode & aSink,
+ std::vector<am_Route_s> & resultPath,
+ std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath,
+ const bool includeCycles)
+{
+ std::ios_base::fmtflags oldflags = std::cout.flags();
+ std::streamsize oldprecision = std::cout.precision();
+ auto t_start = std::chrono::high_resolution_clock::now();
+ ASSERT_EQ(E_OK, pRouter.getAllPaths(aSource, aSink, resultPath, resultNodesPath, includeCycles));
+ auto t_end = std::chrono::high_resolution_clock::now();
+ std::cout << std::fixed << std::setprecision(2);
+ std::cout << "getAllPaths did find " << resultPath.size()
+ << " routes from " << aSource.getData().data.source->sourceID
+ << " to " << aSink.getData().data.sink->sinkID;
+ std::cout << " in " << std::chrono::duration<double, std::milli>(t_end-t_start).count() << " ms\n";
+ std::cout.flags (oldflags);
+ std::cout.precision (oldprecision);
+}
+
+TEST_F(CAmRouterMapTest,checkInsertedDomain)
+{
+ std::vector<am_domainID_t> domains;
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22));
+ domains.push_back(22);
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22));
+ domains.push_back(22);
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22));
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 50));
+ domains.push_back(30);
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30));
+ ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22));
+ domains.push_back(30);
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30));
+ ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22));
+ ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 60));
+}
+
+//test that checks just sinks and source in a domain but connectionformats do not match
+TEST_F(CAmRouterMapTest,simpleRoute2withDomainNoMatchFormats)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1;
+ am_domainID_t domainID1;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+
+ am_Source_s source;
+ am_sourceID_t sourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+
+ sink.domainID = domainID1;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+
+ hopp1.sinkID = sinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(true, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+}
+
+//test that checks just sinks and source in a domain
+TEST_F(CAmRouterMapTest,simpleRoute2withDomain)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1;
+ am_domainID_t domainID1;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+
+ am_Source_s source;
+ am_sourceID_t sourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+
+ sink.domainID = domainID1;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+
+ hopp1.sinkID = sinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(true, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(CAmRouterMapTest,simpleRoute2DomainsOnlyFree)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+
+ getRoute(true,sourceID,sinkID,listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(CAmRouterMapTest,simpleRoute2DomainsOnlyFreeNotFree)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am_Connection_s connection,connection1;
+ am_connectionID_t id1,id2;
+ connection.sourceID=sourceID;
+ connection.sinkID=gwSinkID;
+ connection.connectionFormat=CF_GENIVI_ANALOG;
+ connection.connectionID=0;
+ connection1.sourceID=gwSourceID;
+ connection1.sinkID=sinkID;
+ connection1.connectionFormat=CF_GENIVI_ANALOG;
+ connection1.connectionID=0;
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConnectionDB(connection,id1));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConnectionDB(connection1,id2));
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(true, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+
+ listRoutes.clear();
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks just 2 domains, with gateway for each direction (possible circular route)
+TEST_F(CAmRouterMapTest,simpleRoute2DomainsCircularGWOnlyFree)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource, gwSource2;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID2;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource2.domainID = domainID1;
+ gwSource2.name = "gwsource2";
+ gwSource2.sourceState = SS_ON;
+ gwSource2.sourceID = 0;
+ gwSource2.sourceClassID = 5;
+ gwSource2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource2,gwSourceID2));
+
+ am_Sink_s sink, gwSink, gwSink2;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID2;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSink2.domainID = domainID2;
+ gwSink2.name = "gwSink2";
+ gwSink2.sinkID = 0;
+ gwSink2.sinkClassID = 5;
+ gwSink2.muteState = MS_MUTED;
+ gwSink2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink2,gwSinkID2));
+
+ am_Gateway_s gateway, gateway2;
+ am_gatewayID_t gatewayID, gatewayID2;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway2.controlDomainID = domainID1;
+ gateway2.gatewayID = 0;
+ gateway2.sinkID = gwSinkID2;
+ gateway2.sourceID = gwSourceID2;
+ gateway2.domainSourceID = domainID1;
+ gateway2.domainSinkID = domainID2;
+ gateway2.listSinkFormats = gwSink2.listConnectionFormats;
+ gateway2.listSourceFormats = gwSource2.listConnectionFormats;
+ gateway2.convertionMatrix.push_back(true);
+ gateway2.name = "gateway2";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(true, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 3 domains, one sink one source, longer lists of connectionformats.
+TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats_2)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(true);
+ gateway.convertionMatrix.push_back(true);
+ gateway.convertionMatrix.push_back(false);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(false);
+ gateway1.convertionMatrix.push_back(false);
+ gateway1.convertionMatrix.push_back(false);
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway1";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[1];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[1];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 3 domains, one sink one source, longer lists of connectionformats.
+TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats_1)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(true);
+ gateway.convertionMatrix.push_back(false);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+
+//test that checks 3 domains, one sink one source, longer lists of connectionformats.
+TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[1];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+
+//test that checks 4 domains, one sink and one source but there are 2 routes because there are 2 gateways
+TEST_F(CAmRouterMapTest,simpleRoute4Domains2Routes)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3, domain4;
+ am_domainID_t domainID1, domainID2, domainID3, domainID4;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+ domain4.domainID = 0;
+ domain4.name = "domain4";
+ domain4.busname = "domain4bus";
+ domain4.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain4,domainID4));
+
+ am_Source_s source, gwSource, gwSource1, gwSource2, gwSource3;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1, gwSourceID2, gwSourceID3;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource2.domainID = domainID4;
+ gwSource2.name = "gwsource3";
+ gwSource2.sourceState = SS_OFF;
+ gwSource2.sourceID = 0;
+ gwSource2.sourceClassID = 5;
+ gwSource2.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ gwSource3.domainID = domainID3;
+ gwSource3.name = "gwsource4";
+ gwSource3.sourceState = SS_OFF;
+ gwSource3.sourceID = 0;
+ gwSource3.sourceClassID = 5;
+ gwSource3.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource2,gwSourceID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource3,gwSourceID3));
+
+ am_Sink_s sink, gwSink, gwSink1, gwSink2, gwSink3;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1, gwSinkID2, gwSinkID3;
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSink2.domainID = domainID3;
+ gwSink2.name = "gwSink2";
+ gwSink2.sinkID = 0;
+ gwSink2.sinkClassID = 5;
+ gwSink2.muteState = MS_MUTED;
+ gwSink2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink3.domainID = domainID2;
+ gwSink3.name = "gwSink3";
+ gwSink3.sinkID = 0;
+ gwSink3.sinkClassID = 5;
+ gwSink3.muteState = MS_MUTED;
+ gwSink3.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ sink.domainID = domainID4;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink2,gwSinkID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink3,gwSinkID3));
+
+ am_Gateway_s gateway, gateway1, gateway2, gateway3;
+ am_gatewayID_t gatewayID, gatewayID1, gatewayID2, gatewayID3;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway1";
+
+ gateway2.controlDomainID = domainID3;
+ gateway2.gatewayID = 0;
+ gateway2.sinkID = gwSinkID2;
+ gateway2.sourceID = gwSourceID2;
+ gateway2.domainSourceID = domainID4;
+ gateway2.domainSinkID = domainID3;
+ gateway2.listSinkFormats = gwSink2.listConnectionFormats;
+ gateway2.listSourceFormats = gwSource2.listConnectionFormats;
+ gateway2.convertionMatrix.push_back(true);
+ gateway2.name = "gateway2";
+
+ gateway3.controlDomainID = domainID2;
+ gateway3.gatewayID = 0;
+ gateway3.sinkID = gwSinkID3;
+ gateway3.sourceID = gwSourceID3;
+ gateway3.domainSourceID = domainID3;
+ gateway3.domainSinkID = domainID2;
+ gateway3.listSinkFormats = gwSink3.listConnectionFormats;
+ gateway3.listSourceFormats = gwSource3.listConnectionFormats;
+ gateway3.convertionMatrix.push_back(true);
+ gateway3.name = "gateway3";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway3,gatewayID3));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements, listRoutingElements1;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+ am_RoutingElement_s hopp4;
+ am_RoutingElement_s hopp2alt;
+ am_RoutingElement_s hopp3alt;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = gwSinkID2;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = gwSink2.listConnectionFormats[0];
+
+ hopp4.sourceID = gwSourceID2;
+ hopp4.sinkID = sinkID;
+ hopp4.domainID = domainID4;
+ hopp4.connectionFormat = sink.listConnectionFormats[0];
+
+ hopp2alt.sourceID = gwSourceID;
+ hopp2alt.sinkID = gwSinkID3;
+ hopp2alt.domainID = domainID2;
+ hopp2alt.connectionFormat = gwSink3.listConnectionFormats[0];
+
+ hopp3alt.sourceID = gwSourceID3;
+ hopp3alt.sinkID = gwSinkID2;
+ hopp3alt.domainID = domainID3;
+ hopp3alt.connectionFormat = gwSink2.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+ listRoutingElements.push_back(hopp4);
+ listRoutingElements1.push_back(hopp1);
+ listRoutingElements1.push_back(hopp2alt);
+ listRoutingElements1.push_back(hopp3alt);
+ listRoutingElements1.push_back(hopp4);
+
+ am_Route_s compareRoute, compareRoute1;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ compareRoute1.route = listRoutingElements1;
+ compareRoute1.sinkID = sinkID;
+ compareRoute1.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(2), listRoutes.size());
+
+ bool containsRoute1 = std::find_if(listRoutes.begin(), listRoutes.end(), [&](const am_Route_s & ref) {
+ return pCF.compareRoute(compareRoute, ref);
+ })!=listRoutes.end();
+ bool containsRoute2 = std::find_if(listRoutes.begin(), listRoutes.end(), [&](const am_Route_s & ref) {
+ return pCF.compareRoute(compareRoute1, ref);
+ })!=listRoutes.end();
+
+ ASSERT_TRUE(containsRoute1);
+ ASSERT_TRUE(containsRoute2);
+}
+
+//test that checks 3 domains, one sink one source but the connectionformat of third domains do not fit.
+TEST_F(CAmRouterMapTest,simpleRoute3DomainsNoConnection)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+}
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(CAmRouterMapTest,simpleRoute2Domains)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks just 2 domains, one sink one source but the connectionformat of source
+TEST_F(CAmRouterMapTest,simpleRoute2DomainsNoMatchConnectionFormats)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+ }
+
+//test that checks 3 domains, one sink one source.
+TEST_F(CAmRouterMapTest,simpleRoute3Domains)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 4 domains, one sink and one source.
+TEST_F(CAmRouterMapTest,simpleRoute4Domains)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3, domain4;
+ am_domainID_t domainID1, domainID2, domainID3, domainID4;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+ domain4.domainID = 0;
+ domain4.name = "domain4";
+ domain4.busname = "domain4bus";
+ domain4.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain4,domainID4));
+
+ am_Source_s source, gwSource, gwSource1, gwSource2;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1, gwSourceID2;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource2.domainID = domainID4;
+ gwSource2.name = "gwsource3";
+ gwSource2.sourceState = SS_OFF;
+ gwSource2.sourceID = 0;
+ gwSource2.sourceClassID = 5;
+ gwSource2.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource2,gwSourceID2));
+
+ am_Sink_s sink, gwSink, gwSink1, gwSink2;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1, gwSinkID2;
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSink2.domainID = domainID3;
+ gwSink2.name = "gwSink2";
+ gwSink2.sinkID = 0;
+ gwSink2.sinkClassID = 5;
+ gwSink2.muteState = MS_MUTED;
+ gwSink2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ sink.domainID = domainID4;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink2,gwSinkID2));
+
+ am_Gateway_s gateway, gateway1, gateway2;
+ am_gatewayID_t gatewayID, gatewayID1, gatewayID2;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway1";
+
+ gateway2.controlDomainID = domainID3;
+ gateway2.gatewayID = 0;
+ gateway2.sinkID = gwSinkID2;
+ gateway2.sourceID = gwSourceID2;
+ gateway2.domainSourceID = domainID4;
+ gateway2.domainSinkID = domainID3;
+ gateway2.listSinkFormats = gwSink2.listConnectionFormats;
+ gateway2.listSourceFormats = gwSource2.listConnectionFormats;
+ gateway2.convertionMatrix.push_back(true);
+ gateway2.name = "gateway2";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+ am_RoutingElement_s hopp4;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = gwSinkID2;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = gwSink2.listConnectionFormats[0];
+
+ hopp4.sourceID = gwSourceID2;
+ hopp4.sinkID = sinkID;
+ hopp4.domainID = domainID4;
+ hopp4.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+ listRoutingElements.push_back(hopp4);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am::am_Source_s sourceDb;
+ am::am_Sink_s sinkDb;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb);
+ pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb);
+ listRoutes.clear();
+ getRoute(false, sourceDb, sinkDb, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest,getAllowedFormatsFromConvMatrix)
+{
+ std::vector<bool> convertionMatrix;
+ convertionMatrix.push_back(1);
+ convertionMatrix.push_back(0);
+ convertionMatrix.push_back(0);
+ convertionMatrix.push_back(1);
+ convertionMatrix.push_back(1);
+ convertionMatrix.push_back(0);
+
+ std::vector<am_CustomConnectionFormat_t> listSourceFormats;
+ listSourceFormats.push_back(CF_GENIVI_ANALOG);
+ listSourceFormats.push_back(CF_GENIVI_STEREO);
+
+ std::vector<am_CustomConnectionFormat_t> listSinkFormats;
+ listSinkFormats.push_back(CF_GENIVI_MONO);
+ listSinkFormats.push_back(CF_GENIVI_AUTO);
+ listSinkFormats.push_back(CF_GENIVI_STEREO);
+
+ std::vector<am_CustomConnectionFormat_t> sourceFormats;
+ std::vector<am_CustomConnectionFormat_t> sinkFormats;
+
+ ASSERT_TRUE(CAmRouter::getAllowedFormatsFromConvMatrix(convertionMatrix, listSourceFormats, listSinkFormats, sourceFormats, sinkFormats));
+
+ ASSERT_TRUE(sourceFormats.size()==3);
+ ASSERT_TRUE(sinkFormats.size()==3);
+ ASSERT_TRUE(sourceFormats.at(0)==CF_GENIVI_ANALOG);
+ ASSERT_TRUE(sourceFormats.at(1)==CF_GENIVI_STEREO);
+ ASSERT_TRUE(sourceFormats.at(2)==CF_GENIVI_ANALOG);
+ ASSERT_TRUE(sinkFormats.at(0)==CF_GENIVI_MONO);
+ ASSERT_TRUE(sinkFormats.at(1)==CF_GENIVI_AUTO);
+ ASSERT_TRUE(sinkFormats.at(2)==CF_GENIVI_STEREO);
+
+ sinkFormats.clear();
+ sourceFormats.clear();
+ convertionMatrix.clear();
+ listSinkFormats.clear();
+ listSourceFormats.clear();
+
+ convertionMatrix.push_back(1);
+ listSinkFormats.push_back(CF_GENIVI_STEREO);
+ listSourceFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_TRUE(CAmRouter::getAllowedFormatsFromConvMatrix(convertionMatrix, listSourceFormats, listSinkFormats, sourceFormats, sinkFormats));
+
+ sinkFormats.clear();
+ sourceFormats.clear();
+ convertionMatrix.clear();
+ listSinkFormats.clear();
+ listSourceFormats.clear();
+
+ convertionMatrix.push_back(1);
+ convertionMatrix.push_back(0);
+ listSourceFormats.push_back(CF_GENIVI_STEREO);
+ listSinkFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_FALSE(CAmRouter::getAllowedFormatsFromConvMatrix(convertionMatrix, listSourceFormats, listSinkFormats, sourceFormats, sinkFormats));
+
+ sinkFormats.clear();
+ sourceFormats.clear();
+ convertionMatrix.clear();
+ listSinkFormats.clear();
+ listSourceFormats.clear();
+
+ convertionMatrix.push_back(1);
+ listSinkFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_FALSE(CAmRouter::getAllowedFormatsFromConvMatrix(convertionMatrix, listSourceFormats, listSinkFormats, sourceFormats, sinkFormats));
+}
+
+TEST_F(CAmRouterMapTest,route1Domain1Source1Sink)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domainID1;
+ enterDomainDB("domain1", domainID1);
+
+ am_sourceID_t sourceID;
+ std::vector<am_CustomConnectionFormat_t> cf1;
+ cf1.push_back(CF_GENIVI_STEREO);
+ cf1.push_back(CF_GENIVI_ANALOG);
+ enterSourceDB("source1", domainID1, cf1, sourceID);
+
+ am_sinkID_t sinkID;
+ std::vector<am_CustomConnectionFormat_t> cf2;
+ cf2.push_back(CF_GENIVI_ANALOG);
+ cf2.push_back(CF_GENIVI_MONO);
+ enterSinkDB("sink1", domainID1, cf2, sinkID);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+
+ pDatabaseHandler.getSinkInfoDB(sinkID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = sinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = cf2[0];
+
+ listRoutingElements.push_back(hopp1);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest,route1Domain1Source1Converter1Sink)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domainID1;
+ enterDomainDB("domain1", domainID1);
+
+ am_sourceID_t sourceID;
+ std::vector<am_CustomConnectionFormat_t> cf1;
+ cf1.push_back(CF_GENIVI_STEREO);
+ cf1.push_back(CF_GENIVI_AUTO);
+ enterSourceDB("source1", domainID1, cf1, sourceID);
+
+ am_sinkID_t sinkID1, sinkID2;
+ std::vector<am_CustomConnectionFormat_t> cf2;
+ cf2.push_back(CF_GENIVI_MONO);
+ cf2.push_back(CF_GENIVI_ANALOG);
+ enterSinkDB("sink1", domainID1, cf2, sinkID1);
+ enterSinkDB("sink2", domainID1, cf2, sinkID2);
+
+ am_sourceID_t gwSourceID;
+ std::vector<am_CustomConnectionFormat_t> cf3;
+ cf3.push_back(CF_GENIVI_MONO);
+ cf3.push_back(CF_GENIVI_ANALOG);
+ enterSourceDB("gwSource1", domainID1, cf3, gwSourceID);
+
+ am_sinkID_t gwSinkID;
+ std::vector<am_CustomConnectionFormat_t> cf4;
+ cf4.push_back(CF_GENIVI_STEREO);
+ cf4.push_back(CF_GENIVI_ANALOG);
+ enterSinkDB("gwSink1", domainID1, cf4, gwSinkID);
+
+ am_converterID_t converterID;
+ std::vector<bool> matrix;
+ matrix.resize(4, false);
+ matrix[0]=(true);
+ matrix[1]=(true);
+ enterConverterDB("converter", domainID1, cf3, cf4, matrix, gwSourceID, gwSinkID, converterID);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+
+ pDatabaseHandler.getSinkInfoDB(sinkID1, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = CF_GENIVI_STEREO;
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = sinkID1;
+ hopp2.domainID = domainID1;
+ hopp2.connectionFormat = CF_GENIVI_MONO;
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID1;
+ compareRoute.sourceID = sourceID;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest,route1Domain1Source3Converters1Sink)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domainID1;
+ enterDomainDB("domain1", domainID1);
+
+ std::vector<am_CustomConnectionFormat_t> cf1;
+ cf1.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cf2;
+ cf2.push_back(CF_GENIVI_MONO);
+ std::vector<am_CustomConnectionFormat_t> cf3;
+ cf3.push_back(CF_GENIVI_AUTO);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cf1, sourceID);
+
+ am_sinkID_t sinkID;
+ enterSinkDB("sink1", domainID1, cf3, sinkID);
+
+ am_sourceID_t gwSourceID;
+ enterSourceDB("gwSource1", domainID1, cf2, gwSourceID);
+ am_sinkID_t gwSinkID;
+ enterSinkDB("gwSink1", domainID1, cf1, gwSinkID);
+ am_converterID_t converterID;
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ enterConverterDB("converter1", domainID1, cf2, cf1, matrix, gwSourceID, gwSinkID, converterID);
+
+ am_sourceID_t gwSourceID1;
+ enterSourceDB("gwSource2", domainID1, cf2, gwSourceID1);
+ am_sinkID_t gwSinkID1;
+ enterSinkDB("gwSink2", domainID1, cf1, gwSinkID1);
+ am_converterID_t converterID1;
+ enterConverterDB("converter2", domainID1, cf2, cf1, matrix, gwSourceID1, gwSinkID1, converterID1);
+
+ am_sourceID_t gwSourceID2;
+ enterSourceDB("gwSource3", domainID1, cf3, gwSourceID2);
+ am_sinkID_t gwSinkID2;
+ enterSinkDB("gwSink3", domainID1, cf2, gwSinkID2);
+ am_converterID_t converterID2;
+ enterConverterDB("converter3", domainID1, cf3, cf2, matrix, gwSourceID2, gwSinkID2, converterID2);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements1;
+ std::vector<am_RoutingElement_s> listRoutingElements2;
+ am_RoutingElement_s hopp11;
+ am_RoutingElement_s hopp12;
+ am_RoutingElement_s hopp13;
+ am_RoutingElement_s hopp21;
+ am_RoutingElement_s hopp22;
+
+ hopp11.sourceID = sourceID;
+ hopp11.sinkID = gwSinkID;
+ hopp11.domainID = domainID1;
+ hopp11.connectionFormat = CF_GENIVI_STEREO;
+
+ hopp12.sourceID = gwSourceID;
+ hopp12.sinkID = gwSinkID2;
+ hopp12.domainID = domainID1;
+ hopp12.connectionFormat = CF_GENIVI_MONO;
+
+ hopp21.sourceID = sourceID;
+ hopp21.sinkID = gwSinkID1;
+ hopp21.domainID = domainID1;
+ hopp21.connectionFormat = CF_GENIVI_STEREO;
+
+ hopp22.sourceID = gwSourceID1;
+ hopp22.sinkID = gwSinkID2;
+ hopp22.domainID = domainID1;
+ hopp22.connectionFormat = CF_GENIVI_MONO;
+
+ hopp13.sourceID = gwSourceID2;
+ hopp13.sinkID = sinkID;
+ hopp13.domainID = domainID1;
+ hopp13.connectionFormat = CF_GENIVI_AUTO;
+
+ listRoutingElements1.push_back(hopp11);
+ listRoutingElements1.push_back(hopp12);
+ listRoutingElements1.push_back(hopp13);
+
+ listRoutingElements2.push_back(hopp21);
+ listRoutingElements2.push_back(hopp22);
+ listRoutingElements2.push_back(hopp13);
+
+ am_Route_s compareRoute1;
+ compareRoute1.route = listRoutingElements1;
+ compareRoute1.sinkID = sinkID;
+ compareRoute1.sourceID = sourceID;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(2), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])||pCF.compareRoute(compareRoute1,listRoutes[1]));
+
+ am_Route_s compareRoute2;
+ compareRoute2.route = listRoutingElements2;
+ compareRoute2.sinkID = sinkID;
+ compareRoute2.sourceID = sourceID;
+ ASSERT_TRUE(pCF.compareRoute(compareRoute2,listRoutes[1])||pCF.compareRoute(compareRoute2,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest,route2Domains1Source1Sink)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domainID1, domainID2;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+
+ am_sourceID_t sourceID;
+ std::vector<am_CustomConnectionFormat_t> cf1;
+ cf1.push_back(CF_GENIVI_STEREO);
+ enterSourceDB("source1", domainID1, cf1, sourceID);
+
+ am_sinkID_t sinkID;
+ std::vector<am_CustomConnectionFormat_t> cf2;
+ cf2.push_back(CF_GENIVI_ANALOG);
+ enterSinkDB("sink1", domainID2, cf2, sinkID);
+
+ am_sourceID_t gwSourceID;
+ std::vector<am_CustomConnectionFormat_t> cf3;
+ cf3.push_back(CF_GENIVI_ANALOG);
+ enterSourceDB("gwSource1", domainID2, cf3, gwSourceID);
+
+ am_sinkID_t gwSinkID;
+ std::vector<am_CustomConnectionFormat_t> cf4;
+ cf4.push_back(CF_GENIVI_STEREO);
+ enterSinkDB("gwSink1", domainID1, cf4, gwSinkID);
+
+ am_gatewayID_t gatewayID;
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ enterGatewayDB("gateway", domainID2, domainID1, cf3, cf4, matrix, gwSourceID, gwSinkID, gatewayID);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+
+ pDatabaseHandler.getSinkInfoDB(sinkID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+ std::vector<am_Route_s> listRoutes;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sinkID;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, gwSinkID, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gwSourceID, sinkID, domainID2, CF_GENIVI_ANALOG});
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest,route3Domains1Source1Sink)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domainID1, domainID2, domainID3;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+ enterDomainDB("domain3", domainID3);
+
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog;
+ cfAnalog.push_back(CF_GENIVI_ANALOG);
+ std::vector<am_CustomConnectionFormat_t> cfMono;
+ cfMono.push_back(CF_GENIVI_MONO);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cfStereo, sourceID);
+
+ am_sinkID_t gwSinkID1;
+ enterSinkDB("gwSink1", domainID1, cfStereo, gwSinkID1);
+
+ am_sourceID_t gwSourceID1;
+ enterSourceDB("gwSource1", domainID2, cfMono, gwSourceID1);
+
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+
+ am_gatewayID_t gatewayID;
+ enterGatewayDB("gateway", domainID2, domainID1, cfMono, cfStereo, matrix, gwSourceID1, gwSinkID1, gatewayID);
+
+ am_sourceID_t gwSourceID2;
+ enterSourceDB("gwSource2", domainID3, cfStereo, gwSourceID2);
+
+ am_sinkID_t gwSinkID2;
+ enterSinkDB("gwSink2", domainID2, cfMono, gwSinkID2);
+
+ am_sinkID_t sinkID;
+ enterSinkDB("sink1", domainID3, cfStereo, sinkID);
+
+ am_gatewayID_t gatewayID1;
+ enterGatewayDB("gateway", domainID3, domainID2, cfStereo, cfMono, matrix, gwSourceID2, gwSinkID2, gatewayID1);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+
+ pDatabaseHandler.getSinkInfoDB(sinkID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sinkID;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gwSourceID1, gwSinkID2, domainID2, CF_GENIVI_MONO});
+ compareRoute1.route.push_back({gwSourceID2, sinkID, domainID3, CF_GENIVI_STEREO});
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest,routeSource1Sink2PathThroughConv1Gate1)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ am_domainID_t domainID1, domainID2;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog;
+ cfAnalog.push_back(CF_GENIVI_ANALOG);
+ std::vector<am_CustomConnectionFormat_t> cfMono;
+ cfMono.push_back(CF_GENIVI_MONO);
+ std::vector<am_CustomConnectionFormat_t> cfAuto;
+ cfAuto.push_back(CF_GENIVI_AUTO);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cfStereo, sourceID);
+
+ am_sinkID_t gwSinkID1;
+ enterSinkDB("gwSink1", domainID1, cfMono, gwSinkID1);
+
+ am_sinkID_t coSinkID21;
+ enterSinkDB("coSink21", domainID1, cfStereo, coSinkID21);
+
+ am_sourceID_t coSourceID21;
+ enterSourceDB("coSource21", domainID1, cfMono, coSourceID21);
+
+ am_converterID_t converterID1;
+ enterConverterDB("converter1", domainID1, cfMono, cfStereo, matrix, coSourceID21, coSinkID21, converterID1);
+
+ am_sourceID_t gwSourceID1;
+ enterSourceDB("gwSource21", domainID2, cfAuto, gwSourceID1);
+
+ am_gatewayID_t gatewayID;
+ enterGatewayDB("gateway1", domainID2, domainID1, cfAuto, cfMono, matrix, gwSourceID1, gwSinkID1, gatewayID);
+
+ am_sinkID_t sinkID1;
+ enterSinkDB("sink1", domainID2, cfAuto, sinkID1);
+
+ am_sinkID_t sinkID2;
+ enterSinkDB("sink2", domainID1, cfAuto, sinkID2);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink1;
+ pDatabaseHandler.getSinkInfoDB(sinkID1, sink1);
+ am::am_Sink_s sink2;
+ pDatabaseHandler.getSinkInfoDB(sinkID2, sink2);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+
+ getRoute(false, source, sink1, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sinkID1;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, coSinkID21, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({coSourceID21, gwSinkID1, domainID1, CF_GENIVI_MONO});
+ compareRoute1.route.push_back({gwSourceID1, sinkID1, domainID2, CF_GENIVI_AUTO});
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0]));
+
+ listRoutes.clear();
+ getRoute(false, source, sink2, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+}
+
+TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughDomain2)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ am_domainID_t domainID1, domainID2;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog;
+ cfAnalog.push_back(CF_GENIVI_ANALOG);
+ std::vector<am_CustomConnectionFormat_t> cfMono;
+ cfMono.push_back(CF_GENIVI_MONO);
+ std::vector<am_CustomConnectionFormat_t> cfAuto;
+ cfAuto.push_back(CF_GENIVI_AUTO);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cfStereo, sourceID);
+
+ am_sinkID_t gwSinkID11;
+ enterSinkDB("gwSink11", domainID1, cfStereo, gwSinkID11);
+ am_sourceID_t gwSourceID11;
+ enterSourceDB("gwSource11", domainID2, cfAnalog, gwSourceID11);
+ am_converterID_t gatewayID1;
+ enterGatewayDB("gateway1", domainID2, domainID1, cfAnalog, cfStereo, matrix, gwSourceID11, gwSinkID11, gatewayID1);
+
+ am_sinkID_t gwSinkID21;
+ enterSinkDB("gwSink21", domainID2, cfAnalog, gwSinkID21);
+ am_sourceID_t gwSourceID12;
+ enterSourceDB("gwSource12", domainID1, cfAuto, gwSourceID12);
+ am_gatewayID_t gatewayID2;
+ enterGatewayDB("gateway2", domainID1, domainID2, cfAuto, cfAnalog, matrix, gwSourceID12, gwSinkID21, gatewayID2);
+
+ am_sinkID_t sink1ID;
+ enterSinkDB("sink1", domainID1, cfAuto, sink1ID);
+ am_sinkID_t sink2ID;
+ enterSinkDB("sink2", domainID2, cfAnalog, sink2ID);
+
+ std::vector<am_Route_s> listRoutes;
+
+ am::am_Source_s source;
+ am::am_Sink_s sink1;
+ pDatabaseHandler.getSinkInfoDB(sink1ID, sink1);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ getRoute(false, source, sink1, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+
+ am::am_Sink_s sink2;
+ pDatabaseHandler.getSinkInfoDB(sink2ID, sink2);
+
+ getRoute(false, source, sink2, listRoutes);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sink2ID;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, gwSinkID11, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gwSourceID11, sink2ID, domainID2, CF_GENIVI_ANALOG});
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughGate1Conv2Gate2)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ am_domainID_t domainID1, domainID2;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog;
+ cfAnalog.push_back(CF_GENIVI_ANALOG);
+ std::vector<am_CustomConnectionFormat_t> cfMono;
+ cfMono.push_back(CF_GENIVI_MONO);
+ std::vector<am_CustomConnectionFormat_t> cfAuto;
+ cfAuto.push_back(CF_GENIVI_AUTO);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cfStereo, sourceID);
+
+ am_sinkID_t gwSinkID11;
+ enterSinkDB("gwSink11", domainID1, cfStereo, gwSinkID11);
+
+ am_sourceID_t gwSourceID21;
+ enterSourceDB("gwSource21", domainID2, cfAnalog, gwSourceID21);
+
+ am_converterID_t gatewayID1;
+ enterGatewayDB("gateway1", domainID2, domainID1, cfAnalog, cfStereo, matrix, gwSourceID21, gwSinkID11, gatewayID1);
+
+ am_sinkID_t gwSinkID21;
+ enterSinkDB("gwSink21", domainID2, cfStereo, gwSinkID21);
+
+ am_sourceID_t gwSourceID12;
+ enterSourceDB("gwSource12", domainID1, cfAuto, gwSourceID12);
+
+ am_sinkID_t coSinkID21;
+ enterSinkDB("coSink21", domainID2, cfAnalog, coSinkID21);
+
+ am_sourceID_t coSourceID21;
+ enterSourceDB("coSource21", domainID2, cfStereo, coSourceID21);
+
+ am_converterID_t converterID2;
+ enterConverterDB("converter2", domainID2, cfStereo, cfAnalog, matrix, coSourceID21, coSinkID21, converterID2);
+
+ am_gatewayID_t gatewayID2;
+ enterGatewayDB("gateway2", domainID1, domainID2, cfAuto, cfStereo, matrix, gwSourceID12, gwSinkID21, gatewayID2);
+
+ am_sinkID_t sink1ID;
+ enterSinkDB("sink1", domainID1, cfAuto, sink1ID);
+ am_sinkID_t sink2ID;
+ enterSinkDB("sink2", domainID2, cfStereo, sink2ID);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+
+ pDatabaseHandler.getSinkInfoDB(sink1ID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+
+ am::am_Sink_s sink1;
+ pDatabaseHandler.getSinkInfoDB(sink2ID, sink1);
+ getRoute(false, source, sink1, listRoutes);
+
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sink2ID;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, gwSinkID11, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gwSourceID21, coSinkID21, domainID2, CF_GENIVI_ANALOG});
+ compareRoute1.route.push_back({coSourceID21, sink2ID, domainID2, CF_GENIVI_STEREO});
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0]));
+}
+
+TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughConv1Gate1Conv2Gate2)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ am_domainID_t domainID1, domainID2;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog;
+ cfAnalog.push_back(CF_GENIVI_ANALOG);
+ std::vector<am_CustomConnectionFormat_t> cfMono;
+ cfMono.push_back(CF_GENIVI_MONO);
+ std::vector<am_CustomConnectionFormat_t> cfAuto;
+ cfAuto.push_back(CF_GENIVI_AUTO);
+ std::vector<am_CustomConnectionFormat_t> cfFuture1;
+ cfFuture1.push_back(5);
+ std::vector<am_CustomConnectionFormat_t> cfFuture2;
+ cfFuture2.push_back(6);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cfStereo, sourceID);
+
+ am_sinkID_t coSinkID11;
+ enterSinkDB("coSink11", domainID1, cfStereo, coSinkID11);
+ am_sourceID_t coSourceID11;
+ enterSourceDB("coSource11", domainID1, cfFuture1, coSourceID11);
+ am_converterID_t converterID11;
+ enterConverterDB("converter11", domainID1, cfFuture1, cfStereo, matrix, coSourceID11, coSinkID11, converterID11);
+
+ am_sinkID_t coSinkID12;
+ enterSinkDB("coSink12", domainID1, cfStereo, coSinkID12);
+ am_sourceID_t coSourceID12;
+ enterSourceDB("coSource12", domainID1, cfFuture2, coSourceID12);
+ am_converterID_t converterID12;
+ enterConverterDB("converter12", domainID1, cfFuture2, cfStereo, matrix, coSourceID12, coSinkID12, converterID12);
+
+ am_sinkID_t coSinkID13;
+ enterSinkDB("coSink13", domainID1, cfFuture2, coSinkID13);
+ am_sourceID_t coSourceID13;
+ enterSourceDB("coSource13", domainID1, cfFuture1, coSourceID13);
+ am_converterID_t converterID13;
+ enterConverterDB("converter13", domainID1, cfFuture1, cfFuture2, matrix, coSourceID13, coSinkID13, converterID13);
+
+ am_sinkID_t gwSinkID11;
+ enterSinkDB("gwSink11", domainID1, cfFuture1, gwSinkID11);
+ am_sourceID_t gwSourceID21;
+ enterSourceDB("gwSource21", domainID2, cfAnalog, gwSourceID21);
+ am_converterID_t gatewayID1;
+ enterGatewayDB("gateway1", domainID2, domainID1, cfAnalog, cfFuture1, matrix, gwSourceID21, gwSinkID11, gatewayID1);
+
+ am_sinkID_t gwSinkID21;
+ enterSinkDB("gwSink21", domainID2, cfStereo, gwSinkID21);
+
+ am_sourceID_t gwSourceID12;
+ enterSourceDB("gwSource12", domainID1, cfAuto, gwSourceID12);
+
+ am_sinkID_t coSinkID21;
+ enterSinkDB("coSink21", domainID2, cfAnalog, coSinkID21);
+
+ am_sourceID_t coSourceID21;
+ enterSourceDB("coSource21", domainID2, cfStereo, coSourceID21);
+
+ am_converterID_t converterID2;
+ enterConverterDB("converter2", domainID2, cfStereo, cfAnalog, matrix, coSourceID21, coSinkID21, converterID2);
+
+
+ am_gatewayID_t gatewayID2;
+ enterGatewayDB("gateway2", domainID1, domainID2, cfAuto, cfStereo, matrix, gwSourceID12, gwSinkID21, gatewayID2);
+
+ am_sinkID_t sinkID;
+ enterSinkDB("sink1", domainID1, cfAuto, sinkID);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+ pDatabaseHandler.getSinkInfoDB(sinkID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+
+ am::am_Sink_s sink2;
+ pDatabaseHandler.getSinkInfoDB(coSinkID21, sink2);
+ pRouter.getRoute(false, source, sink2, listRoutes);
+ ASSERT_EQ(static_cast<uint>(2), listRoutes.size());
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = coSinkID21;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, coSinkID11, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({coSourceID11, gwSinkID11, domainID1, 5});
+ compareRoute1.route.push_back({gwSourceID21, coSinkID21, domainID2, CF_GENIVI_ANALOG});
+
+ am_Route_s compareRoute2;
+ compareRoute2.sinkID = coSinkID21;
+ compareRoute2.sourceID = sourceID;
+ compareRoute2.route.push_back({sourceID, coSinkID12, domainID1, CF_GENIVI_STEREO});
+ compareRoute2.route.push_back({coSourceID12, coSinkID13, domainID1, 6});
+ compareRoute2.route.push_back({coSourceID13, gwSinkID11, domainID1, 5});
+ compareRoute2.route.push_back({gwSourceID21, coSinkID21, domainID2, CF_GENIVI_ANALOG});
+
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[1])||pCF.compareRoute(compareRoute1,listRoutes[0]));
+ ASSERT_TRUE(pCF.compareRoute(compareRoute2,listRoutes[0])||pCF.compareRoute(compareRoute2,listRoutes[1]));
+}
+
+TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domain1ID, domain2ID, domain3ID;
+ enterDomainDB("domain1", domain1ID);
+ enterDomainDB("domain2", domain2ID);
+ enterDomainDB("domain3", domain3ID);
+
+ //just make so many cycles as possible
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog = cfStereo;
+ std::vector<am_CustomConnectionFormat_t> cfMono = cfStereo;
+ std::vector<am_CustomConnectionFormat_t> cfAuto;
+ cfAuto.push_back(CF_GENIVI_AUTO);
+
+ am_sourceID_t source1ID;
+ enterSourceDB("source1", domain1ID, cfStereo, source1ID);
+ am_sinkID_t gw1SinkID;
+ enterSinkDB("gw1Sink", domain1ID, cfStereo, gw1SinkID);
+ am_sinkID_t gw2SinkID;
+ enterSinkDB("gw2Sink", domain1ID, cfStereo, gw2SinkID);
+ am_sourceID_t gw3SourceID;
+ enterSourceDB("gw3Source", domain1ID, cfAnalog, gw3SourceID);
+ am_sourceID_t gw4SourceID;
+ enterSourceDB("gw4Source", domain1ID, cfAnalog, gw4SourceID);
+ am_sinkID_t gw5SinkID;
+ enterSinkDB("gw5Sink", domain1ID, cfAnalog, gw5SinkID);
+
+ am_sourceID_t gw1SourceID;
+ enterSourceDB("gw1Source", domain2ID, cfMono, gw1SourceID);
+ am_sourceID_t gw2SourceID;
+ enterSourceDB("gw2Source", domain2ID, cfMono, gw2SourceID);
+ am_sinkID_t gw3SinkID;
+ enterSinkDB("gw3Sink", domain2ID, cfMono, gw3SinkID);
+ am_sinkID_t gw4SinkID;
+ enterSinkDB("gw4Sink", domain2ID, cfMono, gw4SinkID);
+
+ am_sourceID_t gw5SourceID;
+ enterSourceDB("gw5Source", domain3ID, cfStereo, gw5SourceID);
+ am_sinkID_t sink1ID;
+ enterSinkDB("sink1", domain3ID, cfStereo, sink1ID);
+
+ std::vector<bool> matrixT;
+ matrixT.push_back(true);
+ std::vector<bool> matrixF;
+ matrixF.push_back(false);
+
+ am_gatewayID_t gateway1ID;
+ enterGatewayDB("gateway1", domain2ID, domain1ID, cfMono, cfStereo, matrixT, gw1SourceID, gw1SinkID, gateway1ID);
+ am_gatewayID_t gateway2ID;
+ enterGatewayDB("gateway2", domain2ID, domain1ID, cfMono, cfStereo, matrixT, gw2SourceID, gw2SinkID, gateway2ID);
+ am_gatewayID_t gateway3ID;
+ enterGatewayDB("gateway3", domain1ID, domain2ID, cfAnalog, cfMono, matrixT, gw3SourceID, gw3SinkID, gateway3ID);
+ am_gatewayID_t gateway4ID;
+ enterGatewayDB("gateway4", domain1ID, domain2ID, cfAnalog, cfMono, matrixT, gw4SourceID, gw4SinkID, gateway4ID);
+ am_gatewayID_t gateway5ID;
+ enterGatewayDB("gateway5", domain3ID, domain1ID, cfStereo, cfAnalog, matrixT, gw5SourceID, gw5SinkID, gateway5ID);
+
+ pRouter.load(false);
+
+ CAmRoutingNode* sourceNode = pRouter.sourceNodeWithID(source1ID);
+ CAmRoutingNode* sinkNode = pRouter.sinkNodeWithID(sink1ID);
+
+ ASSERT_TRUE(sourceNode);
+ ASSERT_TRUE(sinkNode);
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<std::vector<CAmRoutingNode*>> resultNodesPath;
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sink1ID;
+ compareRoute1.sourceID = source1ID;
+
+#define DO_ASSERT() \
+ {\
+ bool didMatch = false; \
+ for(auto it = listRoutes.begin(); it!=listRoutes.end(); it++) \
+ didMatch|=pCF.compareRoute(compareRoute1,*it); \
+ ASSERT_TRUE(didMatch); \
+ }
+
+#ifdef ROUTING_BUILD_CONNECTIONS
+ getAllPaths(*sourceNode, *sinkNode, listRoutes, resultNodesPath, true);
+ ASSERT_EQ(static_cast<uint>(9), listRoutes.size());
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw4SourceID, gw1SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw3SourceID, gw1SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw3SourceID, gw2SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw4SourceID, gw2SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+ DO_ASSERT()
+#else
+ compareRoute1.route.clear();
+ compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO});
+#endif
+
+ listRoutes.clear();
+ resultNodesPath.clear();
+ getAllPaths(*sourceNode, *sinkNode, listRoutes, resultNodesPath, false);
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ DO_ASSERT()
+}
+
+TEST_F(CAmRouterMapTest,route3Domains1Source3Gateways3Convertres1Sink)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ am_domainID_t domainID1, domainID2, domainID3;
+ enterDomainDB("domain1", domainID1);
+ enterDomainDB("domain2", domainID2);
+ enterDomainDB("domain3", domainID3);
+
+ std::vector<am_CustomConnectionFormat_t> cfStereo;
+ cfStereo.push_back(CF_GENIVI_STEREO);
+ std::vector<am_CustomConnectionFormat_t> cfAnalog;
+ cfAnalog.push_back(CF_GENIVI_ANALOG);
+ std::vector<am_CustomConnectionFormat_t> cfMono;
+ cfMono.push_back(CF_GENIVI_MONO);
+ std::vector<am_CustomConnectionFormat_t> cfAuto;
+ cfAuto.push_back(CF_GENIVI_AUTO);
+
+ am_sourceID_t sourceID;
+ enterSourceDB("source1", domainID1, cfStereo, sourceID);
+ am_sinkID_t gwSinkID1;
+ enterSinkDB("gwSink1", domainID1, cfStereo, gwSinkID1);
+ am_sinkID_t gwSinkID21;
+ enterSinkDB("gwSink21", domainID1, cfStereo, gwSinkID21);
+
+ am_sourceID_t gwSourceID1;
+ enterSourceDB("gwSource1", domainID2, cfMono, gwSourceID1);
+ am_sinkID_t gwSinkID22;
+ enterSinkDB("gwSink22", domainID2, cfMono, gwSinkID22);
+
+ am_sourceID_t gwSourceID21;
+ enterSourceDB("gwSource21", domainID3, cfAuto, gwSourceID21);
+
+ am_sourceID_t gwSourceID22;
+ enterSourceDB("gwSource22", domainID3, cfAuto, gwSourceID22);
+ am_sourceID_t gwSourceID5;
+ enterSourceDB("gwSource5", domainID3, cfStereo, gwSourceID5);
+ am_sinkID_t gwSinkID5;
+ enterSinkDB("gwSink5", domainID3, cfAnalog, gwSinkID5);
+ am_sourceID_t gwSourceID3;
+ enterSourceDB("gwSource3", domainID3, cfAnalog, gwSourceID3);
+ am_sinkID_t gwSinkID3;
+ enterSinkDB("gwSink3", domainID3, cfAuto, gwSinkID3);
+ am_sourceID_t gwSourceID4;
+ enterSourceDB("gwSource4", domainID3, cfStereo, gwSourceID4);
+ am_sinkID_t gwSinkID4;
+ enterSinkDB("gwSink4", domainID3, cfAnalog, gwSinkID4);
+ am_sinkID_t sinkID;
+ enterSinkDB("sink1", domainID3, cfStereo, sinkID);
+
+ std::vector<bool> matrix;
+ matrix.push_back(true);
+ am_gatewayID_t gatewayID;
+ enterGatewayDB("gateway1", domainID2, domainID1, cfMono, cfStereo, matrix, gwSourceID1, gwSinkID1, gatewayID);
+ am_gatewayID_t gatewayID22;
+ enterGatewayDB("gateway22", domainID3, domainID2, cfAuto, cfMono, matrix, gwSourceID22, gwSinkID22, gatewayID22);
+ am_gatewayID_t gatewayID21;
+ enterGatewayDB("gateway21", domainID3, domainID1, cfAuto, cfStereo, matrix, gwSourceID21, gwSinkID21, gatewayID21);
+ am_converterID_t converterID1;
+ enterConverterDB("converter1", domainID3, cfAnalog, cfAuto, matrix, gwSourceID3, gwSinkID3, converterID1);
+ am_converterID_t converterID2;
+ enterConverterDB("converter2", domainID3, cfStereo, cfAnalog, matrix, gwSourceID4, gwSinkID4, converterID2);
+ am_converterID_t converterID3;
+ enterConverterDB("converter3", domainID3, cfStereo, cfAnalog, matrix, gwSourceID5, gwSinkID5, converterID3);
+
+ am::am_Source_s source;
+ am::am_Sink_s sink;
+
+ pDatabaseHandler.getSinkInfoDB(sinkID, sink);
+ pDatabaseHandler.getSourceInfoDB(sourceID, source);
+
+ std::vector<am_Route_s> listRoutes;
+
+ getRoute(false, source, sink, listRoutes);
+ ASSERT_EQ(static_cast<uint>(4), listRoutes.size());
+
+ am_Route_s compareRoute1;
+ compareRoute1.sinkID = sinkID;
+ compareRoute1.sourceID = sourceID;
+ compareRoute1.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO});
+ compareRoute1.route.push_back({gwSourceID1, gwSinkID22, domainID2, CF_GENIVI_MONO});
+ compareRoute1.route.push_back({gwSourceID22, gwSinkID3, domainID3, CF_GENIVI_AUTO});
+ compareRoute1.route.push_back({gwSourceID3, gwSinkID4, domainID3, CF_GENIVI_ANALOG});
+ compareRoute1.route.push_back({gwSourceID4, sinkID, domainID3, CF_GENIVI_STEREO});
+
+ am_Route_s compareRoute2;
+ compareRoute2.sinkID = sinkID;
+ compareRoute2.sourceID = sourceID;
+ compareRoute2.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO});
+ compareRoute2.route.push_back({gwSourceID1, gwSinkID22, domainID2, CF_GENIVI_MONO});
+ compareRoute2.route.push_back({gwSourceID22, gwSinkID3, domainID3, CF_GENIVI_AUTO});
+ compareRoute2.route.push_back({gwSourceID3, gwSinkID5, domainID3, CF_GENIVI_ANALOG});
+ compareRoute2.route.push_back({gwSourceID5, sinkID, domainID3, CF_GENIVI_STEREO});
+
+ am_Route_s compareRoute3;
+ compareRoute3.sinkID = sinkID;
+ compareRoute3.sourceID = sourceID;
+ compareRoute3.route.push_back({sourceID, gwSinkID21, domainID1, CF_GENIVI_STEREO});
+ compareRoute3.route.push_back({gwSourceID21, gwSinkID3, domainID3, CF_GENIVI_AUTO});
+ compareRoute3.route.push_back({gwSourceID3, gwSinkID4, domainID3, CF_GENIVI_ANALOG});
+ compareRoute3.route.push_back({gwSourceID4, sinkID, domainID3, CF_GENIVI_STEREO});
+
+ am_Route_s compareRoute4;
+ compareRoute4.sinkID = sinkID;
+ compareRoute4.sourceID = sourceID;
+ compareRoute4.route.push_back({sourceID, gwSinkID21, domainID1, CF_GENIVI_STEREO});
+ compareRoute4.route.push_back({gwSourceID21, gwSinkID3, domainID3, CF_GENIVI_AUTO});
+ compareRoute4.route.push_back({gwSourceID3, gwSinkID5, domainID3, CF_GENIVI_ANALOG});
+ compareRoute4.route.push_back({gwSourceID5, sinkID, domainID3, CF_GENIVI_STEREO});
+
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])||
+ pCF.compareRoute(compareRoute1,listRoutes[1])||
+ pCF.compareRoute(compareRoute1,listRoutes[2])||
+ pCF.compareRoute(compareRoute1,listRoutes[3]));
+
+ ASSERT_TRUE(pCF.compareRoute(compareRoute2,listRoutes[0])||
+ pCF.compareRoute(compareRoute2,listRoutes[1])||
+ pCF.compareRoute(compareRoute2,listRoutes[2])||
+ pCF.compareRoute(compareRoute2,listRoutes[3]));
+
+ ASSERT_TRUE(pCF.compareRoute(compareRoute3,listRoutes[0])||
+ pCF.compareRoute(compareRoute3,listRoutes[1])||
+ pCF.compareRoute(compareRoute3,listRoutes[2])||
+ pCF.compareRoute(compareRoute3,listRoutes[3]));
+
+ ASSERT_TRUE(pCF.compareRoute(compareRoute4,listRoutes[0])||
+ pCF.compareRoute(compareRoute4,listRoutes[1])||
+ pCF.compareRoute(compareRoute4,listRoutes[2])||
+ pCF.compareRoute(compareRoute4,listRoutes[3]));
+}
+
+int main(int argc, char **argv)
+{
+ try
+ {
+ TCLAP::CmdLine* cmd(CAmCommandLineSingleton::instanciateOnce("The team of the AudioManager wishes you a nice day!",' ',DAEMONVERSION,true));
+ cmd->add(enableNoDLTDebug);
+ }
+ catch (TCLAP::ArgException &e) // catch any exceptions
+ { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
+ CAmCommandLineSingleton::instance()->preparse(argc,argv);
+ CAmDltWrapper::instance(enableNoDLTDebug.getValue())->registerApp("routing", "CAmRouterMapTest");
+ logInfo("Routing Test started ");
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h b/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h
new file mode 100644
index 0000000..65ff97b
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h
@@ -0,0 +1,108 @@
+/**
+ * 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, 2014
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef MAPTEST_H_
+#define MAPTEST_H_
+
+#define UNIT_TEST 1
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <set>
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmControlReceiver.h"
+#include "CAmControlSender.h"
+#include "CAmDatabaseObserver.h"
+#include "CAmRoutingSender.h"
+#include "CAmRouter.h"
+#include "CAmSocketHandler.h"
+#include "../IAmControlBackdoor.h"
+#include "../IAmCommandBackdoor.h"
+#include "../CAmCommonFunctions.h"
+#include "../MockIAmControlSend.h"
+#include "../MockIAmCommandSend.h"
+
+
+namespace am
+{
+
+class CAmRouterMapTest: public ::testing::Test
+{
+public:
+ CAmRouterMapTest();
+ ~CAmRouterMapTest();
+ std::vector<std::string> plistRoutingPluginDirs;
+ std::vector<std::string> plistCommandPluginDirs;
+ CAmSocketHandler pSocketHandler;
+ CAmControlSender pControlSender;
+ CAmDatabaseHandlerMap pDatabaseHandler;
+ CAmRouter pRouter;
+ CAmRoutingSender pRoutingSender;
+ CAmCommandSender pCommandSender;
+ MockIAmCommandSend pMockInterface;
+ MockIAmControlSend pMockControlInterface;
+ IAmRoutingBackdoor pRoutingInterfaceBackdoor;
+ IAmCommandBackdoor pCommandInterfaceBackdoor;
+ IAmControlBackdoor pControlInterfaceBackdoor;
+ CAmControlReceiver pControlReceiver;
+ CAmDatabaseObserver pObserver;
+ CAmCommonFunctions pCF;
+ void SetUp();
+ void TearDown();
+
+ void createMainConnectionSetup();
+
+ void enterDomainDB(const std::string & domainName, am_domainID_t & domainID);
+ void enterSourceDB(const std::string & sourceName, const am_domainID_t domainID, const std::vector<am_CustomConnectionFormat_t> & connectionFormats, am_sourceID_t & sourceID);
+ void enterSinkDB(const std::string & sinkName, const am_domainID_t domainID, const std::vector<am_CustomConnectionFormat_t> & connectionFormats, am_sinkID_t & sinkID);
+ void enterGatewayDB(const std::string & gwName,
+ const am_domainID_t domainSourceID,
+ const am_domainID_t domainSinkID,
+ const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats,
+ const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats,
+ const std::vector<bool> & matrix,
+ const am_sourceID_t & sourceID,
+ const am_sinkID_t & sinkID,
+ am_gatewayID_t & gatewayID);
+ void enterConverterDB(const std::string & gwName,
+ const am_domainID_t domainID,
+ const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats,
+ const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats,
+ const std::vector<bool> & matrix,
+ const am_sourceID_t & sourceID,
+ const am_sinkID_t & sinkID,
+ am_converterID_t & converterID);
+ void getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
+ void getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes);
+ void getAllPaths(CAmRoutingNode & aSource,
+ CAmRoutingNode & aSink,
+ std::vector<am_Route_s> & resultPath,
+ std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath,
+ const bool includeCycles);
+};
+
+}
+
+#endif /* MAPTEST_H_ */
diff --git a/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt
new file mode 100644
index 0000000..17689d9
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt
@@ -0,0 +1,47 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project (AmRouterMapTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+file(GLOB ROUTINGMAP_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+ )
+
+ADD_EXECUTABLE( AmRouterMapTest ${ROUTINGMAP_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmRouterMapTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmRouterMapTest AudioManagerCore)
+
+INSTALL(TARGETS AmRouterMapTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt~ b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt~
new file mode 100644
index 0000000..ec79082
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt~
@@ -0,0 +1,47 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project (AmRouterMapTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIR}
+ ${GTEST_INCLUDE_DIRS})
+
+file(GLOB ROUTINGMAP_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+ )
+
+ADD_EXECUTABLE( AmRouterMapTest ${ROUTINGMAP_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmRouterMapTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmRouterMapTest AudioManagerCore)
+
+INSTALL(TARGETS AmRouterMapTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmRouterTest/CAmRouterTest.cpp b/AudioManagerCore/test/AmRouterTest/CAmRouterTest.cpp
new file mode 100644
index 0000000..a64979e
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterTest/CAmRouterTest.cpp
@@ -0,0 +1,1967 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmRouterTest.h"
+#include <string.h>
+#include "CAmDltWrapper.h"
+#include "CAmCommandLineSingleton.h"
+
+using namespace am;
+using namespace testing;
+
+TCLAP::SwitchArg enableNoDLTDebug ("V","logDlt","print DLT logs to stdout or dlt-daemon default off",false);
+
+CAmRouterTest::CAmRouterTest() :
+ plistRoutingPluginDirs(), //
+ plistCommandPluginDirs(), //
+ pSocketHandler(), //
+ pControlSender(), //
+ pDatabaseHandler(),
+ pRouter(&pDatabaseHandler, &pControlSender), //
+ pRoutingSender(plistRoutingPluginDirs), //
+ pCommandSender(plistCommandPluginDirs), //
+ pMockInterface(), //
+ pMockControlInterface(), //
+ pRoutingInterfaceBackdoor(), //
+ pCommandInterfaceBackdoor(), //
+ pControlInterfaceBackdoor(), //
+ pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender,&pSocketHandler, &pRouter), //
+ pObserver(&pCommandSender, &pRoutingSender, &pSocketHandler)
+{
+ pDatabaseHandler.registerObserver(&pObserver);
+ pCommandInterfaceBackdoor.injectInterface(&pCommandSender, &pMockInterface);
+ pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface);
+}
+
+CAmRouterTest::~CAmRouterTest()
+{
+
+}
+
+void CAmRouterTest::SetUp()
+{
+ logInfo("Routing Test started ");
+}
+
+void CAmRouterTest::TearDown()
+{
+}
+
+ACTION(returnConnectionFormat){
+arg4=arg3;
+}
+
+//test that checks just sinks and source in a domain but connectionformats do not match
+TEST_F(CAmRouterTest,simpleRoute2withDomainNoMatchFormats)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1;
+ am_domainID_t domainID1;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+
+ am_Source_s source;
+ am_sourceID_t sourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ source.sourceID=sourceID;
+
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+
+ sink.domainID = domainID1;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ sink.sinkID=sinkID;
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+
+ hopp1.sinkID = sinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(true,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+
+}
+
+//test that checks just sinks and source in a domain
+TEST_F(CAmRouterTest,simpleRoute2withDomain)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1;
+ am_domainID_t domainID1;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+
+ am_Source_s source;
+ am_sourceID_t sourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+
+ sink.domainID = domainID1;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+
+ hopp1.sinkID = sinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(true,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+
+}
+
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(CAmRouterTest,simpleRoute2DomainsOnlyFree)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ std::vector<am_Connection_s> listConnections;
+ pDatabaseHandler.getListConnections(listConnections);
+ ASSERT_EQ(0, listConnections.size());
+ ASSERT_EQ(E_OK, pRouter.getRoute(true,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+
+}
+
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(CAmRouterTest,simpleRoute2DomainsOnlyFreeNotFree)
+{
+
+
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ am_Connection_s connection,connection1;
+ am_connectionID_t id1,id2;
+ connection.sourceID=sourceID;
+ connection.sinkID=gwSinkID;
+ connection.connectionFormat=CF_GENIVI_ANALOG;
+ connection.connectionID=0;
+ connection1.sourceID=gwSourceID;
+ connection1.sinkID=sinkID;
+ connection1.connectionFormat=CF_GENIVI_ANALOG;
+ connection1.connectionID=0;
+
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConnectionDB(connection,id1));
+ ASSERT_EQ(E_OK,pDatabaseHandler.enterConnectionDB(connection1,id2));
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(true,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks just 2 domains, with gateway for each direction (possible circular route)
+TEST_F(CAmRouterTest,simpleRoute2DomainsCircularGWOnlyFree)
+{
+
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource, gwSource2;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID2;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource2.domainID = domainID1;
+ gwSource2.name = "gwsource2";
+ gwSource2.sourceState = SS_ON;
+ gwSource2.sourceID = 0;
+ gwSource2.sourceClassID = 5;
+ gwSource2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource2,gwSourceID2));
+
+ am_Sink_s sink, gwSink, gwSink2;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID2;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSink2.domainID = domainID2;
+ gwSink2.name = "gwSink2";
+ gwSink2.sinkID = 0;
+ gwSink2.sinkClassID = 5;
+ gwSink2.muteState = MS_MUTED;
+ gwSink2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink2,gwSinkID2));
+
+ am_Gateway_s gateway, gateway2;
+ am_gatewayID_t gatewayID, gatewayID2;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway2.controlDomainID = domainID1;
+ gateway2.gatewayID = 0;
+ gateway2.sinkID = gwSinkID2;
+ gateway2.sourceID = gwSourceID2;
+ gateway2.domainSourceID = domainID1;
+ gateway2.domainSinkID = domainID2;
+ gateway2.listSinkFormats = gwSink2.listConnectionFormats;
+ gateway2.listSourceFormats = gwSource2.listConnectionFormats;
+ gateway2.convertionMatrix.push_back(true);
+ gateway2.name = "gateway2";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(true,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 3 domains, one sink one source, longer lists of connectionformats.
+TEST_F(CAmRouterTest,simpleRoute3DomainsListConnectionFormats_2)
+{
+
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(true);
+ gateway.convertionMatrix.push_back(true);
+ gateway.convertionMatrix.push_back(false);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(false);
+ gateway1.convertionMatrix.push_back(false);
+ gateway1.convertionMatrix.push_back(false);
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway1";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[1];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[1];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 3 domains, one sink one source, longer lists of connectionformats.
+TEST_F(CAmRouterTest,simpleRoute3DomainsListConnectionFormats_1)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(true);
+ gateway.convertionMatrix.push_back(false);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+
+//test that checks 3 domains, one sink one source, longer lists of connectionformats.
+TEST_F(CAmRouterTest,simpleRoute3DomainsListConnectionFormats)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(false);
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[1];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+
+//test that checks 4 domains, one sink and one source but there are 2 routes because there are 2 gateways
+TEST_F(CAmRouterTest,simpleRoute4Domains2Routes)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3, domain4;
+ am_domainID_t domainID1, domainID2, domainID3, domainID4;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+ domain4.domainID = 0;
+ domain4.name = "domain4";
+ domain4.busname = "domain4bus";
+ domain4.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain4,domainID4));
+
+ am_Source_s source, gwSource, gwSource1, gwSource2, gwSource3;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1, gwSourceID2, gwSourceID3;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource2.domainID = domainID4;
+ gwSource2.name = "gwsource3";
+ gwSource2.sourceState = SS_OFF;
+ gwSource2.sourceID = 0;
+ gwSource2.sourceClassID = 5;
+ gwSource2.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ gwSource3.domainID = domainID3;
+ gwSource3.name = "gwsource4";
+ gwSource3.sourceState = SS_OFF;
+ gwSource3.sourceID = 0;
+ gwSource3.sourceClassID = 5;
+ gwSource3.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource2,gwSourceID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource3,gwSourceID3));
+
+ am_Sink_s sink, gwSink, gwSink1, gwSink2, gwSink3;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1, gwSinkID2, gwSinkID3;
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSink2.domainID = domainID3;
+ gwSink2.name = "gwSink2";
+ gwSink2.sinkID = 0;
+ gwSink2.sinkClassID = 5;
+ gwSink2.muteState = MS_MUTED;
+ gwSink2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink3.domainID = domainID2;
+ gwSink3.name = "gwSink3";
+ gwSink3.sinkID = 0;
+ gwSink3.sinkClassID = 5;
+ gwSink3.muteState = MS_MUTED;
+ gwSink3.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ sink.domainID = domainID4;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink2,gwSinkID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink3,gwSinkID3));
+
+ am_Gateway_s gateway, gateway1, gateway2, gateway3;
+ am_gatewayID_t gatewayID, gatewayID1, gatewayID2, gatewayID3;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway1";
+
+ gateway2.controlDomainID = domainID3;
+ gateway2.gatewayID = 0;
+ gateway2.sinkID = gwSinkID2;
+ gateway2.sourceID = gwSourceID2;
+ gateway2.domainSourceID = domainID4;
+ gateway2.domainSinkID = domainID3;
+ gateway2.listSinkFormats = gwSink2.listConnectionFormats;
+ gateway2.listSourceFormats = gwSource2.listConnectionFormats;
+ gateway2.convertionMatrix.push_back(true);
+ gateway2.name = "gateway2";
+
+ gateway3.controlDomainID = domainID2;
+ gateway3.gatewayID = 0;
+ gateway3.sinkID = gwSinkID3;
+ gateway3.sourceID = gwSourceID3;
+ gateway3.domainSourceID = domainID3;
+ gateway3.domainSinkID = domainID2;
+ gateway3.listSinkFormats = gwSink3.listConnectionFormats;
+ gateway3.listSourceFormats = gwSource3.listConnectionFormats;
+ gateway3.convertionMatrix.push_back(true);
+ gateway3.name = "gateway3";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway3,gatewayID3));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements, listRoutingElements1;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+ am_RoutingElement_s hopp4;
+ am_RoutingElement_s hopp2alt;
+ am_RoutingElement_s hopp3alt;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = gwSinkID2;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = gwSink2.listConnectionFormats[0];
+
+ hopp4.sourceID = gwSourceID2;
+ hopp4.sinkID = sinkID;
+ hopp4.domainID = domainID4;
+ hopp4.connectionFormat = sink.listConnectionFormats[0];
+
+ hopp2alt.sourceID = gwSourceID;
+ hopp2alt.sinkID = gwSinkID3;
+ hopp2alt.domainID = domainID2;
+ hopp2alt.connectionFormat = gwSink3.listConnectionFormats[0];
+
+ hopp3alt.sourceID = gwSourceID3;
+ hopp3alt.sinkID = gwSinkID2;
+ hopp3alt.domainID = domainID3;
+ hopp3alt.connectionFormat = gwSink2.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+ listRoutingElements.push_back(hopp4);
+ listRoutingElements1.push_back(hopp1);
+ listRoutingElements1.push_back(hopp2alt);
+ listRoutingElements1.push_back(hopp3alt);
+ listRoutingElements1.push_back(hopp4);
+
+ am_Route_s compareRoute, compareRoute1;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ compareRoute1.route = listRoutingElements1;
+ compareRoute1.sinkID = sinkID;
+ compareRoute1.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(2), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]) || pCF.compareRoute(compareRoute,listRoutes[1]) );
+ ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[1]) || pCF.compareRoute(compareRoute1,listRoutes[0]) );
+}
+
+//test that checks 3 domains, one sink one source but the connectionformat of third domains do not fit.
+TEST_F(CAmRouterTest,simpleRoute3DomainsNoConnection)
+{
+
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+}
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(CAmRouterTest,simpleRoute2Domains)
+{
+
+
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+
+}
+
+//test that checks just 2 domains, one sink one source but the connectionformat of source
+TEST_F(CAmRouterTest,simpleRoute2DomainsNoMatchConnectionFormats)
+{
+
+
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2;
+ am_domainID_t domainID1, domainID2;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+ am_Source_s source, gwSource;
+ am_sourceID_t sourceID, gwSourceID;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+ am_Sink_s sink, gwSink;
+ am_sinkID_t sinkID, gwSinkID;
+
+ sink.domainID = domainID2;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+ am_Gateway_s gateway;
+ am_gatewayID_t gatewayID;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+
+ hopp1.sinkID = gwSinkID;
+ hopp1.sourceID = sourceID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sinkID = sinkID;
+ hopp2.sourceID = gwSourceID;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(0), listRoutes.size());
+}
+
+//test that checks 3 domains, one sink one source.
+TEST_F(CAmRouterTest,simpleRoute3Domains)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3;
+ am_domainID_t domainID1, domainID2, domainID3;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+ am_Source_s source, gwSource, gwSource1;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+ am_Sink_s sink, gwSink, gwSink1;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+ sink.domainID = domainID3;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+ am_Gateway_s gateway, gateway1;
+ am_gatewayID_t gatewayID, gatewayID1;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = sinkID;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ ASSERT_EQ(static_cast<uint>(1), listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 4 domains, one sink and one source.
+TEST_F(CAmRouterTest,simpleRoute4Domains)
+{
+ EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK)));
+
+ //initialize 2 domains
+ am_Domain_s domain1, domain2, domain3, domain4;
+ am_domainID_t domainID1, domainID2, domainID3, domainID4;
+
+ domain1.domainID = 0;
+ domain1.name = "domain1";
+ domain1.busname = "domain1bus";
+ domain1.state = DS_CONTROLLED;
+ domain2.domainID = 0;
+ domain2.name = "domain2";
+ domain2.busname = "domain2bus";
+ domain2.state = DS_CONTROLLED;
+ domain3.domainID = 0;
+ domain3.name = "domain3";
+ domain3.busname = "domain3bus";
+ domain3.state = DS_CONTROLLED;
+ domain4.domainID = 0;
+ domain4.name = "domain4";
+ domain4.busname = "domain4bus";
+ domain4.state = DS_CONTROLLED;
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain4,domainID4));
+
+ am_Source_s source, gwSource, gwSource1, gwSource2;
+ am_sourceID_t sourceID, gwSourceID, gwSourceID1, gwSourceID2;
+
+ source.domainID = domainID1;
+ source.name = "source1";
+ source.sourceState = SS_ON;
+ source.sourceID = 0;
+ source.sourceClassID = 5;
+ source.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource.domainID = domainID2;
+ gwSource.name = "gwsource1";
+ gwSource.sourceState = SS_ON;
+ gwSource.sourceID = 0;
+ gwSource.sourceClassID = 5;
+ gwSource.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSource1.domainID = domainID3;
+ gwSource1.name = "gwsource2";
+ gwSource1.sourceState = SS_ON;
+ gwSource1.sourceID = 0;
+ gwSource1.sourceClassID = 5;
+ gwSource1.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSource2.domainID = domainID4;
+ gwSource2.name = "gwsource3";
+ gwSource2.sourceState = SS_OFF;
+ gwSource2.sourceID = 0;
+ gwSource2.sourceClassID = 5;
+ gwSource2.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource2,gwSourceID2));
+
+ am_Sink_s sink, gwSink, gwSink1, gwSink2;
+ am_sinkID_t sinkID, gwSinkID, gwSinkID1, gwSinkID2;
+
+ gwSink.domainID = domainID1;
+ gwSink.name = "gwSink";
+ gwSink.sinkID = 0;
+ gwSink.sinkClassID = 5;
+ gwSink.muteState = MS_MUTED;
+ gwSink.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ gwSink1.domainID = domainID2;
+ gwSink1.name = "gwSink1";
+ gwSink1.sinkID = 0;
+ gwSink1.sinkClassID = 5;
+ gwSink1.muteState = MS_MUTED;
+ gwSink1.listConnectionFormats.push_back(CF_GENIVI_ANALOG);
+
+ gwSink2.domainID = domainID3;
+ gwSink2.name = "gwSink2";
+ gwSink2.sinkID = 0;
+ gwSink2.sinkClassID = 5;
+ gwSink2.muteState = MS_MUTED;
+ gwSink2.listConnectionFormats.push_back(CF_GENIVI_MONO);
+
+ sink.domainID = domainID4;
+ sink.name = "sink1";
+ sink.sinkID = 0;
+ sink.sinkClassID = 5;
+ sink.muteState = MS_MUTED;
+ sink.listConnectionFormats.push_back(CF_GENIVI_STEREO);
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink2,gwSinkID2));
+
+ am_Gateway_s gateway, gateway1, gateway2;
+ am_gatewayID_t gatewayID, gatewayID1, gatewayID2;
+
+ gateway.controlDomainID = domainID1;
+ gateway.gatewayID = 0;
+ gateway.sinkID = gwSinkID;
+ gateway.sourceID = gwSourceID;
+ gateway.domainSourceID = domainID2;
+ gateway.domainSinkID = domainID1;
+ gateway.listSinkFormats = gwSink.listConnectionFormats;
+ gateway.listSourceFormats = gwSource.listConnectionFormats;
+ gateway.convertionMatrix.push_back(true);
+ gateway.name = "gateway";
+
+ gateway1.controlDomainID = domainID2;
+ gateway1.gatewayID = 0;
+ gateway1.sinkID = gwSinkID1;
+ gateway1.sourceID = gwSourceID1;
+ gateway1.domainSourceID = domainID3;
+ gateway1.domainSinkID = domainID2;
+ gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+ gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+ gateway1.convertionMatrix.push_back(true);
+ gateway1.name = "gateway1";
+
+ gateway2.controlDomainID = domainID3;
+ gateway2.gatewayID = 0;
+ gateway2.sinkID = gwSinkID2;
+ gateway2.sourceID = gwSourceID2;
+ gateway2.domainSourceID = domainID4;
+ gateway2.domainSinkID = domainID3;
+ gateway2.listSinkFormats = gwSink2.listConnectionFormats;
+ gateway2.listSourceFormats = gwSource2.listConnectionFormats;
+ gateway2.convertionMatrix.push_back(true);
+ gateway2.name = "gateway2";
+
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway2,gatewayID2));
+
+ std::vector<am_Route_s> listRoutes;
+ std::vector<am_RoutingElement_s> listRoutingElements;
+ am_RoutingElement_s hopp1;
+ am_RoutingElement_s hopp2;
+ am_RoutingElement_s hopp3;
+ am_RoutingElement_s hopp4;
+
+ hopp1.sourceID = sourceID;
+ hopp1.sinkID = gwSinkID;
+ hopp1.domainID = domainID1;
+ hopp1.connectionFormat = source.listConnectionFormats[0];
+
+ hopp2.sourceID = gwSourceID;
+ hopp2.sinkID = gwSinkID1;
+ hopp2.domainID = domainID2;
+ hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+ hopp3.sourceID = gwSourceID1;
+ hopp3.sinkID = gwSinkID2;
+ hopp3.domainID = domainID3;
+ hopp3.connectionFormat = gwSink2.listConnectionFormats[0];
+
+ hopp4.sourceID = gwSourceID2;
+ hopp4.sinkID = sinkID;
+ hopp4.domainID = domainID4;
+ hopp4.connectionFormat = sink.listConnectionFormats[0];
+
+ listRoutingElements.push_back(hopp1);
+ listRoutingElements.push_back(hopp2);
+ listRoutingElements.push_back(hopp3);
+ listRoutingElements.push_back(hopp4);
+
+ am_Route_s compareRoute;
+ compareRoute.route = listRoutingElements;
+ compareRoute.sinkID = sinkID;
+ compareRoute.sourceID = sourceID;
+
+ ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+ size_t size(1);
+ ASSERT_EQ(size, listRoutes.size());
+ ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+int main(int argc, char **argv)
+{
+ try
+ {
+ TCLAP::CmdLine* cmd(CAmCommandLineSingleton::instanciateOnce("The team of the AudioManager wishes you a nice day!",' ',DAEMONVERSION,true));
+ cmd->add(enableNoDLTDebug);
+ }
+ catch (TCLAP::ArgException &e) // catch any exceptions
+ { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
+ CAmCommandLineSingleton::instance()->preparse(argc,argv);
+ CAmDltWrapper::instance(enableNoDLTDebug.getValue())->registerApp("routing", "CAmRouterTest");
+ logInfo("Routing Test started ");
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/AudioManagerCore/test/AmRouterTest/CAmRouterTest.h b/AudioManagerCore/test/AmRouterTest/CAmRouterTest.h
new file mode 100644
index 0000000..4a4e35b
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterTest/CAmRouterTest.h
@@ -0,0 +1,81 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef DATABASETEST_H_
+#define DATABASETEST_H_
+
+#define UNIT_TEST 1
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <set>
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmControlReceiver.h"
+#include "CAmControlSender.h"
+#include "CAmDatabaseObserver.h"
+#include "CAmRoutingSender.h"
+#include "CAmRouter.h"
+#include "CAmSocketHandler.h"
+#include "../IAmControlBackdoor.h"
+#include "../IAmCommandBackdoor.h"
+#include "../CAmCommonFunctions.h"
+#include "../MockIAmControlSend.h"
+#include "../MockIAmCommandSend.h"
+
+
+namespace am
+{
+
+class CAmRouterTest: public ::testing::Test
+{
+public:
+ CAmRouterTest();
+ ~CAmRouterTest();
+ std::vector<std::string> plistRoutingPluginDirs;
+ std::vector<std::string> plistCommandPluginDirs;
+ CAmSocketHandler pSocketHandler;
+ CAmControlSender pControlSender;
+ CAmDatabaseHandlerMap pDatabaseHandler;
+ CAmRouter pRouter;
+ CAmRoutingSender pRoutingSender;
+ CAmCommandSender pCommandSender;
+ MockIAmCommandSend pMockInterface;
+ MockIAmControlSend pMockControlInterface;
+ IAmRoutingBackdoor pRoutingInterfaceBackdoor;
+ IAmCommandBackdoor pCommandInterfaceBackdoor;
+ IAmControlBackdoor pControlInterfaceBackdoor;
+ CAmControlReceiver pControlReceiver;
+ CAmDatabaseObserver pObserver;
+ CAmCommonFunctions pCF;
+ void SetUp();
+ void TearDown();
+
+ void createMainConnectionSetup();
+};
+
+}
+
+#endif /* DATABASETEST_H_ */
diff --git a/AudioManagerCore/test/AmRouterTest/CMakeLists.txt b/AudioManagerCore/test/AmRouterTest/CMakeLists.txt
new file mode 100644
index 0000000..db05911
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterTest/CMakeLists.txt
@@ -0,0 +1,48 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmRouterTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+
+file(GLOB ROUTING_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+ )
+
+ADD_EXECUTABLE( AmRouterTest ${ROUTING_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmRouterTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmRouterTest AudioManagerCore)
+
+INSTALL(TARGETS AmRouterTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmRouterTest/CMakeLists.txt~ b/AudioManagerCore/test/AmRouterTest/CMakeLists.txt~
new file mode 100644
index 0000000..32e1206
--- /dev/null
+++ b/AudioManagerCore/test/AmRouterTest/CMakeLists.txt~
@@ -0,0 +1,47 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmRouterTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIR})
+
+
+file(GLOB ROUTING_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+ )
+
+ADD_EXECUTABLE( AmRouterTest ${ROUTING_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmRouterTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmRouterTest AudioManagerCore)
+
+INSTALL(TARGETS AmRouterTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp b/AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp
new file mode 100644
index 0000000..5978b6d
--- /dev/null
+++ b/AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp
@@ -0,0 +1,383 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmRoutingInterfaceTest.h"
+#include "CAmDltWrapper.h"
+#include "CAmCommandLineSingleton.h"
+
+using namespace am;
+using namespace testing;
+
+TCLAP::SwitchArg enableNoDLTDebug ("V","logDlt","print DLT logs to stdout or dlt-daemon default off",false);
+
+CAmRoutingInterfaceTest::CAmRoutingInterfaceTest() :
+ plistRoutingPluginDirs(), //
+ plistCommandPluginDirs(), //
+ pSocketHandler(), //
+ pDatabaseHandler(), //
+ pRoutingSender(plistRoutingPluginDirs), //
+ pCommandSender(plistCommandPluginDirs), //
+ pControlSender(), //
+ pRouter(&pDatabaseHandler, &pControlSender), //
+ pMockInterface(), //
+ pRoutingInterfaceBackdoor(), //
+ pCommandInterfaceBackdoor(), //
+ pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender, &pSocketHandler, &pRouter), //
+ pObserver(&pCommandSender, &pRoutingSender, &pSocketHandler)
+{
+ pDatabaseHandler.registerObserver(&pObserver);
+ pRoutingInterfaceBackdoor.unloadPlugins(&pRoutingSender);
+ pRoutingInterfaceBackdoor.injectInterface(&pRoutingSender, &pMockInterface, "mock");
+ pCommandInterfaceBackdoor.unloadPlugins(&pCommandSender);
+}
+
+CAmRoutingInterfaceTest::~CAmRoutingInterfaceTest()
+{
+}
+
+void CAmRoutingInterfaceTest::SetUp()
+{
+ logInfo("RoutingSendInterface Test started ");
+
+}
+
+void CAmRoutingInterfaceTest::TearDown()
+{
+}
+
+TEST_F(CAmRoutingInterfaceTest,abort)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_connectionID_t connectionID;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+
+ //prepare the stage
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+
+ //start a connect, expect a call on the routingInterface
+ EXPECT_CALL(pMockInterface,asyncConnect(_,_,1,sinkID,CF_GENIVI_ANALOG)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_ANALOG,1,2));
+
+ //check the correctness of the handle
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_CONNECT);
+
+ //the handle must be inside the handlelist
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[0].handle==handle.handle);
+ ASSERT_TRUE(listHandles[0].handleType==handle.handleType);
+
+ //send an abort expect a call on the routing interface
+ EXPECT_CALL(pMockInterface,asyncAbort(_)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.abortAction(handle));
+
+ //the reaction on the abort is specific for every function
+
+ //now we try to abort a handle that does not exist
+ handle.handle = 24;
+ ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.abortAction(handle));
+}
+
+TEST_F(CAmRoutingInterfaceTest,abortNonExistent)
+{
+ EXPECT_CALL(pMockInterface,asyncAbort(_)).Times(0);
+ am_Handle_s handle;
+ ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.abortAction(handle));
+}
+
+TEST_F(CAmRoutingInterfaceTest,alreadyConnected)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(pMockInterface,asyncConnect(_,_,1,sinkID,CF_GENIVI_ANALOG)).WillOnce(Return(E_OK));
+ am_Handle_s handle;
+ am_connectionID_t connectionID;
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_ANALOG,1,2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+ //ASSERT_EQ(E_ALREADY_EXISTS, pControlReceiver.connect(handle,connectionID,CF_GENIVI_ANALOG,1,2));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_CONNECT);
+}
+
+TEST_F(CAmRoutingInterfaceTest,setSinkSoundPropertyNoChange)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_SoundProperty_s soundProperty;
+ soundProperty.type = SP_GENIVI_TREBLE;
+ soundProperty.value = 23;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ sink.listSoundProperties.push_back(soundProperty);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(pMockInterface,asyncSetSinkSoundProperty(_,sinkID,_)).Times(1).WillOnce(Return(E_NO_CHANGE));
+ ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkSoundProperty(handle,sinkID,soundProperty));
+}
+
+TEST_F(CAmRoutingInterfaceTest,setSourceState)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ handle.handle = 0;
+ am_SourceState_e state = SS_PAUSED;
+ pCF.createSource(source);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(pMockInterface,asyncSetSourceState(_,sourceID,state)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSourceState(handle,sourceID,state));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_SETSOURCESTATE);
+}
+
+TEST_F(CAmRoutingInterfaceTest,setSourceSoundProperty)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_SoundProperty_s soundProperty;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSource(source);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ source.sourceID = 2;
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(pMockInterface,asyncSetSourceSoundProperty(_,sourceID,_)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSourceSoundProperty(handle,sourceID,soundProperty));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_SETSOURCESOUNDPROPERTY);
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[0].handle==handle.handle);
+ ASSERT_TRUE(listHandles[0].handleType==handle.handleType);
+}
+
+TEST_F(CAmRoutingInterfaceTest,setSinkSoundProperty)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_SoundProperty_s soundProperty;
+ soundProperty.value=5;
+ soundProperty.type=SP_GENIVI_MID;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ sink.listSoundProperties.push_back(soundProperty);
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(pMockInterface,asyncSetSinkSoundProperty(_,sinkID,_)).WillOnce(Return(E_OK));
+ soundProperty.value=10;
+ ASSERT_EQ(E_OK, pControlReceiver.setSinkSoundProperty(handle,sinkID,soundProperty));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_SETSINKSOUNDPROPERTY);
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[0].handle==handle.handle);
+ ASSERT_TRUE(listHandles[0].handleType==handle.handleType);
+}
+
+
+
+TEST_F(CAmRoutingInterfaceTest,setSourceVolume)
+{
+ am_Source_s source;
+ am_sourceID_t sourceID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_volume_t volume = 34;
+ am_CustomRampType_t rampType = RAMP_GENIVI_DIRECT;
+ am_time_t rampTime = 300;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSource(source);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ source.sourceID = 2;
+ source.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+ EXPECT_CALL(pMockInterface,asyncSetSourceVolume(_,2,volume,rampType,rampTime)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSourceVolume(handle,2,volume,rampType,rampTime));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_SETSOURCEVOLUME);
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[0].handle==handle.handle);
+ ASSERT_TRUE(listHandles[0].handleType==handle.handleType);
+}
+
+TEST_F(CAmRoutingInterfaceTest,setSinkVolume)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_volume_t volume = 34;
+ am_CustomRampType_t rampType = RAMP_GENIVI_DIRECT;
+ am_time_t rampTime = 300;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(pMockInterface,asyncSetSinkVolume(_,2,volume,rampType,rampTime)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.setSinkVolume(handle,2,volume,rampType,rampTime));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_SETSINKVOLUME);
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[0].handle==handle.handle);
+ ASSERT_TRUE(listHandles[0].handleType==handle.handleType);
+}
+
+TEST_F(CAmRoutingInterfaceTest,connect)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_connectionID_t connectionID;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(pMockInterface,asyncConnect(_,_,1,sinkID,CF_GENIVI_ANALOG)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_ANALOG,1,2));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_CONNECT);
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[0].handle==handle.handle);
+ ASSERT_TRUE(listHandles[0].handleType==handle.handleType);
+}
+
+TEST_F(CAmRoutingInterfaceTest,disconnect)
+{
+ am_Sink_s sink;
+ am_sinkID_t sinkID;
+ am_Domain_s domain;
+ am_domainID_t domainID;
+ am_Handle_s handle;
+ am_connectionID_t connectionID;
+ std::vector<am_Handle_s> listHandles;
+ pCF.createSink(sink);
+ pCF.createDomain(domain);
+ domain.name = "mock";
+ domain.busname = "mock";
+ sink.sinkID = 2;
+ sink.domainID = DYNAMIC_ID_BOUNDARY;
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
+ ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+ EXPECT_CALL(pMockInterface,asyncConnect(_,_,1,sinkID,CF_GENIVI_ANALOG)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_ANALOG,1,2));
+ ASSERT_EQ(E_OK, pDatabaseHandler.changeConnectionFinal(connectionID));
+ EXPECT_CALL(pMockInterface,asyncDisconnect(_,connectionID)).WillOnce(Return(E_OK));
+ ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,connectionID));
+ ASSERT_NE(handle.handle, 0);
+ ASSERT_EQ(handle.handleType, H_DISCONNECT);
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles[1].handle==handle.handle);
+ ASSERT_TRUE(listHandles[1].handleType==handle.handleType);
+}
+
+
+TEST_F(CAmRoutingInterfaceTest,nothingTodisconnect)
+{
+ am_Handle_s handle;
+ am_connectionID_t connectionID = 4;
+ std::vector<am_Handle_s> listHandles;
+ ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.disconnect(handle,connectionID));
+ ASSERT_EQ(E_OK, pControlReceiver.getListHandles(listHandles));
+ ASSERT_TRUE(listHandles.empty());
+}
+
+
+int main(int argc, char **argv)
+{
+ try
+ {
+ TCLAP::CmdLine* cmd(CAmCommandLineSingleton::instanciateOnce("The team of the AudioManager wishes you a nice day!",' ',DAEMONVERSION,true));
+ cmd->add(enableNoDLTDebug);
+ }
+ catch (TCLAP::ArgException &e) // catch any exceptions
+ { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
+ CAmCommandLineSingleton::instance()->preparse(argc,argv);
+ CAmDltWrapper::instance(enableNoDLTDebug.getValue())->registerApp("routing", "CAmRouterTest");
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.h b/AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.h
new file mode 100644
index 0000000..75a7511
--- /dev/null
+++ b/AudioManagerCore/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.h
@@ -0,0 +1,71 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef ROUTINGINTERFACETEST_H_
+#define ROUTINGINTERFACETEST_H_
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <set>
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmControlReceiver.h"
+#include "CAmControlSender.h"
+#include "CAmDatabaseObserver.h"
+#include "CAmRouter.h"
+#include "../IAmRoutingBackdoor.h"
+#include "../IAmCommandBackdoor.h"
+#include "../CAmCommonFunctions.h"
+#include "../MockIAmRoutingSend.h"
+#include "CAmSocketHandler.h"
+
+namespace am
+{
+
+class CAmRoutingInterfaceTest: public ::testing::Test
+{
+public:
+ CAmRoutingInterfaceTest();
+ ~CAmRoutingInterfaceTest();
+ std::vector<std::string> plistRoutingPluginDirs;
+ std::vector<std::string> plistCommandPluginDirs;
+ CAmSocketHandler pSocketHandler;
+ CAmDatabaseHandlerMap pDatabaseHandler;
+ CAmRoutingSender pRoutingSender;
+ CAmCommandSender pCommandSender;
+ CAmControlSender pControlSender;
+ CAmRouter pRouter;
+ MockIAmRoutingSend pMockInterface;
+ IAmRoutingBackdoor pRoutingInterfaceBackdoor;
+ IAmCommandBackdoor pCommandInterfaceBackdoor;
+ CAmControlReceiver pControlReceiver;
+ CAmDatabaseObserver pObserver;
+ CAmCommonFunctions pCF;
+ void SetUp();
+ void TearDown();
+};
+
+}
+
+#endif /* ROUTINGINTERFACETEST_H_ */
diff --git a/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt
new file mode 100644
index 0000000..dc5115d
--- /dev/null
+++ b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt
@@ -0,0 +1,49 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project (AmRoutingInterfaceTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNIT_TEST=1 -DDLT_CONTEXT=AudioManager")
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+file(GLOB ROUTING_INTERFACE_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+)
+
+ADD_EXECUTABLE(AmRoutingInterfaceTest ${ROUTING_INTERFACE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmRoutingInterfaceTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmRoutingInterfaceTest AudioManagerCore)
+
+INSTALL(TARGETS AmRoutingInterfaceTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt~ b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt~
new file mode 100644
index 0000000..e8fbb29
--- /dev/null
+++ b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt~
@@ -0,0 +1,48 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project (AmRoutingInterfaceTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNIT_TEST=1 -DDLT_CONTEXT=AudioManager")
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIR})
+
+file(GLOB ROUTING_INTERFACE_SRCS_CXX
+ "../CAmCommonFunctions.cpp"
+ "*.cpp"
+)
+
+ADD_EXECUTABLE(AmRoutingInterfaceTest ${ROUTING_INTERFACE_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmRoutingInterfaceTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmRoutingInterfaceTest AudioManagerCore)
+
+INSTALL(TARGETS AmRoutingInterfaceTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
diff --git a/AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.cpp b/AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.cpp
new file mode 100644
index 0000000..d3f7a11
--- /dev/null
+++ b/AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.cpp
@@ -0,0 +1,209 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string>
+
+#include "CAmTelnetServerTest.h"
+#include "CAmCommandReceiver.h"
+#include "CAmRoutingReceiver.h"
+#include "CAmControlReceiver.h"
+#include "audiomanagerconfig.h"
+
+
+using namespace testing;
+using namespace am;
+using namespace std;
+
+
+static std::string controllerPlugin = std::string(CONTROLLER_PLUGIN_DIR);
+static unsigned short servPort = 6060;
+static int staticSocket = -1;
+static CAmSocketHandler* mpSocketHandler = NULL;
+
+void* startSocketHandler(void* data)
+{
+ CAmEnvironment* Env = static_cast<CAmEnvironment*>(data);
+ Env->setSocketHandler(&Env->mSocketHandler);
+ Env->mSocketHandler.start_listenting();
+ Env->setSocketHandler(NULL);
+ return (NULL);
+}
+
+CAmEnvironment::CAmEnvironment()
+: mlistRoutingPluginDirs()
+, mlistCommandPluginDirs()
+, mSocketHandler()
+, mDatabasehandler()
+, mRoutingSender(mlistRoutingPluginDirs)
+, mCommandSender(mlistRoutingPluginDirs)
+, mRouter(&mDatabasehandler,&mControlSender)
+, mpCommandReceiver(NULL)
+, mpRoutingReceiver(NULL)
+, mpControlReceiver(NULL)
+, mpTelnetServer(NULL)
+, mSocketHandlerThread(0)
+{
+}
+
+CAmEnvironment::~CAmEnvironment()
+{
+ usleep(500);
+ if(NULL != mpTelnetServer)
+ delete(mpTelnetServer);
+ if(NULL != mpControlReceiver)
+ delete(mpControlReceiver);
+ if(NULL != mpRoutingReceiver)
+ delete(mpRoutingReceiver);
+ if(NULL != mpCommandReceiver)
+ delete(mpCommandReceiver);
+}
+
+void CAmEnvironment::SetUp()
+{
+ pthread_create(&mSocketHandlerThread, NULL, startSocketHandler, this);
+ sleep(1);
+}
+
+void CAmEnvironment::TearDown()
+{
+ pthread_cancel(mSocketHandlerThread);
+}
+
+void CAmEnvironment::setSocketHandler(CAmSocketHandler* pSocketHandler)
+{
+ mpSocketHandler = pSocketHandler;
+
+ if(NULL != pSocketHandler)
+ {
+ mpCommandReceiver = new CAmCommandReceiver(&mDatabasehandler,&mControlSender,mpSocketHandler);
+ mpRoutingReceiver = new CAmRoutingReceiver(&mDatabasehandler,&mRoutingSender,&mControlSender,mpSocketHandler);
+ mpControlReceiver = new CAmControlReceiver(&mDatabasehandler,&mRoutingSender,&mCommandSender,mpSocketHandler,&mRouter);
+
+ //startup all the Plugins and Interfaces
+ //mControlSender.startupController(mpControlReceiver);
+ //mCommandSender.startupInterfaces(mpCommandReceiver);
+ //mRoutingSender.startupInterfaces(mpRoutingReceiver);
+
+ //when the routingInterface is done, all plugins are loaded:
+ //mControlSender.setControllerReady();
+
+ // Starting TelnetServer
+ mpTelnetServer = new CAmTelnetServer(mpSocketHandler,&mCommandSender,mpCommandReceiver,&mRoutingSender,mpRoutingReceiver,&mControlSender,mpControlReceiver,&mDatabasehandler,&mRouter,servPort,3);
+ }
+}
+
+void CAmEnvironment::stopSocketHandler()
+{
+ mpSocketHandler->stop_listening();
+}
+
+CAmTelnetServerTest::CAmTelnetServerTest()
+{
+
+}
+
+CAmTelnetServerTest::~CAmTelnetServerTest()
+{
+
+}
+
+void CAmTelnetServerTest::SetUp()
+{
+
+}
+
+void CAmTelnetServerTest::TearDown()
+{
+
+}
+
+void CAmTelnetServerTest::sendCmd(std::string & command )
+{
+ ssize_t sizesent = send(staticSocket, command.c_str(), command.size(), 0);
+ ASSERT_EQ(static_cast<uint>(sizesent),command.size());
+
+ char buffer[1000];
+ memset(buffer,0,sizeof(buffer));
+ int read=recv(staticSocket,buffer,sizeof(buffer),0);
+ ASSERT_GT(read,1);
+}
+
+TEST_F(CAmTelnetServerTest,connectTelnetServer)
+{
+ struct sockaddr_in servAddr;
+
+ staticSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ ASSERT_GE(staticSocket,0);
+
+ struct hostent *host = (struct hostent*) gethostbyname("localhost");
+ if (host == 0)
+ {
+ std::cout << " ERROR: gethostbyname() failed\n" << std::endl;
+ return;
+ }
+
+ memset(&servAddr, 0, sizeof(servAddr));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) (host->h_addr_list[0])));
+ servAddr.sin_port = htons(servPort);
+
+ int return_connect = connect(staticSocket, (struct sockaddr *) &servAddr, sizeof(servAddr));
+ ASSERT_GE(return_connect,0);
+
+ char buffer[1000];
+ int read=recv(staticSocket,buffer,sizeof(buffer),0);
+ ASSERT_GT(read,1);
+}
+
+TEST_F(CAmTelnetServerTest,sendCmdTelnetServer)
+{
+ std::string cmd("help");
+ sendCmd(cmd);
+}
+
+TEST_F(CAmTelnetServerTest,sendDumpCmdTelnetServer)
+{
+ std::string cmd1("info");
+ std::string cmd3("dump");
+ sendCmd(cmd1);
+ sendCmd(cmd3);
+}
+
+TEST_F(CAmTelnetServerTest,closeTelnetServerConnection)
+{
+ std::string cmd("exit");
+ mpSocketHandler->stop_listening();
+ sendCmd(cmd);
+ close(staticSocket);
+ staticSocket = -1;
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ::testing::Environment* const env = ::testing::AddGlobalTestEnvironment(new CAmEnvironment);
+ (void) env;
+ return RUN_ALL_TESTS();
+}
diff --git a/AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.h b/AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.h
new file mode 100644
index 0000000..02f98a3
--- /dev/null
+++ b/AudioManagerCore/test/AmTelnetServerTest/CAmTelnetServerTest.h
@@ -0,0 +1,107 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef CAMTELNETSERVERTEST_H_
+#define CAMTELNETSERVERTEST_H_
+
+#include "gtest/gtest.h"
+#include "CAmTelnetServer.h"
+#include "CAmRoutingSender.h"
+#include "CAmCommandSender.h"
+#include "CAmControlSender.h"
+#include "CAmRouter.h"
+#include "audiomanagerconfig.h"
+#include "CAmDatabaseHandlerMap.h"
+
+
+
+
+
+namespace am
+{
+
+class CAmSocketHandler;
+class CAmRoutingSender;
+class CAmCommandSender;
+class CAmControlSender;
+class CAmRouter;
+class CAmCommandReceiver;
+class CAmRoutingReceiver;
+class CAmControlReceiver;
+class CAmTelnetServer;
+
+
+class CAmEnvironment : public ::testing::Environment
+{
+ public:
+ CAmEnvironment();
+
+ ~CAmEnvironment();
+ // Override this to define how to set up the environment.
+ void SetUp();
+ // Override this to define how to tear down the environment.
+ void TearDown();
+
+ void setSocketHandler(CAmSocketHandler* pSocketHandler);
+
+ void stopSocketHandler();
+
+ std::vector<std::string> mlistRoutingPluginDirs;
+ std::vector<std::string> mlistCommandPluginDirs;
+
+ CAmSocketHandler mSocketHandler;
+ CAmDatabaseHandlerMap mDatabasehandler;
+ CAmRoutingSender mRoutingSender;
+ CAmCommandSender mCommandSender;
+ CAmControlSender mControlSender;
+ CAmRouter mRouter;
+
+ CAmCommandReceiver* mpCommandReceiver;
+ CAmRoutingReceiver* mpRoutingReceiver;
+ CAmControlReceiver* mpControlReceiver;
+
+ CAmTelnetServer* mpTelnetServer;
+
+ pthread_t mSocketHandlerThread;
+};
+
+class CAmTelnetServerTest : public ::testing::Test
+{
+ public:
+ CAmTelnetServerTest();
+ ~CAmTelnetServerTest();
+
+
+ void SetUp() ;
+
+ void TearDown() ;
+ void sendCmd(std::string & command );
+ //int mSocket;
+};
+
+}
+
+
+
+
+#endif /* CAMTELNETSERVERTEST_H_ */
diff --git a/AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt b/AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt
new file mode 100644
index 0000000..8dcb0a3
--- /dev/null
+++ b/AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt
@@ -0,0 +1,48 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+PROJECT(AmTelnetServerTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+file(GLOB TELNET_SRCS_CXX
+ "*.cpp"
+)
+
+ADD_EXECUTABLE(AmTelnetServerTest ${TELNET_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmTelnetServerTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+add_test(AmTelnetServerTest AmTelnetServerTest)
+
+ADD_DEPENDENCIES(AmTelnetServerTest AudioManagerCore)
+
+INSTALL(TARGETS AmTelnetServerTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
+
diff --git a/AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt~ b/AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt~
new file mode 100644
index 0000000..51e92b8
--- /dev/null
+++ b/AudioManagerCore/test/AmTelnetServerTest/CMakeLists.txt~
@@ -0,0 +1,46 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+PROJECT(AmTelnetServerTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_CORE_INCLUDE}
+ ${GMOCK_INCLUDE_DIR})
+
+file(GLOB TELNET_SRCS_CXX
+ "*.cpp"
+)
+
+ADD_EXECUTABLE(AmTelnetServerTest ${TELNET_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmTelnetServerTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerCore
+)
+
+ADD_DEPENDENCIES(AmTelnetServerTest AudioManagerCore)
+
+INSTALL(TARGETS AmTelnetServerTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
+
diff --git a/AudioManagerCore/test/CAmCommonFunctions.cpp b/AudioManagerCore/test/CAmCommonFunctions.cpp
new file mode 100644
index 0000000..22331d4
--- /dev/null
+++ b/AudioManagerCore/test/CAmCommonFunctions.cpp
@@ -0,0 +1,383 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmCommonFunctions.h"
+#include "IAmCommandBackdoor.h"
+#include "IAmRoutingBackdoor.h"
+#include "IAmControlBackdoor.h"
+#include <cassert>
+#include <sstream>
+
+using namespace am;
+
+IAmCommandBackdoor::IAmCommandBackdoor()
+{
+}
+IAmCommandBackdoor::~IAmCommandBackdoor()
+{
+}
+
+bool IAmCommandBackdoor::unloadPlugins(CAmCommandSender *CommandSender)
+{
+ assert(CommandSender != NULL);
+ CommandSender->unloadLibraries();
+ CommandSender->mListInterfaces.clear();
+ if (CommandSender->mListInterfaces.empty())
+ return true;
+ return false;
+}
+
+bool IAmCommandBackdoor::injectInterface(CAmCommandSender *CommandSender, IAmCommandSend *CommandSendInterface)
+{
+ assert(CommandSender != NULL);
+ assert(CommandSendInterface != NULL);
+ CommandSender->mListInterfaces.push_back(CommandSendInterface);
+ return true;
+}
+
+IAmRoutingBackdoor::IAmRoutingBackdoor()
+{
+}
+IAmRoutingBackdoor::~IAmRoutingBackdoor()
+{
+}
+
+bool IAmRoutingBackdoor::unloadPlugins(CAmRoutingSender *RoutingSender)
+{
+ assert(RoutingSender != NULL);
+ RoutingSender->unloadLibraries();
+ RoutingSender->mListInterfaces.clear();
+ if (RoutingSender->mListInterfaces.empty())
+ return true;
+ return false;
+}
+
+bool IAmRoutingBackdoor::injectInterface(CAmRoutingSender *RoutingSender, IAmRoutingSend *newInterface, const std::string& busname)
+{
+ assert(RoutingSender != NULL);
+ assert(newInterface != NULL);
+
+ CAmRoutingSender::InterfaceNamePairs newInterfacePair;
+ newInterfacePair.routingInterface = newInterface;
+ newInterfacePair.busName = busname;
+ RoutingSender->mListInterfaces.push_back(newInterfacePair);
+ return true;
+}
+
+IAmControlBackdoor::IAmControlBackdoor()
+{
+}
+
+IAmControlBackdoor::~IAmControlBackdoor()
+{
+}
+
+bool IAmControlBackdoor::replaceController(CAmControlSender *controlSender, IAmControlSend *newController)
+{
+ controlSender->mController = newController;
+ return controlSender->mController == newController;
+}
+
+//int GetRandomNumber(int nLow, int nHigh) {
+// return (rand() % (nHigh - nLow + 1)) + nLow;
+//}
+
+bool equalSoundProperty(const am_SoundProperty_s a, const am_SoundProperty_s b)
+{
+ return (a.type == b.type && a.value == b.value);
+}
+
+bool equalMainSoundProperty(const am_MainSoundProperty_s a, const am_MainSoundProperty_s b)
+{
+ return (a.type == b.type && a.value == b.value);
+}
+
+bool equalNotificationConfiguration(const am_NotificationConfiguration_s a, const am_NotificationConfiguration_s b)
+{
+ return (a.parameter == b.parameter && a.status == b.status && a.type == b.type);
+}
+
+bool equalRoutingElement(const am_RoutingElement_s a, const am_RoutingElement_s b)
+{
+ return (a.connectionFormat == b.connectionFormat && a.domainID == b.domainID && a.sinkID == b.sinkID && a.sourceID == b.sourceID);
+}
+
+bool equalClassProperties(const am_ClassProperty_s a, const am_ClassProperty_s b)
+{
+ return (a.classProperty == b.classProperty && a.value == b.value);
+}
+
+std::string int2string(int i)
+{
+ std::stringstream out;
+ out << i;
+ return out.str();
+}
+
+bool CAmCommonFunctions::compareSource(std::vector<am_Source_s>::iterator listIterator, const am_Source_s& sourceData)
+{
+ return (listIterator->available.availability == sourceData.available.availability) && \
+ (listIterator->available.availabilityReason == sourceData.available.availabilityReason) &&
+ (listIterator->sourceClassID == sourceData.sourceClassID) &&
+ (listIterator->domainID == sourceData.domainID) &&
+ (listIterator->interruptState == sourceData.interruptState) &&
+ (listIterator->visible == sourceData.visible) &&
+ (listIterator->name.compare(sourceData.name) == 0) &&
+ (listIterator->volume == sourceData.volume) &&
+ std::equal(listIterator->listConnectionFormats.begin(), listIterator->listConnectionFormats.end(), sourceData.listConnectionFormats.begin()) &&
+ std::equal(listIterator->listMainSoundProperties.begin(), listIterator->listMainSoundProperties.end(), sourceData.listMainSoundProperties.begin(), equalMainSoundProperty) &&
+ std::equal(listIterator->listSoundProperties.begin(), listIterator->listSoundProperties.end(), sourceData.listSoundProperties.begin(), equalSoundProperty);
+}
+
+bool CAmCommonFunctions::compareSink(std::vector<am_Sink_s>::iterator listIterator, const am_Sink_s& sinkData)
+{
+ return (listIterator->available.availability == sinkData.available.availability) && (listIterator->available.availabilityReason == sinkData.available.availabilityReason) && (listIterator->sinkClassID == sinkData.sinkClassID) && (listIterator->domainID == sinkData.domainID) && (listIterator->mainVolume == sinkData.mainVolume) && (listIterator->muteState == sinkData.muteState) && (listIterator->visible == sinkData.visible) && (listIterator->name.compare(sinkData.name) == 0) && (listIterator->volume == sinkData.volume) && std::equal(listIterator->listConnectionFormats.begin(), listIterator->listConnectionFormats.end(), sinkData.listConnectionFormats.begin())
+ && std::equal(listIterator->listMainSoundProperties.begin(), listIterator->listMainSoundProperties.end(), sinkData.listMainSoundProperties.begin(), equalMainSoundProperty) && std::equal(listIterator->listSoundProperties.begin(), listIterator->listSoundProperties.end(), sinkData.listSoundProperties.begin(), equalSoundProperty);
+}
+
+bool CAmCommonFunctions::compareGateway(std::vector<am_Gateway_s>::iterator listIterator, const am_Gateway_s& gatewayData)
+{
+ return (listIterator->name.compare(gatewayData.name) == 0) && (listIterator->sinkID == gatewayData.sinkID) && (listIterator->sourceID == gatewayData.sourceID) && (listIterator->controlDomainID == gatewayData.controlDomainID) && (listIterator->domainSinkID == gatewayData.domainSinkID) && (listIterator->domainSourceID == gatewayData.domainSourceID) && std::equal(listIterator->convertionMatrix.begin(), listIterator->convertionMatrix.end(), gatewayData.convertionMatrix.begin()) && std::equal(listIterator->listSourceFormats.begin(), listIterator->listSourceFormats.end(), gatewayData.listSourceFormats.begin()) && std::equal(listIterator->listSinkFormats.begin(), listIterator->listSinkFormats.end(), gatewayData.listSinkFormats.begin());
+}
+
+bool CAmCommonFunctions::compareConverter(std::vector<am_Converter_s>::iterator listIterator, const am_Converter_s& gatewayData)
+{
+ return (listIterator->name.compare(gatewayData.name) == 0) && (listIterator->sinkID == gatewayData.sinkID) && (listIterator->sourceID == gatewayData.sourceID) && (listIterator->domainID == gatewayData.domainID) && std::equal(listIterator->convertionMatrix.begin(), listIterator->convertionMatrix.end(), gatewayData.convertionMatrix.begin()) && std::equal(listIterator->listSourceFormats.begin(), listIterator->listSourceFormats.end(), gatewayData.listSourceFormats.begin()) && std::equal(listIterator->listSinkFormats.begin(), listIterator->listSinkFormats.end(), gatewayData.listSinkFormats.begin());
+}
+
+bool CAmCommonFunctions::compareGateway1(const am_Gateway_s gateway1, const am_Gateway_s gatewayData)
+{
+ return (gateway1.name.compare(gatewayData.name) == 0) && (gateway1.sinkID == gatewayData.sinkID) && (gateway1.sourceID == gatewayData.sourceID) && (gateway1.controlDomainID == gatewayData.controlDomainID) && (gateway1.domainSinkID == gatewayData.domainSinkID) && (gateway1.domainSourceID == gatewayData.domainSourceID) && std::equal(gateway1.convertionMatrix.begin(), gateway1.convertionMatrix.end(), gatewayData.convertionMatrix.begin()) && std::equal(gateway1.listSourceFormats.begin(), gateway1.listSourceFormats.end(), gatewayData.listSourceFormats.begin()) && std::equal(gateway1.listSinkFormats.begin(), gateway1.listSinkFormats.end(), gatewayData.listSinkFormats.begin());
+}
+
+bool CAmCommonFunctions::compareConverter1(const am_Converter_s gateway1, const am_Converter_s gatewayData)
+{
+ return (gateway1.name.compare(gatewayData.name) == 0) && (gateway1.sinkID == gatewayData.sinkID) && (gateway1.sourceID == gatewayData.sourceID) && (gateway1.domainID == gatewayData.domainID) && std::equal(gateway1.convertionMatrix.begin(), gateway1.convertionMatrix.end(), gatewayData.convertionMatrix.begin()) && std::equal(gateway1.listSourceFormats.begin(), gateway1.listSourceFormats.end(), gatewayData.listSourceFormats.begin()) && std::equal(gateway1.listSinkFormats.begin(), gateway1.listSinkFormats.end(), gatewayData.listSinkFormats.begin());
+}
+
+bool CAmCommonFunctions::compareSinkMainSink(std::vector<am_SinkType_s>::iterator listIterator, const std::vector<am_Sink_s>& sinkList)
+{
+ std::vector<am_Sink_s>::const_iterator sinkListIterator = sinkList.begin();
+ for (; sinkListIterator < sinkList.end(); ++sinkListIterator)
+ {
+ if (listIterator->sinkID == sinkListIterator->sinkID)
+ {
+ return (listIterator->name.compare(sinkListIterator->name) == 0) && (listIterator->availability.availability == sinkListIterator->available.availability) && (listIterator->availability.availabilityReason == sinkListIterator->available.availabilityReason) && (listIterator->muteState == sinkListIterator->muteState) && (listIterator->volume == sinkListIterator->mainVolume) && (listIterator->sinkClassID == sinkListIterator->sinkClassID);
+ }
+ }
+ return false;
+}
+
+bool CAmCommonFunctions::compareSinkMainSource(std::vector<am_SourceType_s>::iterator listIterator, const std::vector<am_Source_s>& sourceList)
+{
+ std::vector<am_Source_s>::const_iterator sinkListIterator = sourceList.begin();
+ for (; sinkListIterator < sourceList.end(); ++sinkListIterator)
+ {
+ if (listIterator->sourceID == sinkListIterator->sourceID)
+ {
+ return (listIterator->name.compare(sinkListIterator->name) == 0) && (listIterator->availability.availability == sinkListIterator->available.availability) && (listIterator->availability.availabilityReason == sinkListIterator->available.availabilityReason) && (listIterator->sourceClassID == sinkListIterator->sourceClassID);
+ }
+ }
+ return false;
+}
+
+bool CAmCommonFunctions::compareRoute(am_Route_s a, am_Route_s b)
+{
+ bool retVal = true;
+ std::vector<am_RoutingElement_s>::iterator itA = a.route.begin(), itB = b.route.begin();
+ retVal &= a.sourceID == b.sourceID;
+ retVal &= a.sinkID == b.sinkID;
+ for (; itA != a.route.end(); ++itA)
+ {
+ retVal &= itA->sinkID == itB->sinkID;
+ retVal &= itA->sourceID == itB->sourceID;
+ retVal &= itA->connectionFormat == itB->connectionFormat;
+ retVal &= itA->domainID == itB->domainID;
+ itB++;
+ }
+ return retVal;
+}
+
+std::vector<am_CustomAvailabilityReason_t> CAmCommonFunctions::getStandardConnectionFormatList()
+{
+ std::vector<am_CustomAvailabilityReason_t> list;
+ list.push_back(CF_GENIVI_ANALOG);
+ list.push_back(CF_GENIVI_STEREO);
+ return list;
+}
+
+std::vector<am_SoundProperty_s> CAmCommonFunctions::getStandardSoundPropertyList()
+{
+ std::vector<am_SoundProperty_s> soundPropertyList;
+ am_SoundProperty_s soundProperty;
+ soundProperty.type = SP_GENIVI_BASS;
+ soundProperty.value = 23;
+ soundPropertyList.push_back(soundProperty);
+ soundProperty.type = SP_GENIVI_MID;
+ soundProperty.value = 2;
+ soundPropertyList.push_back(soundProperty);
+ return soundPropertyList;
+}
+
+std::vector<am_MainSoundProperty_s> CAmCommonFunctions::getStandardMainSoundPropertyList()
+{
+ std::vector<am_MainSoundProperty_s> mainSoundPropertyList;
+ am_MainSoundProperty_s mainSoundProperty;
+ mainSoundProperty.type = MSP_GENIVI_BASS;
+ mainSoundProperty.value = 23;
+ mainSoundPropertyList.push_back(mainSoundProperty);
+ mainSoundProperty.type = MSP_UNKNOWN;
+ mainSoundProperty.value = 3;
+ mainSoundPropertyList.push_back(mainSoundProperty);
+ return mainSoundPropertyList;
+}
+
+void CAmCommonFunctions::createSink(am_Sink_s& sink) const
+{
+ sink.name = "AnySink";
+ sink.domainID = 4;
+ sink.available.availability = A_AVAILABLE;
+ sink.available.availabilityReason = AR_GENIVI_NEWMEDIA;
+ sink.sinkClassID = 1;
+ sink.listConnectionFormats = getStandardConnectionFormatList();
+ sink.listSoundProperties = getStandardSoundPropertyList();
+ sink.listMainSoundProperties = getStandardMainSoundPropertyList();
+ sink.listNotificationConfigurations = getStandardNotificationConfigurationList();
+ sink.listMainNotificationConfigurations = getStandardNotificationConfigurationList();
+ sink.mainVolume = 12;
+ sink.muteState = MS_UNMUTED;
+ sink.visible = true;
+ sink.volume = 23;
+ sink.sinkID = 0;
+}
+
+void CAmCommonFunctions::createSource(am_Source_s& source) const
+{
+ source.name = "AnySource";
+ source.domainID = 4;
+ source.available.availability = A_AVAILABLE;
+ source.available.availabilityReason = AR_GENIVI_NEWMEDIA;
+ source.sourceClassID = 1;
+ source.listConnectionFormats = getStandardConnectionFormatList();
+ source.listSoundProperties = getStandardSoundPropertyList();
+ source.listMainSoundProperties = getStandardMainSoundPropertyList();
+ source.listMainNotificationConfigurations=getStandardNotificationConfigurationList();
+ source.listNotificationConfigurations=getStandardNotificationConfigurationList();
+ source.interruptState = IS_OFF;
+ source.visible = true;
+ source.volume = 23;
+ source.sourceID = 0;
+ source.sourceState = SS_ON;
+}
+
+void CAmCommonFunctions::createDomain(am_Domain_s & domain) const
+{
+
+ domain.domainID = 0;
+ domain.name = "AnyDomain";
+ domain.nodename = "AnyNode";
+ domain.busname = "AnyBusname";
+ domain.complete = true;
+ domain.early = true;
+ domain.state = DS_CONTROLLED;
+}
+
+void CAmCommonFunctions::createGateway(am_Gateway_s & gateway)
+{
+ gateway.name = "AnyGateway";
+ gateway.sinkID = 1;
+ gateway.sourceID = 2;
+ gateway.controlDomainID = 1;
+ gateway.domainSinkID = 3;
+ gateway.domainSourceID = 4;
+ gateway.convertionMatrix = getStandardConvertionMatrix();
+ gateway.listSourceFormats = getStandardConnectionFormatList();
+ gateway.listSinkFormats = getStandardConnectionFormatList();
+ gateway.gatewayID = 0;
+
+}
+
+void CAmCommonFunctions::createConverter(am_Converter_s & converter) const
+{
+ converter.name = "AnyConverter";
+ converter.sinkID = 1;
+ converter.sourceID = 2;
+ converter.domainID = 1;
+ converter.convertionMatrix = getStandardConvertionMatrix();
+ converter.listSourceFormats = getStandardConnectionFormatList();
+ converter.listSinkFormats = getStandardConnectionFormatList();
+ converter.converterID = 0;
+
+}
+
+void CAmCommonFunctions::createConnection(am_Connection_s & connection) const
+{
+ connection.connectionID = 0;
+ connection.sinkID = 1;
+ connection.sourceID = 2;
+ connection.delay = -1;
+ connection.connectionFormat = CF_GENIVI_ANALOG;
+}
+
+std::vector<bool> CAmCommonFunctions::getStandardConvertionMatrix()
+{
+ std::vector<bool> convMatrix;
+ convMatrix.push_back(true);
+ convMatrix.push_back(false);
+ convMatrix.push_back(true);
+ convMatrix.push_back(false);
+ convMatrix.push_back(true);
+ convMatrix.push_back(true);
+ return convMatrix;
+}
+
+std::vector<am_NotificationConfiguration_s> am::CAmCommonFunctions::getStandardNotificationConfigurationList()
+{
+ std::vector<am_NotificationConfiguration_s> listNotificationConfigurations;
+ am_NotificationConfiguration_s tempNotificationConfiguration;
+ tempNotificationConfiguration.type=NT_TEST_1;
+ tempNotificationConfiguration.parameter=12;
+ tempNotificationConfiguration.status=NS_PERIODIC;
+ listNotificationConfigurations.push_back(tempNotificationConfiguration);
+
+ tempNotificationConfiguration.type=NT_TEST_2;
+ tempNotificationConfiguration.parameter=16;
+ tempNotificationConfiguration.status=NS_CHANGE;
+ listNotificationConfigurations.push_back(tempNotificationConfiguration);
+
+ return (listNotificationConfigurations);
+}
+
+void CAmCommonFunctions::connectionList2RoutingList(std::vector<am_RoutingElement_s> & routingList, const std::vector<am_Connection_s>& connectionList)
+{
+ am_RoutingElement_s routingElement;
+ std::vector<am_Connection_s>::const_iterator cIterator = connectionList.begin();
+ for (; cIterator < connectionList.end(); ++cIterator)
+ {
+ routingElement.sinkID = cIterator->sinkID;
+ routingElement.sourceID = cIterator->sourceID;
+ routingElement.connectionFormat = cIterator->connectionFormat;
+ routingElement.domainID = 4; //todo: make this test read out the real value
+ routingList.push_back(routingElement);
+ }
+}
+
diff --git a/AudioManagerCore/test/CAmCommonFunctions.h b/AudioManagerCore/test/CAmCommonFunctions.h
new file mode 100644
index 0000000..9dbdc8f
--- /dev/null
+++ b/AudioManagerCore/test/CAmCommonFunctions.h
@@ -0,0 +1,96 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef COMMONHEADERS_H_
+#define COMMONHEADERS_H_
+
+#include "audiomanagertypes.h"
+
+namespace am
+{
+
+static const am_CustomNotificationType_t NT_TEST_1 = 1;
+static const am_CustomNotificationType_t NT_TEST_2 = 2;
+
+
+class CAmCommonFunctions
+{
+public:
+
+ static std::vector<am_CustomAvailabilityReason_t> getStandardConnectionFormatList();
+ static std::vector<am_SoundProperty_s> getStandardSoundPropertyList();
+ static std::vector<am_MainSoundProperty_s> getStandardMainSoundPropertyList();
+ static std::vector<bool> getStandardConvertionMatrix();
+ static std::vector<am_NotificationConfiguration_s> getStandardNotificationConfigurationList();
+ bool compareSource(std::vector<am_Source_s>::iterator listIterator, const am_Source_s& sourceData);
+ bool compareSink(std::vector<am_Sink_s>::iterator listIterator, const am_Sink_s& sinkData);
+ bool compareGateway(std::vector<am_Gateway_s>::iterator listIterator, const am_Gateway_s& gatewayData);
+ bool compareGateway1(const am_Gateway_s gateway1, const am_Gateway_s gatewayData);
+ bool compareConverter(std::vector<am_Converter_s>::iterator listIterator, const am_Converter_s& gatewayData);
+ bool compareConverter1(const am_Converter_s gateway1, const am_Converter_s gatewayData);
+ bool compareSinkMainSink(std::vector<am_SinkType_s>::iterator listIterator, const std::vector<am_Sink_s>& sinkList);
+ bool compareSinkMainSource(std::vector<am_SourceType_s>::iterator listIterator, const std::vector<am_Source_s>& sourceList);
+ bool compareRoute(am_Route_s a, am_Route_s b);
+ void createSink(am_Sink_s& sink) const;
+ void createSource(am_Source_s& source) const;
+ void createDomain(am_Domain_s& domain) const;
+ void createGateway(am_Gateway_s& gateway);
+ void createConnection(am_Connection_s& connection) const;
+ void createConverter(am_Converter_s & converter) const;
+ void connectionList2RoutingList(std::vector<am_RoutingElement_s>& routingList, const std::vector<am_Connection_s>& connectionList);
+
+ struct sortBySinkID
+ {
+ bool operator()(const am_RoutingElement_s & a, const am_RoutingElement_s & b) const
+ {
+ return (a.sinkID < b.sinkID);
+ }
+ };
+
+ struct sortByConnectionFormat
+ {
+ bool operator()(const am_CustomAvailabilityReason_t & a, const am_CustomAvailabilityReason_t & b) const
+ {
+ return (a < b);
+ }
+ };
+
+ struct sortByMainSoundProperty
+ {
+ bool operator()(const am_MainSoundProperty_s & a, const am_MainSoundProperty_s & b) const
+ {
+ return (a.type > b.type);
+ }
+ };
+
+ struct sortBySoundProperty
+ {
+ bool operator()(const am_SoundProperty_s & a, const am_SoundProperty_s & b) const
+ {
+ return (a.type < b.type);
+ }
+ };
+};
+
+}
+
+#endif /* COMMONHEADERS_H_ */
diff --git a/AudioManagerCore/test/CMakeLists.txt b/AudioManagerCore/test/CMakeLists.txt
new file mode 100644
index 0000000..9dd9007
--- /dev/null
+++ b/AudioManagerCore/test/CMakeLists.txt
@@ -0,0 +1,35 @@
+# 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
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+
+set(EXECUTABLE_OUTPUT_PATH ${TEST_EXECUTABLE_OUTPUT_PATH})
+
+#make aunt google stop complaining
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNIT_TEST=1 -DDLT_CONTEXT=AudioManager -Wno-unused-local-typedefs -lz -ldl")
+
+add_subdirectory (AmControlInterfaceTest)
+add_subdirectory (AmMapHandlerTest)
+add_subdirectory (AmRouterTest)
+add_subdirectory (AmRouterMapTest)
+add_subdirectory (AmRoutingInterfaceTest)
+
+IF(WITH_TELNET)
+ add_subdirectory (AmTelnetServerTest)
+ENDIF(WITH_TELNET)
+
diff --git a/AudioManagerCore/test/IAmCommandBackdoor.h b/AudioManagerCore/test/IAmCommandBackdoor.h
new file mode 100644
index 0000000..b7d2b20
--- /dev/null
+++ b/AudioManagerCore/test/IAmCommandBackdoor.h
@@ -0,0 +1,47 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef COMMANDINTERFACEBACKDOOR_H_
+#define COMMANDINTERFACEBACKDOOR_H_
+
+#include <IAmCommand.h>
+#include "CAmCommandSender.h"
+
+namespace am
+{
+
+class CAmCommandSender;
+
+class IAmCommandBackdoor
+{
+public:
+ IAmCommandBackdoor();
+ virtual ~IAmCommandBackdoor();
+ bool unloadPlugins(CAmCommandSender *CommandSender);
+ bool injectInterface(CAmCommandSender* CommandSender, IAmCommandSend* CommandSendInterface);
+};
+
+}
+
+//definitions are in CAmCommonFunctions.cpp!
+
+#endif /* COMMANDINTERFACEBACKDOOR_H_ */
diff --git a/AudioManagerCore/test/IAmControlBackdoor.h b/AudioManagerCore/test/IAmControlBackdoor.h
new file mode 100644
index 0000000..b5ba3ef
--- /dev/null
+++ b/AudioManagerCore/test/IAmControlBackdoor.h
@@ -0,0 +1,44 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef CONTROLINTERFACEBACKDOOR_H_
+#define CONTROLINTERFACEBACKDOOR_H_
+
+#include "IAmControl.h"
+#include "CAmControlSender.h"
+
+namespace am
+{
+
+class CAmControlSender;
+
+class IAmControlBackdoor
+{
+public:
+ IAmControlBackdoor();
+ virtual ~IAmControlBackdoor();
+ bool replaceController(CAmControlSender *controlSender, IAmControlSend *newController);
+};
+
+}
+
+#endif /* CONTROLINTERFACEBACKDOOR_H_ */
diff --git a/AudioManagerCore/test/IAmRoutingBackdoor.h b/AudioManagerCore/test/IAmRoutingBackdoor.h
new file mode 100644
index 0000000..cbdb070
--- /dev/null
+++ b/AudioManagerCore/test/IAmRoutingBackdoor.h
@@ -0,0 +1,46 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef ROUTINGINTERFACEBACKDOOR_H_
+#define ROUTINGINTERFACEBACKDOOR_H_
+
+#include "CAmRoutingSender.h"
+
+namespace am
+{
+
+class CAmRoutingSender;
+
+class IAmRoutingBackdoor
+{
+public:
+ IAmRoutingBackdoor();
+ virtual ~IAmRoutingBackdoor();
+ bool unloadPlugins(CAmRoutingSender *RoutingSender);
+ bool injectInterface(CAmRoutingSender *RoutingSender, IAmRoutingSend *newInterface, const std::string& busname);
+};
+
+}
+
+//definitions are in CAmCommonFunctions.cpp!
+
+#endif /* ROUTINGINTERFACEBACKDOOR_H_ */
diff --git a/AudioManagerCore/test/MockIAmCommandSend.h b/AudioManagerCore/test/MockIAmCommandSend.h
new file mode 100644
index 0000000..36bc1cb
--- /dev/null
+++ b/AudioManagerCore/test/MockIAmCommandSend.h
@@ -0,0 +1,94 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef MOCKCOMMANDINTERFACE_H_
+#define MOCKCOMMANDINTERFACE_H_
+
+#include "IAmCommand.h"
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+namespace am {
+
+class MockIAmCommandSend : public IAmCommandSend {
+ public:
+ MOCK_CONST_METHOD1(getInterfaceVersion,
+ void(std::string& version));
+ MOCK_METHOD1(startupInterface,
+ am_Error_e(IAmCommandReceive* commandreceiveinterface));
+ MOCK_METHOD1(setCommandReady,
+ void(const uint16_t handle));
+ MOCK_METHOD1(setCommandRundown,
+ void(const uint16_t handle));
+ MOCK_METHOD1(cbNewMainConnection,
+ void(const am_MainConnectionType_s& mainConnection));
+ MOCK_METHOD1(cbRemovedMainConnection,
+ void(const am_mainConnectionID_t mainConnection));
+ MOCK_METHOD1(cbNewSink,
+ void(const am_SinkType_s& sink));
+ MOCK_METHOD1(cbRemovedSink,
+ void(const am_sinkID_t sinkID));
+ MOCK_METHOD1(cbNewSource,
+ void(const am_SourceType_s& source));
+ MOCK_METHOD1(cbRemovedSource,
+ void(const am_sourceID_t source));
+ MOCK_METHOD0(cbNumberOfSinkClassesChanged,
+ void());
+ MOCK_METHOD0(cbNumberOfSourceClassesChanged,
+ void());
+ MOCK_METHOD2(cbMainConnectionStateChanged,
+ void(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState));
+ MOCK_METHOD2(cbMainSinkSoundPropertyChanged,
+ void(const am_sinkID_t sinkID, const am_MainSoundProperty_s& soundProperty));
+ MOCK_METHOD2(cbMainSourceSoundPropertyChanged,
+ void(const am_sourceID_t sourceID, const am_MainSoundProperty_s& soundProperty));
+ MOCK_METHOD2(cbSinkAvailabilityChanged,
+ void(const am_sinkID_t sinkID, const am_Availability_s& availability));
+ MOCK_METHOD2(cbSourceAvailabilityChanged,
+ void(const am_sourceID_t sourceID, const am_Availability_s& availability));
+ MOCK_METHOD2(cbVolumeChanged,
+ void(const am_sinkID_t sinkID, const am_mainVolume_t volume));
+ MOCK_METHOD2(cbSinkMuteStateChanged,
+ void(const am_sinkID_t sinkID, const am_MuteState_e muteState));
+ MOCK_METHOD1(cbSystemPropertyChanged,
+ void(const am_SystemProperty_s& systemProperty));
+ MOCK_METHOD2(cbTimingInformationChanged,
+ void(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time));
+ MOCK_METHOD3(cbSinkUpdated,
+ void(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties));
+ MOCK_METHOD3(cbSourceUpdated,
+ void(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties));
+ MOCK_METHOD2(cbSinkNotification,
+ void(const am_sinkID_t sinkID, const am_NotificationPayload_s& notification));
+ MOCK_METHOD2(cbSourceNotification,
+ void(const am_sourceID_t sourceID, const am_NotificationPayload_s& notification));
+ MOCK_METHOD2(cbMainSinkNotificationConfigurationChanged,
+ void(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration));
+ MOCK_METHOD2(cbMainSourceNotificationConfigurationChanged,
+ void(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration));
+
+
+
+};
+
+} // namespace am
+#endif /* MOCKCOMMANDINTERFACE_H_ */
diff --git a/AudioManagerCore/test/MockIAmControlSend.h b/AudioManagerCore/test/MockIAmControlSend.h
new file mode 100644
index 0000000..e628068
--- /dev/null
+++ b/AudioManagerCore/test/MockIAmControlSend.h
@@ -0,0 +1,160 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef MOCKCONTROLINTERFACE_H_
+#define MOCKCONTROLINTERFACE_H_
+
+#include "IAmControl.h"
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+namespace am {
+
+class MockIAmControlSend : public IAmControlSend {
+ public:
+ MOCK_CONST_METHOD1(getInterfaceVersion,
+ void(std::string& version));
+ MOCK_METHOD1(startupController,
+ am_Error_e(IAmControlReceive* controlreceiveinterface));
+ MOCK_METHOD0(setControllerReady,
+ void());
+ MOCK_METHOD1(setControllerRundown,
+ void(const int16_t signal));
+ MOCK_METHOD3(hookUserConnectionRequest,
+ am_Error_e(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t& mainConnectionID));
+ MOCK_METHOD1(hookUserDisconnectionRequest,
+ am_Error_e(const am_mainConnectionID_t connectionID));
+ MOCK_METHOD2(hookUserSetMainSinkSoundProperty,
+ am_Error_e(const am_sinkID_t sinkID, const am_MainSoundProperty_s& soundProperty));
+ MOCK_METHOD2(hookUserSetMainSourceSoundProperty,
+ am_Error_e(const am_sourceID_t sourceID, const am_MainSoundProperty_s& soundProperty));
+ MOCK_METHOD1(hookUserSetSystemProperty,
+ am_Error_e(const am_SystemProperty_s& property));
+ MOCK_METHOD2(hookUserVolumeChange,
+ am_Error_e(const am_sinkID_t SinkID, const am_mainVolume_t newVolume));
+ MOCK_METHOD2(hookUserVolumeStep,
+ am_Error_e(const am_sinkID_t SinkID, const int16_t increment));
+ MOCK_METHOD2(hookUserSetSinkMuteState,
+ am_Error_e(const am_sinkID_t sinkID, const am_MuteState_e muteState));
+ MOCK_METHOD2(hookSystemRegisterDomain,
+ am_Error_e(const am_Domain_s& domainData, am_domainID_t& domainID));
+ MOCK_METHOD1(hookSystemDeregisterDomain,
+ am_Error_e(const am_domainID_t domainID));
+ MOCK_METHOD1(hookSystemDomainRegistrationComplete,
+ void(const am_domainID_t domainID));
+ MOCK_METHOD2(hookSystemRegisterSink,
+ am_Error_e(const am_Sink_s& sinkData, am_sinkID_t& sinkID));
+ MOCK_METHOD1(hookSystemDeregisterSink,
+ am_Error_e(const am_sinkID_t sinkID));
+ MOCK_METHOD2(hookSystemRegisterSource,
+ am_Error_e(const am_Source_s& sourceData, am_sourceID_t& sourceID));
+ MOCK_METHOD1(hookSystemDeregisterSource,
+ am_Error_e(const am_sourceID_t sourceID));
+ MOCK_METHOD2(hookSystemRegisterConverter,
+ am_Error_e(const am_Converter_s& converterData, am_converterID_t& converterID));
+ MOCK_METHOD2(hookSystemRegisterGateway,
+ am_Error_e(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID));
+ MOCK_METHOD1(hookSystemDeregisterConverter,
+ am_Error_e(const am_converterID_t converterID));
+ MOCK_METHOD1(hookSystemDeregisterGateway,
+ am_Error_e(const am_gatewayID_t gatewayID));
+ MOCK_METHOD2(hookSystemRegisterCrossfader,
+ am_Error_e(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID));
+ MOCK_METHOD1(hookSystemDeregisterCrossfader,
+ am_Error_e(const am_crossfaderID_t crossfaderID));
+ MOCK_METHOD3(hookSystemSinkVolumeTick,
+ void(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume));
+ MOCK_METHOD3(hookSystemSourceVolumeTick,
+ void(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume));
+ MOCK_METHOD2(hookSystemInterruptStateChange,
+ void(const am_sourceID_t sourceID, const am_InterruptState_e interruptState));
+ MOCK_METHOD2(hookSystemSinkAvailablityStateChange,
+ void(const am_sinkID_t sinkID, const am_Availability_s& availability));
+ MOCK_METHOD2(hookSystemSourceAvailablityStateChange,
+ void(const am_sourceID_t sourceID, const am_Availability_s& availability));
+ MOCK_METHOD2(hookSystemDomainStateChange,
+ void(const am_domainID_t domainID, const am_DomainState_e state));
+ MOCK_METHOD1(hookSystemReceiveEarlyData,
+ void(const std::vector<am_EarlyData_s>& data));
+ MOCK_METHOD1(hookSystemSpeedChange,
+ void(const am_speed_t speed));
+ MOCK_METHOD2(hookSystemTimingInformationChanged,
+ void(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time));
+ MOCK_METHOD2(cbAckConnect,
+ void(const am_Handle_s handle, const am_Error_e errorID));
+ MOCK_METHOD2(cbAckDisconnect,
+ void(const am_Handle_s handle, const am_Error_e errorID));
+ MOCK_METHOD3(cbAckCrossFade,
+ void(const am_Handle_s handle, const am_HotSink_e hostsink, const am_Error_e error));
+ MOCK_METHOD3(cbAckSetSinkVolumeChange,
+ void(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error));
+ MOCK_METHOD3(cbAckSetSourceVolumeChange,
+ void(const am_Handle_s handle, const am_volume_t voulme, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSourceState,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSourceSoundProperties,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSourceSoundProperty,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSinkSoundProperties,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSinkSoundProperty,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD5(getConnectionFormatChoice,
+ am_Error_e(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));
+ MOCK_METHOD1(confirmCommandReady,
+ void(const am_Error_e error));
+ MOCK_METHOD1(confirmRoutingReady,
+ void(const am_Error_e error));
+ MOCK_METHOD1(confirmCommandRundown,
+ void(const am_Error_e error));
+ MOCK_METHOD1(confirmRoutingRundown,
+ void(const am_Error_e error));
+ MOCK_METHOD5(hookSystemUpdateSink,
+ am_Error_e(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));
+ MOCK_METHOD5(hookSystemUpdateSource,
+ am_Error_e(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));
+ MOCK_METHOD4(hookSystemUpdateConverter,
+ am_Error_e(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix));
+ MOCK_METHOD4(hookSystemUpdateGateway,
+ am_Error_e(const am_gatewayID_t gatewayID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix));
+ MOCK_METHOD3(cbAckSetVolumes,
+ void(const am_Handle_s handle, const std::vector<am_Volumes_s>& listVolumes, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSinkNotificationConfiguration,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD2(cbAckSetSourceNotificationConfiguration,
+ void(const am_Handle_s handle, const am_Error_e error));
+ MOCK_METHOD2(hookSinkNotificationDataChanged,
+ void(const am_sinkID_t sinkID, const am_NotificationPayload_s& payload));
+ MOCK_METHOD2(hookSourceNotificationDataChanged,
+ void(const am_sourceID_t sourceID, const am_NotificationPayload_s& payload));
+ MOCK_METHOD2(hookUserSetMainSinkNotificationConfiguration,
+ am_Error_e(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration));
+ MOCK_METHOD2(hookUserSetMainSourceNotificationConfiguration,
+ am_Error_e(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration));
+ MOCK_METHOD2(hookSystemSingleTimingInformationChanged,
+ void(const am_connectionID_t connectionID, const am_timeSync_t time));
+};
+
+
+} // namespace am
+#endif /* MOCKCONTROLINTERFACE_H_ */
diff --git a/AudioManagerCore/test/MockIAmRoutingSend.h b/AudioManagerCore/test/MockIAmRoutingSend.h
new file mode 100644
index 0000000..748e64e
--- /dev/null
+++ b/AudioManagerCore/test/MockIAmRoutingSend.h
@@ -0,0 +1,83 @@
+/**
+ * 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
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef MOCKROUTINGINTERFACE_H_
+#define MOCKROUTINGINTERFACE_H_
+
+#include "IAmRouting.h"
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+namespace am {
+
+class MockIAmRoutingSend : public IAmRoutingSend {
+ public:
+ MOCK_CONST_METHOD1(getInterfaceVersion,
+ void(std::string& version));
+ MOCK_METHOD1(startupInterface,
+ am_Error_e(IAmRoutingReceive* routingreceiveinterface));
+ MOCK_METHOD1(setRoutingReady,
+ void(const uint16_t handle));
+ MOCK_METHOD1(setRoutingRundown,
+ void(const uint16_t handle));
+ MOCK_METHOD1(asyncAbort,
+ am_Error_e(const am_Handle_s handle));
+ MOCK_METHOD5(asyncConnect,
+ am_Error_e(const am_Handle_s handle, const am_connectionID_t connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_CustomAvailabilityReason_t connectionFormat));
+ MOCK_METHOD2(asyncDisconnect,
+ am_Error_e(const am_Handle_s handle, const am_connectionID_t connectionID));
+ MOCK_METHOD5(asyncSetSinkVolume,
+ am_Error_e(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time));
+ MOCK_METHOD5(asyncSetSourceVolume,
+ am_Error_e(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time));
+ MOCK_METHOD3(asyncSetSourceState,
+ am_Error_e(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state));
+ MOCK_METHOD3(asyncSetSinkSoundProperties,
+ am_Error_e(const am_Handle_s handle, const am_sinkID_t sinkID, const std::vector<am_SoundProperty_s>& listSoundProperties));
+ MOCK_METHOD3(asyncSetSinkSoundProperty,
+ am_Error_e(const am_Handle_s handle, const am_sinkID_t sinkID, const am_SoundProperty_s& soundProperty));
+ MOCK_METHOD3(asyncSetSourceSoundProperties,
+ am_Error_e(const am_Handle_s handle, const am_sourceID_t sourceID, const std::vector<am_SoundProperty_s>& listSoundProperties));
+ MOCK_METHOD3(asyncSetSourceSoundProperty,
+ am_Error_e(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SoundProperty_s& soundProperty));
+ MOCK_METHOD5(asyncCrossFade,
+ am_Error_e(const am_Handle_s handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_CustomRampType_t rampType, const am_time_t time));
+ MOCK_METHOD2(setDomainState,
+ am_Error_e(const am_domainID_t domainID, const am_DomainState_e domainState));
+ MOCK_CONST_METHOD1(returnBusName,
+ am_Error_e(std::string& BusName));
+ MOCK_METHOD2(asyncSetVolumes,
+ am_Error_e(const am_Handle_s handle, const std::vector<am_Volumes_s>& listVolumes));
+ MOCK_METHOD3(asyncSetSinkNotificationConfiguration,
+ am_Error_e(const am_Handle_s handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& notificationConfiguration));
+ MOCK_METHOD3(asyncSetSourceNotificationConfiguration,
+ am_Error_e(const am_Handle_s handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& notificationConfiguration));
+ MOCK_METHOD2(resyncConnectionState,
+ am_Error_e(const am_domainID_t domainID, std::vector<am_Connection_s>& listOfExistingConnections));
+
+
+};
+
+} // namespace am
+
+
+#endif /* MOCKROUTINGINTERFACE_H_ */