diff options
author | Christian Linke <Christian.Linke@bmw.de> | 2016-02-11 07:28:47 +0100 |
---|---|---|
committer | Christian Linke <Christian.Linke@bmw.de> | 2016-02-15 09:00:59 +0100 |
commit | 5bcd206b9270d9a79e212f91723ea1a08a4d4859 (patch) | |
tree | 55b0cd4d07fbd7ebfd15d58d02e9cae6ae61b127 /AudioManagerCore/include | |
parent | 59080ecc2c8840fd85c561adea3f85f5344534a8 (diff) | |
download | audiomanager-5bcd206b9270d9a79e212f91723ea1a08a4d4859.tar.gz |
* rework of the build structure, adopt to standard cmake package structure7.4
* check versions when loading the libs
* introduction of the AudioManagerCore
* give control plugin as file or directory
* remove SQLITE
* either find and use gmock or build and install it
* fixed [Bug 411]
* compile flag gnu11 is now used
Signed-off-by: Christian Linke <Christian.Linke@bmw.de>
Signed-off-by: Christian Linke <Christian.Linke@bmw.de>
Diffstat (limited to 'AudioManagerCore/include')
-rw-r--r-- | AudioManagerCore/include/CAmCommandReceiver.h | 97 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmCommandSender.h | 91 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmControlReceiver.h | 156 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmControlSender.h | 154 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmDatabaseHandlerMap.h | 495 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmDatabaseObserver.h | 87 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmGraph.h | 630 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmLog.h | 129 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmRouter.h | 317 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmRoutingReceiver.h | 127 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmRoutingSender.h | 155 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmTelnetMenuHelper.h | 204 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmTelnetServer.h | 100 | ||||
-rw-r--r-- | AudioManagerCore/include/IAmDatabaseHandler.h | 200 | ||||
-rw-r--r-- | AudioManagerCore/include/TAmPluginTemplate.h | 91 |
15 files changed, 3033 insertions, 0 deletions
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_ */ |