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/src/CAmCommandSender.cpp | |
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/src/CAmCommandSender.cpp')
-rw-r--r-- | AudioManagerCore/src/CAmCommandSender.cpp | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/AudioManagerCore/src/CAmCommandSender.cpp b/AudioManagerCore/src/CAmCommandSender.cpp new file mode 100644 index 0000000..da064cc --- /dev/null +++ b/AudioManagerCore/src/CAmCommandSender.cpp @@ -0,0 +1,367 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2012, BMW AG + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012 + * + * \file CAmCommandSender.cpp + * For further information see http://www.genivi.org/. + * + */ + +#include "CAmCommandSender.h" +#include <dirent.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sstream> +#include <string> +#include <cstring> +#include <stdexcept> +#include "CAmCommandReceiver.h" +#include "TAmPluginTemplate.h" +#include "CAmDltWrapper.h" +#include "audiomanagerconfig.h" + +namespace am +{ + +/** + * macro to call all interfaces + */ +#define CALL_ALL_INTERFACES(...) \ + std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin(); \ + std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end(); \ + for (; iter<iterEnd;++iter) \ + { \ + (*iter)->__VA_ARGS__; \ + } + +CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories) : + mListInterfaces(), // + mListLibraryHandles(), // + mListLibraryNames(), // + mCommandReceiver() +{ + if (listOfPluginDirectories.empty()) + { + logError("CAmCommandSender::CAmCommandSender: List of commandplugins is empty"); + } + + std::vector<std::string> sharedLibraryNameList; + std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin(); + std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end(); + + // search communicator plugins in configured directories + for (; dirIter < dirIterEnd; ++dirIter) + { + const char* directoryName = dirIter->c_str(); + logInfo("Searching for CommandPlugins in", *dirIter); + DIR *directory = opendir(directoryName); + + if (!directory) + { + logError("Error opening directory ", *dirIter); + continue; + } + + // iterate content of directory + struct dirent *itemInDirectory = 0; + while ((itemInDirectory = readdir(directory))) + { + unsigned char entryType = itemInDirectory->d_type; + std::string entryName = itemInDirectory->d_name; + std::string fullName = *dirIter + "/" + entryName; + + bool regularFile = (entryType == DT_REG || entryType == DT_LNK); + bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1)); + + // Handle cases where readdir() could not determine the file type + if (entryType == DT_UNKNOWN) { + struct stat buf; + + if (stat(fullName.c_str(), &buf)) { + logInfo(__PRETTY_FUNCTION__,"Failed to stat file: ", entryName, errno); + continue; + } + + regularFile = S_ISREG(buf.st_mode); + } + + if (regularFile && sharedLibExtension) + { + std::string name(directoryName); + sharedLibraryNameList.push_back(name + "/" + entryName); + } + } + closedir(directory); + } + + // iterate all communicator plugins and start them + std::vector<std::string>::iterator iter = sharedLibraryNameList.begin(); + std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end(); + + for (; iter < iterEnd; ++iter) + { + logInfo("Loading CommandSender plugin", *iter); + IAmCommandSend* (*createFunc)(); + void* tempLibHandle = NULL; + createFunc = getCreateFunction<IAmCommandSend*()>(*iter, tempLibHandle); + + if (!createFunc) + { + logInfo("Entry point of CommandPlugin not found", *iter); + continue; + } + + IAmCommandSend* commander = createFunc(); + + if (!commander) + { + logInfo("CommandPlugin initialization failed. Entry Function not callable"); + dlclose(tempLibHandle); + continue; + } + + //check libversion + std::string version, cVersion(CommandVersion); + commander->getInterfaceVersion(version); + uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion; + std::istringstream(version.substr(0, 1)) >> majorVersion; + std::istringstream(version.substr(2, 1)) >> minorVersion; + std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion; + std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion; + + + + if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion))) + { + logError("CommandInterface initialization failed. Version of Interface to old"); + dlclose(tempLibHandle); + continue; + } + + mListInterfaces.push_back(commander); + mListLibraryHandles.push_back(tempLibHandle); + mListLibraryNames.push_back(iter->c_str()); + } +} + +CAmCommandSender::~CAmCommandSender() +{ + //unloadLibraries(); +} + +am_Error_e CAmCommandSender::startupInterfaces(CAmCommandReceiver *iCommandReceiver) +{ + mCommandReceiver = iCommandReceiver; + am_Error_e returnError = E_OK; + + std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin(); + std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end(); + for (; iter < iterEnd; ++iter) + { + am_Error_e error = (*iter)->startupInterface(iCommandReceiver); + if (error != E_OK) + { + returnError = error; + } + } + return (returnError); +} + +void CAmCommandSender::cbNumberOfSinkClassesChanged() +{ + CALL_ALL_INTERFACES(cbNumberOfSinkClassesChanged()) +} + +void CAmCommandSender::cbNumberOfSourceClassesChanged() +{ + CALL_ALL_INTERFACES(cbNumberOfSourceClassesChanged()) +} + +void CAmCommandSender::cbMainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState) +{ + CALL_ALL_INTERFACES(cbMainConnectionStateChanged(connectionID,connectionState)) +} + +void CAmCommandSender::cbMainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty) +{ + CALL_ALL_INTERFACES(cbMainSinkSoundPropertyChanged(sinkID,SoundProperty)) +} + +void CAmCommandSender::cbMainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty) +{ + CALL_ALL_INTERFACES(cbMainSourceSoundPropertyChanged(sourceID,SoundProperty)) +} + +void CAmCommandSender::cbSinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s & availability) +{ + CALL_ALL_INTERFACES(cbSinkAvailabilityChanged(sinkID,availability)) +} + +void CAmCommandSender::cbSourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s & availability) +{ + CALL_ALL_INTERFACES(cbSourceAvailabilityChanged(sourceID,availability)) +} + +void CAmCommandSender::cbVolumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume) +{ + CALL_ALL_INTERFACES(cbVolumeChanged(sinkID,volume)) +} + +void CAmCommandSender::cbSinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState) +{ + CALL_ALL_INTERFACES(cbSinkMuteStateChanged(sinkID,muteState)) +} + +void CAmCommandSender::cbSystemPropertyChanged(const am_SystemProperty_s & SystemProperty) +{ + CALL_ALL_INTERFACES(cbSystemPropertyChanged(SystemProperty)) +} + +void CAmCommandSender::cbTimingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time) +{ + CALL_ALL_INTERFACES(cbTimingInformationChanged(mainConnection,time)) +} + +void CAmCommandSender::cbNewMainConnection(const am_MainConnectionType_s mainConnection) +{ + CALL_ALL_INTERFACES(cbNewMainConnection(mainConnection)) +} + +void CAmCommandSender::cbRemovedMainConnection(const am_mainConnectionID_t mainConnection) +{ + CALL_ALL_INTERFACES(cbRemovedMainConnection(mainConnection)) +} + +void CAmCommandSender::cbNewSink(const am_SinkType_s sink) +{ + CALL_ALL_INTERFACES(cbNewSink(sink)) +} + +void CAmCommandSender::cbRemovedSink(const am_sinkID_t sink) +{ + CALL_ALL_INTERFACES(cbRemovedSink(sink)) +} + +void CAmCommandSender::cbNewSource(const am_SourceType_s source) +{ + CALL_ALL_INTERFACES(cbNewSource(source)) +} + +void CAmCommandSender::cbRemovedSource(const am_sourceID_t source) +{ + CALL_ALL_INTERFACES(cbRemovedSource(source)) +} + +void CAmCommandSender::setCommandReady() +{ + mCommandReceiver->waitOnStartup(false); + + //create a list of handles + std::vector<uint16_t> listStartupHandles; + for (size_t i = 0; i < mListInterfaces.size(); i++) + { + listStartupHandles.push_back(mCommandReceiver->getStartupHandle()); + } + + //set the receiver ready to wait for replies + mCommandReceiver->waitOnStartup(true); + + //now do the calls + std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin(); + std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end(); + std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin()); + for (; iter < iterEnd; ++iter) + { + (*iter)->setCommandReady(*(handleIter++)); + } +} + +void CAmCommandSender::setCommandRundown() +{ + mCommandReceiver->waitOnRundown(false); + //create a list of handles + std::vector<uint16_t> listStartupHandles; + for (size_t i = 0; i < mListInterfaces.size(); i++) + { + listStartupHandles.push_back(mCommandReceiver->getRundownHandle()); + } + + //set the receiver ready to wait for replies + mCommandReceiver->waitOnRundown(true); + + //now do the calls + std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin(); + std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end(); + std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin()); + for (; iter < iterEnd; ++iter) + { + (*iter)->setCommandRundown(*(handleIter++)); + } +} + +void CAmCommandSender::getInterfaceVersion(std::string & version) const +{ + version = CommandVersion; +} + +am_Error_e am::CAmCommandSender::getListPlugins(std::vector<std::string> & interfaces) const +{ + interfaces = mListLibraryNames; + return (E_OK); +} + +void CAmCommandSender::cbSinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties) +{ + CALL_ALL_INTERFACES(cbSinkUpdated(sinkID,sinkClassID,listMainSoundProperties)); +} + +void CAmCommandSender::cbSourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties) +{ + CALL_ALL_INTERFACES(cbSourceUpdated(sourceID,sourceClassID,listMainSoundProperties)); +} + +void CAmCommandSender::cbSinkNotification(const am_sinkID_t sinkID, const am_NotificationPayload_s& notification) +{ + CALL_ALL_INTERFACES(cbSinkNotification(sinkID,notification)); +} + +void CAmCommandSender::cbSourceNotification(const am_sourceID_t sourceID, const am_NotificationPayload_s& notification) +{ + CALL_ALL_INTERFACES(cbSourceNotification(sourceID,notification)); +} + +void CAmCommandSender::cbSinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s& mainNotificationConfiguration) +{ + CALL_ALL_INTERFACES(cbMainSinkNotificationConfigurationChanged(sinkID,mainNotificationConfiguration)); +} + +void CAmCommandSender::cbSourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s& mainNotificationConfiguration) +{ + CALL_ALL_INTERFACES(cbMainSourceNotificationConfigurationChanged(sourceID,mainNotificationConfiguration)); +} + +void CAmCommandSender::unloadLibraries(void) +{ + std::vector<void*>::iterator iterator = mListLibraryHandles.begin(); + for (; iterator < mListLibraryHandles.end(); ++iterator) + { + dlclose(*iterator); + } + mListLibraryHandles.clear(); +} +} |