diff options
author | GENIVI Audio Manager Maintainer <genivi-maint-audiomanager@smtp1.genivi.org> | 2017-11-07 12:58:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-07 12:58:11 +0100 |
commit | d244e592eb11b0d46558da129774fe1c79c45f2b (patch) | |
tree | d72aa2ef57170b74221c137b258eeead5b8378c7 | |
parent | f620be8a774f966fbd76ca8892a39ce28037a213 (diff) | |
parent | 4090fe1d40c978d8c8cbc6a156dbfa664305163e (diff) | |
download | audiomanager-d244e592eb11b0d46558da129774fe1c79c45f2b.tar.gz |
Merge pull request #19 from JensLorenz/socket_hndl_utility_fix
Different Issues Fixed
-rw-r--r-- | AudioManagerCore/CMakeLists.txt | 2 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmCommandSender.h | 2 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmControlSender.h | 1 | ||||
-rw-r--r-- | AudioManagerCore/include/CAmRoutingSender.h | 1 | ||||
-rw-r--r-- | AudioManagerCore/include/TAmPluginTemplate.h | 91 | ||||
-rw-r--r-- | AudioManagerCore/src/CAmCommandSender.cpp | 203 | ||||
-rw-r--r-- | AudioManagerCore/src/CAmControlSender.cpp | 23 | ||||
-rw-r--r-- | AudioManagerCore/src/CAmRoutingSender.cpp | 256 | ||||
-rw-r--r-- | AudioManagerDaemon/CMakeLists.txt | 4 | ||||
-rw-r--r-- | AudioManagerUtilities/CMakeLists.txt | 6 | ||||
-rw-r--r-- | AudioManagerUtilities/include/CAmDltWrapper.h | 7 | ||||
-rw-r--r-- | AudioManagerUtilities/include/CAmSerializer.h | 1 | ||||
-rw-r--r-- | AudioManagerUtilities/include/TAmPluginTemplate.h | 40 | ||||
-rw-r--r-- | AudioManagerUtilities/src/CAmDltWrapper.cpp | 1 | ||||
-rw-r--r-- | AudioManagerUtilities/src/CAmSocketHandler.cpp | 31 | ||||
-rwxr-xr-x | CMakeLists.txt | 6 |
16 files changed, 331 insertions, 344 deletions
diff --git a/AudioManagerCore/CMakeLists.txt b/AudioManagerCore/CMakeLists.txt index 7be36e9..1d50570 100644 --- a/AudioManagerCore/CMakeLists.txt +++ b/AudioManagerCore/CMakeLists.txt @@ -89,7 +89,7 @@ install(FILES ${CMAKE_BINARY_DIR}/audiomanagercore.pc DESTINATION ${CMAKE_INSTAL configure_package_config_file ( ${CMAKE_SOURCE_DIR}/cmake/AudioManagerCoreConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/AudioManagerCoreConfig.cmake - INSTALL_DESTINATION lib/${LIB_INSTALL_SUFFIX}/cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUFFIX}/cmake PATH_VARS AUDIO_INCLUDE_FOLDER ) write_basic_package_version_file( diff --git a/AudioManagerCore/include/CAmCommandSender.h b/AudioManagerCore/include/CAmCommandSender.h index 2f7daec..c9f8fb6 100644 --- a/AudioManagerCore/include/CAmCommandSender.h +++ b/AudioManagerCore/include/CAmCommandSender.h @@ -81,7 +81,7 @@ public: friend class IAmCommandBackdoor; //this is to get access to the loaded plugins and be able to exchange the interfaces #endif private: - + void loadPlugins(const std::vector<std::string>& listOfPluginDirectories); 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. diff --git a/AudioManagerCore/include/CAmControlSender.h b/AudioManagerCore/include/CAmControlSender.h index 40ab379..2c31cf9 100644 --- a/AudioManagerCore/include/CAmControlSender.h +++ b/AudioManagerCore/include/CAmControlSender.h @@ -147,6 +147,7 @@ private: IAmControlSend* mController; //!< pointer to the ControlSend interface static CAmControlSender* mInstance; int16_t mSignal; + std::string mControlPluginFile; }; } diff --git a/AudioManagerCore/include/CAmRoutingSender.h b/AudioManagerCore/include/CAmRoutingSender.h index 8d8a063..e14dd6d 100644 --- a/AudioManagerCore/include/CAmRoutingSender.h +++ b/AudioManagerCore/include/CAmRoutingSender.h @@ -306,6 +306,7 @@ private: } }; + void loadPlugins(const std::vector<std::string>& listOfPluginDirectories); am_Handle_s createHandle(std::shared_ptr<handleDataBase> handleData, const am_Handle_e type); //!< creates a handle void unloadLibraries(void); //!< unloads all loaded plugins diff --git a/AudioManagerCore/include/TAmPluginTemplate.h b/AudioManagerCore/include/TAmPluginTemplate.h deleted file mode 100644 index f000fbe..0000000 --- a/AudioManagerCore/include/TAmPluginTemplate.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * SPDX license identifier: MPL-2.0 - * - * Copyright (C) 2012, BMW AG - * - * This file is part of GENIVI Project AudioManager. - * - * Contributions are licensed to the GENIVI Alliance under one or more - * Contribution License Agreements. - * - * \copyright - * This Source Code Form is subject to the terms of the - * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with - * this file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * - * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012 - * - * \file TAmPluginTemplate.h - * For further information see http://www.genivi.org/. - * - */ - -#ifndef PLUGINTEMPLATE_H_ -#define PLUGINTEMPLATE_H_ - -#include <dlfcn.h> -#include <libgen.h> -#include "CAmDltWrapper.h" - -namespace am -{ - -/** - * * This template tries to load a library and cast to a class - * @param libname the full path to the library to be loaded - * @param libraryHandle the handle to the library that gets returned - * @return returns the pointer to the class to be loaded - */ -template<class T> T* getCreateFunction(const std::string& libname, void*& libraryHandle) -{ - - logInfo("getCreateFunction : Trying to load library with name: ",libname); - - // cut off directories - char* fileWithPath = const_cast<char*>(libname.c_str()); - std::string libFileName = basename(fileWithPath); - - // cut off "lib" in front and cut off .so end" - std::string createFunctionName = libFileName.substr(3, libFileName.length() - 6) + "Factory"; - // open library - dlerror(); // Clear any existing error - libraryHandle = dlopen(libname.c_str(), RTLD_LAZY ); - const char* dlopen_error = dlerror(); - if (!libraryHandle || dlopen_error) - { - logError("getCreateFunction : dlopen failed",dlopen_error); - return (0); - } - - // get entry point from shared lib - dlerror(); // Clear any existing error - - union - { - void* voidPointer; - T* typedPointer; - } functionPointer; - - // Note: direct cast is not allowed by ISO C++. e.g. - // T* createFunction = reinterpret_cast<T*>(dlsym(libraryHandle, createFunctionName.c_str())); - // compiler warning: "forbids casting between pointer-to-function and pointer-to-object" - - functionPointer.voidPointer = dlsym(libraryHandle, createFunctionName.c_str()); - T* createFunction = functionPointer.typedPointer; - - const char* dlsym_error = dlerror(); - if (!createFunction || dlsym_error) - { - logError("getCreateFunction: Failed to load shared lib entry point",dlsym_error); - } - else - { - logInfo("getCreateFunction : loaded successfully plugin", createFunctionName); - } - return (createFunction); -} - -} - -#endif /* PLUGINTEMPLATE_H_ */ diff --git a/AudioManagerCore/src/CAmCommandSender.cpp b/AudioManagerCore/src/CAmCommandSender.cpp index 6626bdb..ded3247 100644 --- a/AudioManagerCore/src/CAmCommandSender.cpp +++ b/AudioManagerCore/src/CAmCommandSender.cpp @@ -59,6 +59,100 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD mCommandReceiver(), mSerializer(iSocketHandler) { + loadPlugins(listOfPluginDirectories); + + dboNewMainConnection = [&](const am_MainConnectionType_s& mainConnection) { + mSerializer.asyncCall(this, &CAmCommandSender::cbNewMainConnection, mainConnection); + }; + dboRemovedMainConnection = [&](const am_mainConnectionID_t mainConnection) { + mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedMainConnection, mainConnection); + }; + dboNewSink = [&](const am_Sink_s& sink) { + if (sink.visible) + { + am_SinkType_s s; + s.availability = sink.available; + s.muteState = sink.muteState; + s.name = sink.name; + s.sinkClassID = sink.sinkClassID; + s.sinkID = sink.sinkID; + s.volume = sink.mainVolume; + typedef void(CAmCommandSender::*TMeth)(am::am_SinkType_s); + mSerializer.asyncCall<CAmCommandSender, TMeth, am::am_SinkType_s>(this, &CAmCommandSender::cbNewSink, s); + } + }; + dboNewSource = [&](const am_Source_s& source) { + if (source.visible) + { + am_SourceType_s s; + s.availability = source.available; + s.name = source.name; + s.sourceClassID = source.sourceClassID; + s.sourceID = source.sourceID; + typedef void(CAmCommandSender::*TMeth)(am::am_SourceType_s); + mSerializer.asyncCall<CAmCommandSender, TMeth, am::am_SourceType_s>(this, &CAmCommandSender::cbNewSource, s); + } + }; + + dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) { + if (visible) + mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSink, sinkID); + }; + dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) { + if (visible) + mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSource, sourceID); + }; + dboNumberOfSinkClassesChanged = [&]() { + mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSinkClassesChanged); + }; + dboNumberOfSourceClassesChanged = [&]() { + mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSourceClassesChanged); + }; + dboMainConnectionStateChanged = [&](const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState) { + mSerializer.asyncCall(this, &CAmCommandSender::cbMainConnectionStateChanged, connectionID, connectionState); + }; + dboMainSinkSoundPropertyChanged = [&](const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty) { + mSerializer.asyncCall(this, &CAmCommandSender::cbMainSinkSoundPropertyChanged, sinkID, SoundProperty); + }; + dboMainSourceSoundPropertyChanged = [&](const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty) { + mSerializer.asyncCall(this, &CAmCommandSender::cbMainSourceSoundPropertyChanged, sourceID, SoundProperty); + }; + dboSinkAvailabilityChanged = [&](const am_sinkID_t sinkID, const am_Availability_s & availability) { + mSerializer.asyncCall(this, &CAmCommandSender::cbSinkAvailabilityChanged, sinkID, availability); + }; + dboSourceAvailabilityChanged = [&](const am_sourceID_t sourceID, const am_Availability_s & availability) { + mSerializer.asyncCall(this, &CAmCommandSender::cbSourceAvailabilityChanged, sourceID, availability); + }; + dboVolumeChanged = [&](const am_sinkID_t sinkID, const am_mainVolume_t volume) { + mSerializer.asyncCall(this, &CAmCommandSender::cbVolumeChanged, sinkID, volume); + }; + dboSinkMuteStateChanged = [&](const am_sinkID_t sinkID, const am_MuteState_e muteState) { + mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState); + }; + dboSystemPropertyChanged = [&](const am_SystemProperty_s& SystemProperty) { + mSerializer.asyncCall(this, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty); + }; + dboTimingInformationChanged = [&](const am_mainConnectionID_t mainConnection, const am_timeSync_t time) { + mSerializer.asyncCall(this, &CAmCommandSender::cbTimingInformationChanged, mainConnection, time); + }; + dboSinkUpdated = [&](const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) { + if (visible) + mSerializer.asyncCall(this, &CAmCommandSender::cbSinkUpdated, sinkID, sinkClassID, listMainSoundProperties); + }; + dboSourceUpdated = [&](const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) { + if (visible) + mSerializer.asyncCall(this, &CAmCommandSender::cbSinkUpdated, sourceID, sourceClassID, listMainSoundProperties); + }; + dboSinkMainNotificationConfigurationChanged = [&](const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) { + mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMainNotificationConfigurationChanged, sinkID, mainNotificationConfiguration); + }; + dboSourceMainNotificationConfigurationChanged = [&](const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) { + mSerializer.asyncCall(this, &CAmCommandSender::cbSourceMainNotificationConfigurationChanged, sourceID, mainNotificationConfiguration); + }; +} + +void CAmCommandSender::loadPlugins(const std::vector<std::string>& listOfPluginDirectories) +{ if (listOfPluginDirectories.empty()) { logError(__METHOD_NAME__,"List of commandplugins is empty"); @@ -93,16 +187,18 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD 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 (entryType == DT_UNKNOWN) + { + struct stat buf; - if (stat(fullName.c_str(), &buf)) { - logInfo(__METHOD_NAME__,"Failed to stat file: ", entryName, errno); - continue; - } + if (stat(fullName.c_str(), &buf)) + { + logInfo(__METHOD_NAME__,"Failed to stat file: ", entryName, errno); + continue; + } - regularFile = S_ISREG(buf.st_mode); - } + regularFile = S_ISREG(buf.st_mode); + } if (regularFile && sharedLibExtension) { @@ -147,8 +243,6 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD 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))) { @@ -161,95 +255,6 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD mListLibraryHandles.push_back(tempLibHandle); mListLibraryNames.push_back(iter->c_str()); } - - dboNewMainConnection = [&](const am_MainConnectionType_s& mainConnection) { - mSerializer.asyncCall(this, &CAmCommandSender::cbNewMainConnection, mainConnection); - }; - dboRemovedMainConnection = [&](const am_mainConnectionID_t mainConnection) { - mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedMainConnection, mainConnection); - }; - dboNewSink = [&](const am_Sink_s& sink) { - if (sink.visible) - { - am_SinkType_s s; - s.availability = sink.available; - s.muteState = sink.muteState; - s.name = sink.name; - s.sinkClassID = sink.sinkClassID; - s.sinkID = sink.sinkID; - s.volume = sink.mainVolume; - typedef void(CAmCommandSender::*TMeth)(am::am_SinkType_s) ; - mSerializer.asyncCall<CAmCommandSender, TMeth, am::am_SinkType_s>(this, &CAmCommandSender::cbNewSink, s); - } - }; - dboNewSource = [&](const am_Source_s& source) { - if (source.visible) - { - am_SourceType_s s; - s.availability = source.available; - s.name = source.name; - s.sourceClassID = source.sourceClassID; - s.sourceID = source.sourceID; - typedef void(CAmCommandSender::*TMeth)(am::am_SourceType_s) ; - mSerializer.asyncCall<CAmCommandSender, TMeth, am::am_SourceType_s>(this, &CAmCommandSender::cbNewSource, s); - } - }; - - dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) { - if (visible) - mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSink, sinkID); - }; - dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) { - if (visible) - mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSource, sourceID); - }; - dboNumberOfSinkClassesChanged = [&]() { - mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSinkClassesChanged); - }; - dboNumberOfSourceClassesChanged = [&]() { - mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSourceClassesChanged); - }; - dboMainConnectionStateChanged = [&](const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState) { - mSerializer.asyncCall(this, &CAmCommandSender::cbMainConnectionStateChanged, connectionID, connectionState); - }; - dboMainSinkSoundPropertyChanged = [&](const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty) { - mSerializer.asyncCall(this, &CAmCommandSender::cbMainSinkSoundPropertyChanged, sinkID, SoundProperty); - }; - dboMainSourceSoundPropertyChanged = [&](const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty) { - mSerializer.asyncCall(this, &CAmCommandSender::cbMainSourceSoundPropertyChanged, sourceID, SoundProperty); - }; - dboSinkAvailabilityChanged = [&](const am_sinkID_t sinkID, const am_Availability_s & availability) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSinkAvailabilityChanged, sinkID, availability); - }; - dboSourceAvailabilityChanged = [&](const am_sourceID_t sourceID, const am_Availability_s & availability) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSourceAvailabilityChanged, sourceID, availability); - }; - dboVolumeChanged = [&](const am_sinkID_t sinkID, const am_mainVolume_t volume) { - mSerializer.asyncCall(this, &CAmCommandSender::cbVolumeChanged, sinkID, volume); - }; - dboSinkMuteStateChanged = [&](const am_sinkID_t sinkID, const am_MuteState_e muteState) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState); - }; - dboSystemPropertyChanged = [&](const am_SystemProperty_s& SystemProperty) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty); - }; - dboTimingInformationChanged = [&](const am_mainConnectionID_t mainConnection, const am_timeSync_t time) { - mSerializer.asyncCall(this, &CAmCommandSender::cbTimingInformationChanged, mainConnection, time); - }; - dboSinkUpdated = [&](const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) { - if (visible) - mSerializer.asyncCall(this, &CAmCommandSender::cbSinkUpdated, sinkID, sinkClassID, listMainSoundProperties); - }; - dboSourceUpdated = [&](const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) { - if (visible) - mSerializer.asyncCall(this, &CAmCommandSender::cbSinkUpdated, sourceID, sourceClassID, listMainSoundProperties); - }; - dboSinkMainNotificationConfigurationChanged = [&](const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMainNotificationConfigurationChanged, sinkID, mainNotificationConfiguration); - }; - dboSourceMainNotificationConfigurationChanged = [&](const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSourceMainNotificationConfigurationChanged, sourceID, mainNotificationConfiguration); - }; } CAmCommandSender::~CAmCommandSender() diff --git a/AudioManagerCore/src/CAmControlSender.cpp b/AudioManagerCore/src/CAmControlSender.cpp index a12373c..17a9b2b 100644 --- a/AudioManagerCore/src/CAmControlSender.cpp +++ b/AudioManagerCore/src/CAmControlSender.cpp @@ -115,7 +115,7 @@ CAmControlSender::CAmControlSender(std::string controlPluginFile,CAmSocketHandle createFunc = getCreateFunction<IAmControlSend*()>(controlPluginFile, mlibHandle); assert(createFunc!=NULL); mController = createFunc(); - + mControlPluginFile = controlPluginFile; //check libversion std::string version, cVersion(ControlVersion); mController->getInterfaceVersion(version); @@ -153,10 +153,23 @@ CAmControlSender::CAmControlSender(std::string controlPluginFile,CAmSocketHandle CAmControlSender::~CAmControlSender() { - close(mPipe[0]); - close(mPipe[1]); - //if (mlibHandle) - // dlclose(mlibHandle); + close(mPipe[0]); + close(mPipe[1]); + + if (mlibHandle) + { + void (*destroyFunc)(IAmControlSend*); + destroyFunc = getDestroyFunction<void(IAmControlSend*)>(mControlPluginFile, mlibHandle); + if (destroyFunc) + { + destroyFunc(mController); + } + else + { + logError("CAmControlSender Dtor: destroyFunc is invalid or not found"); + } + dlclose(mlibHandle); + } } am_Error_e CAmControlSender::hookUserConnectionRequest(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t & mainConnectionID) diff --git a/AudioManagerCore/src/CAmRoutingSender.cpp b/AudioManagerCore/src/CAmRoutingSender.cpp index 9cc013d..603d7b3 100644 --- a/AudioManagerCore/src/CAmRoutingSender.cpp +++ b/AudioManagerCore/src/CAmRoutingSender.cpp @@ -59,146 +59,154 @@ CAmRoutingSender::CAmRoutingSender( mpRoutingReceiver(), // mpDatabaseHandler(databaseHandler) { - if (listOfPluginDirectories.empty()) { - logError(__METHOD_NAME__,"List of routingplugins is empty"); - } - - std::vector<std::string> sharedLibraryNameList; - std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin(); - std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end(); - - // search communicator plugins in configured directories - for (; dirIter < dirIterEnd; ++dirIter) - { - const char* directoryName = dirIter->c_str(); - logInfo(__METHOD_NAME__,"Searching for HookPlugins in", directoryName); - DIR *directory = opendir(directoryName); - - if (!directory) - { - logError(__METHOD_NAME__,"Error opening directory: ", directoryName); - continue; - } - - // iterate content of directory - struct dirent *itemInDirectory = 0; - while ((itemInDirectory = readdir(directory))) - { - unsigned char entryType = itemInDirectory->d_type; - std::string entryName = itemInDirectory->d_name; - std::string fullName = *dirIter + "/" + entryName; - - bool regularFile = (entryType == DT_REG || entryType == DT_LNK); - bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1)); + loadPlugins(listOfPluginDirectories); + + dboNewSink = [&](const am_Sink_s& sink) { + addSinkLookup(sink); + }; + dboNewSource = [&](const am_Source_s& source) { + addSourceLookup(source); + }; + dboNewDomain = [&](const am_Domain_s& domain) { + addDomainLookup(domain); + }; + //todo: newGateway implement something + //todo: newConverter implement something + dboNewCrossfader = [&](const am_Crossfader_s& crossfader) { + addCrossfaderLookup(crossfader); + }; + dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) { + removeSinkLookup(sinkID); + }; + dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) { + removeSourceLookup(sourceID); + }; + dboRemoveDomain = [&](const am_domainID_t domainID) { + removeDomainLookup(domainID); + }; + //todo: removeGateway implement something + //todo: removeConverter implement something + dboRemoveCrossfader = [&](const am_crossfaderID_t crossfaderID) { + removeCrossfaderLookup(crossfaderID); + }; +} - // Handle cases where readdir() could not determine the file type - if (entryType == DT_UNKNOWN) { - struct stat buf; +void CAmRoutingSender::loadPlugins(const std::vector<std::string>& listOfPluginDirectories) +{ + if (listOfPluginDirectories.empty()) + { + logError(__METHOD_NAME__,"List of routingplugins is empty"); + } - if (stat(fullName.c_str(), &buf)) { - logInfo(__METHOD_NAME__,"Failed to stat file: ", entryName, errno); - continue; - } + std::vector<std::string> sharedLibraryNameList; + std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin(); + std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end(); - regularFile = S_ISREG(buf.st_mode); - } + // search communicator plugins in configured directories + for (; dirIter < dirIterEnd; ++dirIter) + { + const char* directoryName = dirIter->c_str(); + logInfo(__METHOD_NAME__,"Searching for HookPlugins in", directoryName); + DIR *directory = opendir(directoryName); - if (regularFile && sharedLibExtension) - { - logInfo(__METHOD_NAME__,"adding file: ", entryName); - std::string name(directoryName); - sharedLibraryNameList.push_back(name + "/" + entryName); - } - else - { - logInfo(__METHOD_NAME__, "plugin search ignoring file :", entryName); - } - } + if (!directory) + { + logError(__METHOD_NAME__,"Error opening directory: ", directoryName); + continue; + } - closedir(directory); - } + // 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(__METHOD_NAME__,"Failed to stat file: ", entryName, errno); + continue; + } + + regularFile = S_ISREG(buf.st_mode); + } + + if (regularFile && sharedLibExtension) + { + logInfo(__METHOD_NAME__,"adding file: ", entryName); + std::string name(directoryName); + sharedLibraryNameList.push_back(name + "/" + entryName); + } + else + { + logInfo(__METHOD_NAME__, "plugin search ignoring file :", entryName); + } + } - // iterate all communicator plugins and start them - std::vector<std::string>::iterator iter = sharedLibraryNameList.begin(); - std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end(); + closedir(directory); + } - for (; iter != iterEnd; ++iter) - { - logInfo(__METHOD_NAME__,"try loading: ", *iter); + // iterate all communicator plugins and start them + std::vector<std::string>::iterator iter = sharedLibraryNameList.begin(); + std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end(); - IAmRoutingSend* (*createFunc)(); - void* tempLibHandle = NULL; - createFunc = getCreateFunction<IAmRoutingSend*()>(*iter, tempLibHandle); + for (; iter != iterEnd; ++iter) + { + logInfo(__METHOD_NAME__,"try loading: ", *iter); - if (!createFunc) - { - logError(__METHOD_NAME__,"Entry point of RoutingPlugin not found"); - continue; - } + IAmRoutingSend* (*createFunc)(); + void* tempLibHandle = NULL; + createFunc = getCreateFunction<IAmRoutingSend*()>(*iter, tempLibHandle); - IAmRoutingSend* router = createFunc(); + if (!createFunc) + { + logError(__METHOD_NAME__,"Entry point of RoutingPlugin not found"); + continue; + } - if (!router) - { - logError(__METHOD_NAME__,"initialization of plugin ",*iter,"failed. Entry Function not callable"); - dlclose(tempLibHandle); - continue; - } + IAmRoutingSend* router = createFunc(); - InterfaceNamePairs routerInterface; - routerInterface.routingInterface = router; + if (!router) + { + logError(__METHOD_NAME__,"initialization of plugin ",*iter,"failed. Entry Function not callable"); + dlclose(tempLibHandle); + continue; + } - //check libversion - std::string version, cVersion(RoutingVersion); - router->getInterfaceVersion(version); - uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion; - std::istringstream(version.substr(0, 1)) >> majorVersion; - std::istringstream(version.substr(2, 1)) >> minorVersion; - std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion; - std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion; + InterfaceNamePairs routerInterface; + routerInterface.routingInterface = router; - if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion))) - { - logError(__METHOD_NAME__,"Routing initialization failed. Version of Interface to old"); - dlclose(tempLibHandle); - continue; - } + //check libversion + std::string version, cVersion(RoutingVersion); + router->getInterfaceVersion(version); + uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion; + std::istringstream(version.substr(0, 1)) >> majorVersion; + std::istringstream(version.substr(2, 1)) >> minorVersion; + std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion; + std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion; - //here, the busname is saved together with the interface. Later The domains will register with the name and sinks, sources etc with the domain.... - router->returnBusName(routerInterface.busName); - assert(!routerInterface.busName.empty()); - mListInterfaces.push_back(routerInterface); - mListLibraryHandles.push_back(tempLibHandle); - } + if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion))) + { + logError(__METHOD_NAME__,"Routing initialization failed. Version of Interface to old"); + dlclose(tempLibHandle); + continue; + } - dboNewSink = [&](const am_Sink_s& sink) { - addSinkLookup(sink); - }; - dboNewSource = [&](const am_Source_s& source) { - addSourceLookup(source); - }; - dboNewDomain = [&](const am_Domain_s& domain) { - addDomainLookup(domain); - }; - //todo: newGateway implement something - //todo: newConverter implement something - dboNewCrossfader = [&](const am_Crossfader_s& crossfader) { - addCrossfaderLookup(crossfader); - }; - dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) { - removeSinkLookup(sinkID); - }; - dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) { - removeSourceLookup(sourceID); - }; - dboRemoveDomain = [&](const am_domainID_t domainID) { - removeDomainLookup(domainID); - }; - //todo: removeGateway implement something - //todo: removeConverter implement something - dboRemoveCrossfader = [&](const am_crossfaderID_t crossfaderID) { - removeCrossfaderLookup(crossfaderID); - }; + //here, the busname is saved together with the interface. Later The domains will register with the name and sinks, sources etc with the domain.... + router->returnBusName(routerInterface.busName); + assert(!routerInterface.busName.empty()); + mListInterfaces.push_back(routerInterface); + mListLibraryHandles.push_back(tempLibHandle); + } } CAmRoutingSender::~CAmRoutingSender() diff --git a/AudioManagerDaemon/CMakeLists.txt b/AudioManagerDaemon/CMakeLists.txt index 9aa0754..786dd2d 100644 --- a/AudioManagerDaemon/CMakeLists.txt +++ b/AudioManagerDaemon/CMakeLists.txt @@ -42,12 +42,12 @@ TARGET_LINK_LIBRARIES(AudioManager AudioManagerCore ${AUDIO_MANAGER_CORE_LIBS}) ADD_DEPENDENCIES(AudioManager AudioManagerCore) INSTALL(TARGETS AudioManager - RUNTIME DESTINATION bin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ COMPONENT bin) INSTALL(DIRECTORY "${AUDIO_INCLUDE_FOLDER}/" - DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${LIB_INSTALL_SUFFIX} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${LIB_INSTALL_SUFFIX} COMPONENT dev) diff --git a/AudioManagerUtilities/CMakeLists.txt b/AudioManagerUtilities/CMakeLists.txt index 6e9a06f..7c502c5 100644 --- a/AudioManagerUtilities/CMakeLists.txt +++ b/AudioManagerUtilities/CMakeLists.txt @@ -17,7 +17,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.0) -PROJECT(AudioManagerUtilities LANGUAGES CXX VERSION ${DAEMONVERSION}) +PROJECT(AudioManagerUtilities LANGUAGES C CXX VERSION ${DAEMONVERSION}) + +FIND_PACKAGE(Threads REQUIRED) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") @@ -141,7 +143,7 @@ LINK_DIRECTORIES(${AUDIOMANAGER_UTILITIES_LIB_DIRECTORIES}) ADD_LIBRARY(AudioManagerUtilities ${LIBRARY_TYPE} ${AUDIO_MANAGER_UTILITIES_SRCS_CXX}) -TARGET_LINK_LIBRARIES(AudioManagerUtilities ${AUDIO_MANAGER_UTILITIES_LIBS}) +TARGET_LINK_LIBRARIES(AudioManagerUtilities ${AUDIO_MANAGER_UTILITIES_LIBS} ${CMAKE_THREAD_LIBS_INIT}) set_target_properties(AudioManagerUtilities PROPERTIES VERSION ${AudioManagerUtilities_VERSION} SOVERSION ${AudioManagerUtilities_VERSION_MAJOR}) diff --git a/AudioManagerUtilities/include/CAmDltWrapper.h b/AudioManagerUtilities/include/CAmDltWrapper.h index 8c5678e..79df911 100644 --- a/AudioManagerUtilities/include/CAmDltWrapper.h +++ b/AudioManagerUtilities/include/CAmDltWrapper.h @@ -162,11 +162,14 @@ public: { #ifdef WITH_DLT #ifdef DLT_IS_LOG_LEVEL_ENABLED - return (dlt_user_is_logLevel_enabled(&mDltContext, logLevel) == DLT_RETURN_TRUE); + if (mlogDestination == logDestination::DAEMON) + { + return (dlt_user_is_logLevel_enabled(&mDltContext, logLevel) == DLT_RETURN_TRUE); + } #else (void)logLevel; - return true; #endif + return true; #else return (logLevel <= mDltContext.log_level_user); #endif diff --git a/AudioManagerUtilities/include/CAmSerializer.h b/AudioManagerUtilities/include/CAmSerializer.h index 6bd6143..8abdf90 100644 --- a/AudioManagerUtilities/include/CAmSerializer.h +++ b/AudioManagerUtilities/include/CAmSerializer.h @@ -18,7 +18,6 @@ #ifndef CAMSERIALIZER_H_ #define CAMSERIALIZER_H_ -#include <pthread.h> #include <deque> #include <cassert> #include <memory> diff --git a/AudioManagerUtilities/include/TAmPluginTemplate.h b/AudioManagerUtilities/include/TAmPluginTemplate.h index f000fbe..95523f1 100644 --- a/AudioManagerUtilities/include/TAmPluginTemplate.h +++ b/AudioManagerUtilities/include/TAmPluginTemplate.h @@ -86,6 +86,46 @@ template<class T> T* getCreateFunction(const std::string& libname, void*& librar return (createFunction); } +/** + * * This template tries to destroy + * @param libname the full path to the library to be loaded + * + */ +template<class T> T* getDestroyFunction(const std::string& libname,void* libraryHandle) +{ + logInfo("destroy : Trying to destroy : ",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 destroyFunctionName = "destroy" + libFileName.substr(3, libFileName.length() - 6); + + // get entry point from shared lib + dlerror(); // Clear any existing error + union + { + void* voidPointer; + T* typedPointer; + } functionPointer; + + functionPointer.voidPointer = dlsym(libraryHandle, destroyFunctionName.c_str()); + T* destroyFunction = functionPointer.typedPointer; + + const char* dlsym_error = dlerror(); + if (!destroyFunction || dlsym_error) + { + logError("getDestroyFunction: Failed to load shared lib entry point function name=", + destroyFunctionName, "error=",dlsym_error); + } + else + { + logInfo("getDestroyFunction: loaded successfully plugin", destroyFunctionName); + } + return (destroyFunction); +} + } #endif /* PLUGINTEMPLATE_H_ */ diff --git a/AudioManagerUtilities/src/CAmDltWrapper.cpp b/AudioManagerUtilities/src/CAmDltWrapper.cpp index 37a5ff0..742b396 100644 --- a/AudioManagerUtilities/src/CAmDltWrapper.cpp +++ b/AudioManagerUtilities/src/CAmDltWrapper.cpp @@ -29,6 +29,7 @@ #include <string.h> #include <chrono> #include <ctime> +#include <unistd.h> namespace am { diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp index 7b0fc5d..fad60e5 100644 --- a/AudioManagerUtilities/src/CAmSocketHandler.cpp +++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp @@ -69,10 +69,13 @@ CAmSocketHandler::CAmSocketHandler() : short event = 0; sh_pollHandle_t handle; event |= POLLIN; - if (addFDPoll(mPipe[0], event, NULL, [](const pollfd pollfd, const sh_pollHandle_t, void*) - {}, [](const sh_pollHandle_t, void*) - { return (false);}, NULL, NULL, handle) != E_OK) + if (addFDPoll(mPipe[0], event, NULL, + [](const pollfd, const sh_pollHandle_t, void*){}, + [](const sh_pollHandle_t, void*) { return (false); }, + NULL, NULL, handle) != E_OK) + { mInternalCodes |= internal_codes_e::FD_ERROR; + } } CAmSocketHandler::~CAmSocketHandler() @@ -99,10 +102,8 @@ void CAmSocketHandler::start_listenting() #endif timespec buffertime; - std::list<sh_poll_s> listPoll; VectorListPoll_t cloneListPoll; VectorListPoll_t::iterator listmPollIt; - VectorListPollfd_t::iterator itMfdPollingArray; VectorListPollfd_t fdPollingArray; //!<the polling array for ppoll auto preparePollfd = [&](const sh_poll_s& row) @@ -151,19 +152,23 @@ void CAmSocketHandler::start_listenting() if (pollStatus != 0) //only check filedescriptors if there was a change { + std::list<sh_poll_s> listPoll; //todo: here could be a timer that makes sure naughty plugins return! - listPoll.clear(); //stage 0+1, call firedCB - for (itMfdPollingArray = fdPollingArray.begin(); itMfdPollingArray != fdPollingArray.end(); itMfdPollingArray++) + listmPollIt = cloneListPoll.begin(); + for (auto it : fdPollingArray) { - if (CAmSocketHandler::eventFired(*itMfdPollingArray)) - { - listmPollIt = cloneListPoll.begin(); - std::advance(listmPollIt, std::distance(fdPollingArray.begin(), itMfdPollingArray)); - + if (CAmSocketHandler::eventFired(it)) + { + listmPollIt->pollfdValue.revents = it.revents; listPoll.push_back(*listmPollIt); CAmSocketHandler::fire(*listmPollIt); } + else + { + listmPollIt->pollfdValue.revents = 0; + } + listmPollIt++; } //stage 2, lets ask around if some dispatching is necessary, the ones who need stay on the list @@ -395,7 +400,7 @@ am::am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmS { std::function<void(const sh_pollHandle_t handle, void* userData)> prepareCB; //preperation callback - std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback + std::function<void(const pollfd poll, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback std::function<bool(const sh_pollHandle_t handle, void* userData)> checkCB; //check callback std::function<bool(const sh_pollHandle_t handle, void* userData)> dispatchCB; //check callback diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c70c61..38d1a68 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) include ( MacroVersionFromGit ) include ( MacroInterfaceVersions ) -project(AudioManager LANGUAGES CXX VERSION ${DAEMONVERSION}) +project(AudioManager LANGUAGES C CXX VERSION ${DAEMONVERSION}) include ( CMakeDependentOption ) include ( CMakePackageConfigHelpers ) @@ -76,13 +76,13 @@ set(DYNAMIC_ID_BOUNDARY 101 set(LIB_INSTALL_SUFFIX "audiomanager" CACHE STRINGS "The suffix used for installation of the plugins") -set(TEST_EXECUTABLE_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/bin +set(TEST_EXECUTABLE_INSTALL_PATH ${CMAKE_INSTALL_BINDIR} CACHE STRINGS "The test binaries will be installed here") set(DOC_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/doc/AudioManager CACHE STRINGS "The doxygen documentation will be placed here") -set(AM_SHARE_FOLDER ${CMAKE_INSTALL_PREFIX}/share/audiomanager +set(AM_SHARE_FOLDER ${CMAKE_INSTALL_DATAROOTDIR}/audiomanager CACHE STRINGS "The share folder for the AM. Some DBus xmls will be placed here and so on") set(AM_MAP_CAPACITY 10 |