From 3e9f7977dc599b6a91e875c8239480f212a4cd3a Mon Sep 17 00:00:00 2001 From: Kapildev Patel Date: Mon, 24 Apr 2017 18:58:31 +0900 Subject: AM: Destroy plugin implementation. With these changes AudioManager would call destroy function of the controller plugin at the time of shutdown. Signed-off-by: Kapildev Patel --- AudioManagerCore/include/CAmControlSender.h | 1 + AudioManagerCore/include/TAmPluginTemplate.h | 91 ----------------------- AudioManagerCore/src/CAmControlSender.cpp | 16 +++- AudioManagerUtilities/include/TAmPluginTemplate.h | 34 +++++++++ 4 files changed, 48 insertions(+), 94 deletions(-) delete mode 100644 AudioManagerCore/include/TAmPluginTemplate.h 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/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 -#include -#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 T* getCreateFunction(const std::string& libname, void*& libraryHandle) -{ - - logInfo("getCreateFunction : Trying to load library with name: ",libname); - - // cut off directories - char* fileWithPath = const_cast(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(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/CAmControlSender.cpp b/AudioManagerCore/src/CAmControlSender.cpp index a12373c..ce5d132 100644 --- a/AudioManagerCore/src/CAmControlSender.cpp +++ b/AudioManagerCore/src/CAmControlSender.cpp @@ -115,7 +115,7 @@ CAmControlSender::CAmControlSender(std::string controlPluginFile,CAmSocketHandle createFunc = getCreateFunction(controlPluginFile, mlibHandle); assert(createFunc!=NULL); mController = createFunc(); - + mControlPluginFile = controlPluginFile; //check libversion std::string version, cVersion(ControlVersion); mController->getInterfaceVersion(version); @@ -155,8 +155,18 @@ CAmControlSender::~CAmControlSender() { close(mPipe[0]); close(mPipe[1]); - //if (mlibHandle) - // dlclose(mlibHandle); + void (*destroyFunc)(IAmControlSend*); + destroyFunc = getDestroyFunction(mControlPluginFile,mlibHandle); + assert(destroyFunc!=NULL); + destroyFunc(mController); + if(mlibHandle) + { + dlclose(mlibHandle); + } + else + { + logError("CAmControlSender Dtor: mlibHandle is invalid"); + } } am_Error_e CAmControlSender::hookUserConnectionRequest(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t & mainConnectionID) diff --git a/AudioManagerUtilities/include/TAmPluginTemplate.h b/AudioManagerUtilities/include/TAmPluginTemplate.h index f000fbe..8034497 100644 --- a/AudioManagerUtilities/include/TAmPluginTemplate.h +++ b/AudioManagerUtilities/include/TAmPluginTemplate.h @@ -86,6 +86,40 @@ template 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 T* getDestroyFunction(const std::string& libname,void* libraryHandle) +{ + logInfo("destroy : Trying to destroy : ",libname); + // cut off directories + char* fileWithPath = const_cast(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); + 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_ */ -- cgit v1.2.1 From 4bfe4632624bc3ee13fa85f0ffdc23d7618e65e3 Mon Sep 17 00:00:00 2001 From: Guerra Mattia Date: Fri, 19 May 2017 14:39:35 +0200 Subject: CMake: Use GNUInstalDirs destinations Replace hardcoded "lib" with ${CMAKE_INSTALL_LIBDIR} to provide multilib support. Signed-off-by: Frederik Sdun Signed-off-by: Mikhail Durnev --- AudioManagerCore/CMakeLists.txt | 2 +- AudioManagerDaemon/CMakeLists.txt | 4 ++-- CMakeLists.txt | 4 ++-- 3 files changed, 5 insertions(+), 5 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/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/CMakeLists.txt b/CMakeLists.txt index 5c70c61..9f3bbe7 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 -- cgit v1.2.1 From 31922cca3a063b2f413967312ae1f927d624a1ed Mon Sep 17 00:00:00 2001 From: Jens Lorenz Date: Tue, 6 Jun 2017 10:47:05 +0200 Subject: AMUtil: Fix for destroy controller on rundown On rundown the controller will be unloaded. In case the controller wasn't loaded successfully or the controller doesn't implement the destroy function the rundown of AudioManager crashed. Signed-off-by: Jens Lorenz --- AudioManagerCore/src/CAmControlSender.cpp | 25 +++++++++++++---------- AudioManagerUtilities/include/TAmPluginTemplate.h | 6 ++++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/AudioManagerCore/src/CAmControlSender.cpp b/AudioManagerCore/src/CAmControlSender.cpp index ce5d132..17a9b2b 100644 --- a/AudioManagerCore/src/CAmControlSender.cpp +++ b/AudioManagerCore/src/CAmControlSender.cpp @@ -153,20 +153,23 @@ CAmControlSender::CAmControlSender(std::string controlPluginFile,CAmSocketHandle CAmControlSender::~CAmControlSender() { - close(mPipe[0]); - close(mPipe[1]); - void (*destroyFunc)(IAmControlSend*); - destroyFunc = getDestroyFunction(mControlPluginFile,mlibHandle); - assert(destroyFunc!=NULL); - destroyFunc(mController); - if(mlibHandle) + close(mPipe[0]); + close(mPipe[1]); + + if (mlibHandle) { + void (*destroyFunc)(IAmControlSend*); + destroyFunc = getDestroyFunction(mControlPluginFile, mlibHandle); + if (destroyFunc) + { + destroyFunc(mController); + } + else + { + logError("CAmControlSender Dtor: destroyFunc is invalid or not found"); + } dlclose(mlibHandle); } - else - { - logError("CAmControlSender Dtor: mlibHandle is invalid"); - } } am_Error_e CAmControlSender::hookUserConnectionRequest(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t & mainConnectionID) diff --git a/AudioManagerUtilities/include/TAmPluginTemplate.h b/AudioManagerUtilities/include/TAmPluginTemplate.h index 8034497..95523f1 100644 --- a/AudioManagerUtilities/include/TAmPluginTemplate.h +++ b/AudioManagerUtilities/include/TAmPluginTemplate.h @@ -94,19 +94,25 @@ template T* getCreateFunction(const std::string& libname, void*& librar template T* getDestroyFunction(const std::string& libname,void* libraryHandle) { logInfo("destroy : Trying to destroy : ",libname); + // cut off directories char* fileWithPath = const_cast(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) { -- cgit v1.2.1 From 50bbb68460af25dcba4110b11b4f0bf61d6e111a Mon Sep 17 00:00:00 2001 From: Jens Lorenz Date: Thu, 22 Jun 2017 10:56:20 +0200 Subject: CMake: Add pthread support If DLT is turned off, CAmDltWrapper needs linkage to pthread. Furthermore, CAmSerializer doesn't need to #include pthread. Signed-off-by: Guerra Mattia --- AudioManagerUtilities/CMakeLists.txt | 6 ++++-- AudioManagerUtilities/include/CAmSerializer.h | 1 - AudioManagerUtilities/src/CAmDltWrapper.cpp | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) 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/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 #include #include #include 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 #include #include +#include namespace am { -- cgit v1.2.1 From 43c445e3ea9a4290e4c60d427bf6435e91bafa65 Mon Sep 17 00:00:00 2001 From: Guerra Mattia Date: Wed, 23 Aug 2017 11:08:56 +0200 Subject: AMUtil: use DLT API only when DLT is selected Protecting access to DLT API dlt_user_is_logLevel_enabled by checking if destination is really meant to be DLT daemon. Otherwise, invalid DLT Context could be accessed. Signed-off-by: Guerra Mattia --- AudioManagerUtilities/include/CAmDltWrapper.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 -- cgit v1.2.1 From 4e72bcb91edee76ad1b1b622c84586a487797339 Mon Sep 17 00:00:00 2001 From: Guerra Mattia Date: Thu, 28 Sep 2017 14:59:54 +0200 Subject: CMake: add C in Project for Threads Signed-off-by: Guerra Mattia --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f3bbe7..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 ) -- cgit v1.2.1 From c7f1fd1a0b14686d06043be27f0ac03265aac16f Mon Sep 17 00:00:00 2001 From: Guerra Mattia Date: Thu, 28 Sep 2017 15:09:56 +0200 Subject: AMUtil: fix missed copy in list Poll When copying the list of Poll fd, also the revents have to be copied. This is very important for AM Plugins which rely on revents in order to consume data. Without updating the revents, there's concrete risk of endless poll and general stuck situation. Signed-off-by: Guerra Mattia --- AudioManagerUtilities/src/CAmSocketHandler.cpp | 31 +++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) 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 listPoll; VectorListPoll_t cloneListPoll; VectorListPoll_t::iterator listmPollIt; - VectorListPollfd_t::iterator itMfdPollingArray; VectorListPollfd_t fdPollingArray; //! 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 prepareCB; //preperation callback - std::function firedCB; //fired callback + std::function firedCB; //fired callback std::function checkCB; //check callback std::function dispatchCB; //check callback -- cgit v1.2.1 From 4090fe1d40c978d8c8cbc6a156dbfa664305163e Mon Sep 17 00:00:00 2001 From: Guerra Mattia Date: Fri, 29 Sep 2017 10:51:32 +0200 Subject: AMCore: remodel ctor Sender in Command and Routing Moving plugin opening to a separate function, this gets rid of a memory writer behavior on ARM64 platforms, otherwise leading to a this pointer of lambda functions severely corrupted (only when compiling optimizations are enabled). Signed-off-by: Guerra Mattia --- AudioManagerCore/include/CAmCommandSender.h | 2 +- AudioManagerCore/include/CAmRoutingSender.h | 1 + AudioManagerCore/src/CAmCommandSender.cpp | 203 +++++++++++----------- AudioManagerCore/src/CAmRoutingSender.cpp | 256 ++++++++++++++-------------- 4 files changed, 238 insertions(+), 224 deletions(-) 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& listOfPluginDirectories); void unloadLibraries(void); //!< unload the shared libraries std::vector mListInterfaces; //!< list of all interfaces std::vector mListLibraryHandles; //!< list of all library handles. This information is used to unload the plugins correctly. 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& listOfPluginDirectories); am_Handle_s createHandle(std::shared_ptr handleData, const am_Handle_e type); //!< creates a handle void unloadLibraries(void); //!< unloads all loaded plugins 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 @@ -58,6 +58,100 @@ CAmCommandSender::CAmCommandSender(const std::vector& listOfPluginD mListLibraryNames(), // 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(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(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& 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& 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& listOfPluginDirectories) { if (listOfPluginDirectories.empty()) { @@ -93,16 +187,18 @@ CAmCommandSender::CAmCommandSender(const std::vector& 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& 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& 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(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(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& 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& 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/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 sharedLibraryNameList; - std::vector::const_iterator dirIter = listOfPluginDirectories.begin(); - std::vector::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& 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 sharedLibraryNameList; + std::vector::const_iterator dirIter = listOfPluginDirectories.begin(); + std::vector::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::iterator iter = sharedLibraryNameList.begin(); - std::vector::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::iterator iter = sharedLibraryNameList.begin(); + std::vector::iterator iterEnd = sharedLibraryNameList.end(); - IAmRoutingSend* (*createFunc)(); - void* tempLibHandle = NULL; - createFunc = getCreateFunction(*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(*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() -- cgit v1.2.1