From cf1be4ecf17ecd992bc6fa690c0ec11c4356d945 Mon Sep 17 00:00:00 2001 From: Timo Lotterbach Date: Fri, 15 Jun 2012 06:58:45 -0700 Subject: [PATCH] IpcModuleLoader: added ipc module loader library - implemented in C - common implementation to find, check and load IpcModules - communication technology independent - returns a struct of function pointers to use IpcModule --- LayerManager.spec.in | 2 + LayerManagerPlugins/IpcModules/CMakeLists.txt | 1 + .../IpcModules/IpcModuleLoader/CMakeLists.txt | 53 +++++++ .../include/IpcModule.h | 0 .../IpcModuleLoader/include/IpcModuleLoader.h | 68 +++++++++ .../IpcModuleLoader/src/IpcModuleLoader.c | 169 +++++++++++++++++++++ 6 files changed, 293 insertions(+) create mode 100644 LayerManagerPlugins/IpcModules/IpcModuleLoader/CMakeLists.txt rename LayerManagerPlugins/IpcModules/{DbusIpcModule => IpcModuleLoader}/include/IpcModule.h (100%) mode change 100755 => 100644 create mode 100644 LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModuleLoader.h create mode 100644 LayerManagerPlugins/IpcModules/IpcModuleLoader/src/IpcModuleLoader.c diff --git a/LayerManager.spec.in b/LayerManager.spec.in index 76f04b0..9e2952c 100644 --- a/LayerManager.spec.in +++ b/LayerManager.spec.in @@ -52,6 +52,7 @@ rm -rf $RPM_BUILD_ROOT %dir %_libdir/layermanager/communicator %{_libdir}/layermanager/communicator/libDBUSCommunicator.so %{_libdir}/layermanager/ipcmodules/*.so +%{_libdir}/libIpcModuleLoader.so %{_libdir}/libLayerManagerCommands.so %{_libdir}/libLayerManagerGraphicGLESv2.so %dir %_libdir/layermanager/renderer @@ -80,6 +81,7 @@ rm -rf $RPM_BUILD_ROOT %changelog * Mon Jun 11 2012 Timo Lotterbach 0.9.6 - added IpcModules +- added IpcModuleLoader * Fri Aug 26 2011 Michael Schuldt 0.9.1 - Missing install target for libLayerManagerGraphicGLESv2.so added - Missing install target for LayerManagerService.conf added diff --git a/LayerManagerPlugins/IpcModules/CMakeLists.txt b/LayerManagerPlugins/IpcModules/CMakeLists.txt index 2440dee..c6ca5f6 100644 --- a/LayerManagerPlugins/IpcModules/CMakeLists.txt +++ b/LayerManagerPlugins/IpcModules/CMakeLists.txt @@ -19,4 +19,5 @@ cmake_minimum_required (VERSION 2.6) +add_subdirectory(IpcModuleLoader) add_subdirectory(DbusIpcModule) diff --git a/LayerManagerPlugins/IpcModules/IpcModuleLoader/CMakeLists.txt b/LayerManagerPlugins/IpcModules/IpcModuleLoader/CMakeLists.txt new file mode 100644 index 0000000..8982460 --- /dev/null +++ b/LayerManagerPlugins/IpcModules/IpcModuleLoader/CMakeLists.txt @@ -0,0 +1,53 @@ +############################################################################ +# +# Copyright 2012 BMW Car IT GmbH +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################ + +cmake_minimum_required (VERSION 2.6) + +include_directories( + "include" + "${CMAKE_SOURCE_DIR}/LayerManagerClient/ilmClient/include" + "${CMAKE_SOURCE_DIR}/LayerManagerPlugins/IpcModules/IpcModuleLoader/include" +) + +add_library(IpcModuleLoader SHARED + src/IpcModuleLoader.c +) + +set(LIBS + dl + ${LIBS} +) +target_link_libraries(IpcModuleLoader ${LIBS}) + +install ( + TARGETS IpcModuleLoader + LIBRARY DESTINATION lib +) + +install ( + FILES include/IpcModule.h + DESTINATION include/ilm +) + +if (WITH_TESTS) +# enable_testing() +# add_executable(IpcModuleLoader_Test tests/IlmCommandTest.cpp) +# target_link_libraries(IpcModuleLoader_Test IpcModuleLoader ${LIBS} gtest) +# add_test(IpcModuleLoader IpcModuleLoader_Test ) +endif(WITH_TESTS) \ No newline at end of file diff --git a/LayerManagerPlugins/IpcModules/DbusIpcModule/include/IpcModule.h b/LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModule.h old mode 100755 new mode 100644 similarity index 100% rename from LayerManagerPlugins/IpcModules/DbusIpcModule/include/IpcModule.h rename to LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModule.h diff --git a/LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModuleLoader.h b/LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModuleLoader.h new file mode 100644 index 0000000..2aa0308 --- /dev/null +++ b/LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModuleLoader.h @@ -0,0 +1,68 @@ +/************************************************************************** + * + * Copyright 2012 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ +#ifndef __IPCMODULELOADER_H_ +#define __IPCMODULELOADER_H_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "ilm_types.h" + +struct IpcModule +{ + t_ilm_bool (*init)(t_ilm_bool); + t_ilm_bool (*destroy)(); + + t_ilm_bool (*createMessage)(t_ilm_const_string); + t_ilm_bool (*sendMessage)(); + t_ilm_bool (*sendError)(t_ilm_const_string); + enum IpcMessageType (*receiveMessage)(int); // timeout in ms + + t_ilm_const_string (*getMessageName)(); + t_ilm_const_string (*getSenderName)(); + t_ilm_bool (*isErrorMessage)(); + + t_ilm_bool (*appendBool)(const t_ilm_bool); + t_ilm_bool (*getBool)(t_ilm_bool*); + + t_ilm_bool (*appendDouble)(const double); + t_ilm_bool (*getDouble)(double*); + + t_ilm_bool (*appendString)(const char*); + t_ilm_bool (*getString)(char*); + + t_ilm_bool (*appendInt)(const int); + t_ilm_bool (*getInt)(int*); + t_ilm_bool (*appendIntArray)(const int*, int); + t_ilm_bool (*getIntArray)(int**, int*); + + t_ilm_bool (*appendUint)(const unsigned int); + t_ilm_bool (*getUint)(unsigned int*); + t_ilm_bool (*appendUintArray)(const unsigned int*, int); + t_ilm_bool (*getUintArray)(unsigned int**, int*); +}; + +t_ilm_bool loadIpcModule(struct IpcModule* communicator); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // __IPCMODULELOADER_H_ diff --git a/LayerManagerPlugins/IpcModules/IpcModuleLoader/src/IpcModuleLoader.c b/LayerManagerPlugins/IpcModules/IpcModuleLoader/src/IpcModuleLoader.c new file mode 100644 index 0000000..d4b3685 --- /dev/null +++ b/LayerManagerPlugins/IpcModules/IpcModuleLoader/src/IpcModuleLoader.c @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2012 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ +#include "IpcModuleLoader.h" +#include "IpcModule.h" +#include +#include +#include +#include +#include // DIR +#include // strcpy, strcat, strstr + +//============================================================================= +// logging +//============================================================================= +//#define LOG_ENTER_FUNCTION printf("--> ilmCommunicatorControl::%s\n", __PRETTY_FUNCTION__) +#define LOG_ENTER_FUNCTION + + +//============================================================================= +// global variables +//============================================================================= +const char* gDefaultPluginLookupPath = "/usr/lib/layermanager"; +const char* gCommunicatorPluginDirectory = "/ipcmodules"; + + +//============================================================================= +// plugin loading +//============================================================================= +t_ilm_bool loadSymbolTable(struct IpcModule* ipcModule, char* path, char* file) +{ + t_ilm_bool returnValue = ILM_FALSE; + void* pluginLibHandle = 0; + char fullFilePath[1024]; + fullFilePath[0] = '\0'; + + struct ApiFunction + { + const char* name; + void** funcPtr; + }; + + struct ApiFunction ApiFunctionTable[] = + { + { "init", (void**)&ipcModule->init }, + { "destroy", (void**)&ipcModule->destroy }, + { "createMessage", (void**)&ipcModule->createMessage }, + { "sendMessage", (void**)&ipcModule->sendMessage }, + { "sendError", (void**)&ipcModule->sendError }, + { "isErrorMessage", (void**)&ipcModule->isErrorMessage }, + { "receiveMessage", (void**)&ipcModule->receiveMessage }, + { "getMessageName", (void**)&ipcModule->getMessageName }, + { "getSenderName", (void**)&ipcModule->getSenderName }, + { "appendBool", (void**)&ipcModule->appendBool }, + { "getBool", (void**)&ipcModule->getBool }, + { "appendDouble", (void**)&ipcModule->appendDouble }, + { "getDouble", (void**)&ipcModule->getDouble }, + { "appendString", (void**)&ipcModule->appendString }, + { "getString", (void**)&ipcModule->getString }, + { "appendInt", (void**)&ipcModule->appendInt }, + { "getInt", (void**)&ipcModule->getInt }, + { "appendIntArray", (void**)&ipcModule->appendIntArray }, + { "getIntArray", (void**)&ipcModule->getIntArray }, + { "appendUint", (void**)&ipcModule->appendUint }, + { "getUint", (void**)&ipcModule->getUint }, + { "appendUintArray", (void**)&ipcModule->appendUintArray }, + { "getUintArray", (void**)&ipcModule->getUintArray } + }; + + const int apiFunctionCount = sizeof (ApiFunctionTable) / sizeof(struct ApiFunction); + int symbolCount = 0; + + strcat(fullFilePath, path); + strcat(fullFilePath, "/"); + strcat(fullFilePath, file); + + pluginLibHandle = dlopen(fullFilePath, RTLD_LAZY); + + if (pluginLibHandle) + { + unsigned int i = 0; + for (i = 0; i < apiFunctionCount; ++i) + { + struct ApiFunction* func = &ApiFunctionTable[i]; + + *func->funcPtr = dlsym(pluginLibHandle, func->name); + if (*func->funcPtr) + { + symbolCount++; + } + } + } + + if (symbolCount == apiFunctionCount) + { + returnValue = ILM_TRUE; + } + else + { + printf("Error in %s: found %d symbols, expected %d symbols.\n", fullFilePath, symbolCount, apiFunctionCount); + if (0 != errno) + { + printf("--> error: %s\n", strerror(errno)); + } + printf("--> not a valid ipc module\n"); + if (pluginLibHandle) + { + dlclose(pluginLibHandle); + } + } + + return returnValue; +} + +t_ilm_bool loadIpcModule(struct IpcModule* communicator) +{ + t_ilm_bool result = ILM_FALSE; + + // find communicator client plugin + char* pluginLookupPath = getenv("LM_PLUGIN_PATH"); + if (pluginLookupPath) + { + gDefaultPluginLookupPath = pluginLookupPath; + } + + char path[1024]; + strcpy(path, gDefaultPluginLookupPath); + strcat(path, gCommunicatorPluginDirectory); + + // open directory + DIR *directory = opendir(path); + if (directory) + { + // iterate content of directory + struct dirent *itemInDirectory = 0; + while ((itemInDirectory = readdir(directory)) && !result) + { + char* fileName = itemInDirectory->d_name; + + if (strstr(fileName, ".so")) + { + result = loadSymbolTable(communicator, path, fileName); + } + } + + closedir(directory); + } + else + { + printf("IpcModuleLoader: Error opening plugin dir %s\n", path); + } + + return result; +} -- 2.7.4