IpcModuleLoader: added ipc module loader library
authorTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Fri, 15 Jun 2012 13:58:45 +0000 (06:58 -0700)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Thu, 21 Jun 2012 07:15:22 +0000 (00:15 -0700)
- 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
LayerManagerPlugins/IpcModules/CMakeLists.txt
LayerManagerPlugins/IpcModules/IpcModuleLoader/CMakeLists.txt [new file with mode: 0644]
LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModule.h [moved from LayerManagerPlugins/IpcModules/DbusIpcModule/include/IpcModule.h with 100% similarity, mode: 0644]
LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModuleLoader.h [new file with mode: 0644]
LayerManagerPlugins/IpcModules/IpcModuleLoader/src/IpcModuleLoader.c [new file with mode: 0644]

index 76f04b0..9e2952c 100644 (file)
@@ -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 <Timo.Lotterbach@bmw-carit.de> 0.9.6
 - added IpcModules
+- added IpcModuleLoader
 * Fri Aug 26 2011 Michael Schuldt <Michael.Schuldt@bmw-carit.de> 0.9.1
 - Missing install target for libLayerManagerGraphicGLESv2.so added
 - Missing install target for LayerManagerService.conf added
index 2440dee..c6ca5f6 100644 (file)
@@ -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 (file)
index 0000000..8982460
--- /dev/null
@@ -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/IpcModuleLoader/include/IpcModuleLoader.h b/LayerManagerPlugins/IpcModules/IpcModuleLoader/include/IpcModuleLoader.h
new file mode 100644 (file)
index 0000000..2aa0308
--- /dev/null
@@ -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 (file)
index 0000000..d4b3685
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <dirent.h> // DIR
+#include <string.h> // 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;
+}