From: Manuel Bachmann Date: Mon, 21 Dec 2015 05:57:05 +0000 (+0100) Subject: Switch to a plugin model X-Git-Tag: blowfish_2.0.1~335 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=src%2Fapp-framework-binder.git;a=commitdiff_plain;h=98f5843474dcec55827279b6f42007341c171ae0 Switch to a plugin model Each API now compiles to a ".so" file, which gets searched for in the "${libdir}/afb" directory at startup. We can now load an arbitrary number of plugins (> 10). Signed-off-by: Manuel Bachmann --- diff --git a/CMakeLists.txt b/CMakeLists.txt index a3ab4c37..4fba65e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ SET(PROJECT_VERSION "0.1") INCLUDE(FindPkgConfig) INCLUDE(CheckIncludeFiles) INCLUDE(CheckLibraryExists) +INCLUDE(GNUInstallDirs) CHECK_INCLUDE_FILES(magic.h HAVE_MAGIC_H) CHECK_LIBRARY_EXISTS(magic magic_load "" HAVE_LIBMAGIC_SO) @@ -51,12 +52,16 @@ INCLUDE(FindThreads) FIND_PACKAGE(Threads) SET(include_dirs ${INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/include ${json-c_INCLUDE_DIRS} ${libmicrohttpd_INCLUDE_DIRS} ${uuid_INCLUDE_DIRS} ${alsa_INCLUDE_DIRS} ${librtlsdr_INCLUDE_DIRS}) -SET(link_libraries ${json-c_LIBRARIES} ${libmicrohttpd_LIBRARIES} ${uuid_LIBRARIES} ${alsa_LIBRARIES} ${librtlsdr_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${libefence_LIBRARIES} -lmagic -lm) +SET(link_libraries ${json-c_LIBRARIES} ${libmicrohttpd_LIBRARIES} ${uuid_LIBRARIES} ${alsa_LIBRARIES} ${librtlsdr_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${libefence_LIBRARIES} -lmagic -lm -ldl) +SET(plugin_install_dir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/afb) + +ADD_DEFINITIONS(-DPLUGIN_INSTALL_DIR="${plugin_install_dir}") ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(plugins) -ADD_EXECUTABLE(afb-daemon $ $) +ADD_EXECUTABLE(afb-daemon $) +INCLUDE_DIRECTORIES(${include_dirs}) TARGET_LINK_LIBRARIES(afb-daemon ${link_libraries}) INSTALL(TARGETS afb-daemon diff --git a/include/proto-def.h b/include/proto-def.h index 315cecfa..937d6930 100644 --- a/include/proto-def.h +++ b/include/proto-def.h @@ -34,11 +34,7 @@ PUBLIC AFB_PostHandle* getPostHandle (AFB_request *request); void initPlugins (AFB_session *session); typedef AFB_plugin* (*AFB_pluginCB)(); -PUBLIC AFB_plugin* tokenRegister (); -PUBLIC AFB_plugin* audioRegister (); -PUBLIC AFB_plugin* helloWorldRegister (); -PUBLIC AFB_plugin* radioRegister (); -PUBLIC AFB_plugin* samplePostRegister (); +PUBLIC AFB_plugin* pluginRegister (); // Session handling PUBLIC AFB_error sessionCheckdir (AFB_session *session); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 7e3e0807..c66de5e7 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,14 +1,4 @@ -SET(SESSION_PLUGIN session/token-api.c) -SET(HELLOWORLD_PLUGINS samples/HelloWorld.c) -SET(SAMPLEPOST_PLUGINS samples/SamplePost.c) -IF(alsa_FOUND) - SET(AUDIO_PLUGIN audio/audio-api.c audio/audio-alsa.c) -ENDIF(alsa_FOUND) -IF(librtlsdr_FOUND) - SET(RADIO_PLUGIN radio/radio-api.c radio/radio-rtlsdr.c) -ENDIF(librtlsdr_FOUND) - -SET(PLUGINS_SOURCES ${SESSION_PLUGIN} ${HELLOWORLD_PLUGINS} ${SAMPLEPOST_PLUGINS} ${AUDIO_PLUGIN} ${RADIO_PLUGIN}) - -ADD_LIBRARY(plugins OBJECT ${PLUGINS_SOURCES}) -INCLUDE_DIRECTORIES(${include_dirs}) +ADD_SUBDIRECTORY(session) +ADD_SUBDIRECTORY(samples) +ADD_SUBDIRECTORY(audio) +ADD_SUBDIRECTORY(radio) diff --git a/plugins/audio/CMakeLists.txt b/plugins/audio/CMakeLists.txt new file mode 100644 index 00000000..b5adc643 --- /dev/null +++ b/plugins/audio/CMakeLists.txt @@ -0,0 +1,10 @@ +IF(alsa_FOUND) + + INCLUDE_DIRECTORIES(${include_dirs}) + + ADD_LIBRARY(audio-api MODULE audio-api.c audio-alsa.c) + SET_TARGET_PROPERTIES(audio-api PROPERTIES PREFIX "") + INSTALL(TARGETS audio-api + LIBRARY DESTINATION ${plugin_install_dir}) + +ENDIF(alsa_FOUND) diff --git a/plugins/audio/audio-api.c b/plugins/audio/audio-api.c index 53a4beab..60a5a962 100644 --- a/plugins/audio/audio-api.c +++ b/plugins/audio/audio-api.c @@ -223,7 +223,7 @@ STATIC AFB_restapi pluginApis[]= { {NULL} }; -PUBLIC AFB_plugin *audioRegister () { +PUBLIC AFB_plugin *pluginRegister () { AFB_plugin *plugin = malloc (sizeof(AFB_plugin)); plugin->type = AFB_PLUGIN_JSON; plugin->info = "Application Framework Binder - Audio plugin"; diff --git a/plugins/radio/CMakeLists.txt b/plugins/radio/CMakeLists.txt new file mode 100644 index 00000000..c7c85411 --- /dev/null +++ b/plugins/radio/CMakeLists.txt @@ -0,0 +1,10 @@ +IF(librtlsdr_FOUND) + + INCLUDE_DIRECTORIES(${include_dirs}) + + ADD_LIBRARY(radio-api MODULE radio-api.c radio-rtlsdr.c) + SET_TARGET_PROPERTIES(radio-api PROPERTIES PREFIX "") + INSTALL(TARGETS radio-api + LIBRARY DESTINATION ${plugin_install_dir}) + +ENDIF(librtlsdr_FOUND) diff --git a/plugins/radio/radio-api.c b/plugins/radio/radio-api.c index 3de8e044..cfa25995 100644 --- a/plugins/radio/radio-api.c +++ b/plugins/radio/radio-api.c @@ -327,7 +327,7 @@ STATIC AFB_restapi pluginApis[]= { {NULL} }; -PUBLIC AFB_plugin* radioRegister () { +PUBLIC AFB_plugin* pluginRegister () { AFB_plugin *plugin = malloc (sizeof(AFB_plugin)); plugin->type = AFB_PLUGIN_JSON; plugin->info = "Application Framework Binder - Radio plugin"; diff --git a/plugins/samples/CMakeLists.txt b/plugins/samples/CMakeLists.txt new file mode 100644 index 00000000..ef5b449e --- /dev/null +++ b/plugins/samples/CMakeLists.txt @@ -0,0 +1,11 @@ +INCLUDE_DIRECTORIES(${include_dirs}) + +ADD_LIBRARY(helloWorld-api MODULE HelloWorld.c) +SET_TARGET_PROPERTIES(helloWorld-api PROPERTIES PREFIX "") +INSTALL(TARGETS helloWorld-api + LIBRARY DESTINATION ${plugin_install_dir}) + +ADD_LIBRARY(samplePost-api MODULE SamplePost.c) +SET_TARGET_PROPERTIES(samplePost-api PROPERTIES PREFIX "") +INSTALL(TARGETS samplePost-api + LIBRARY DESTINATION ${plugin_install_dir}) diff --git a/plugins/samples/HelloWorld.c b/plugins/samples/HelloWorld.c index 4117c26a..5638b427 100644 --- a/plugins/samples/HelloWorld.c +++ b/plugins/samples/HelloWorld.c @@ -84,11 +84,11 @@ STATIC AFB_restapi pluginApis[]= { }; -PUBLIC AFB_plugin *helloWorldRegister () { +PUBLIC AFB_plugin *pluginRegister () { AFB_plugin *plugin = malloc (sizeof (AFB_plugin)); plugin->type = AFB_PLUGIN_JSON; plugin->info = "Application Framework Binder Service"; plugin->prefix= "dbus"; plugin->apis = pluginApis; return (plugin); -}; \ No newline at end of file +}; diff --git a/plugins/samples/SamplePost.c b/plugins/samples/SamplePost.c index 85485015..223f74e8 100644 --- a/plugins/samples/SamplePost.c +++ b/plugins/samples/SamplePost.c @@ -165,7 +165,7 @@ STATIC AFB_restapi pluginApis[]= { {NULL} }; -PUBLIC AFB_plugin *samplePostRegister () { +PUBLIC AFB_plugin *pluginRegister () { AFB_plugin *plugin = malloc (sizeof (AFB_plugin)); plugin->type = AFB_PLUGIN_JSON; plugin->info = "Application Framework Binder Service"; @@ -174,4 +174,4 @@ PUBLIC AFB_plugin *samplePostRegister () { plugin->handle= (void*) "What ever you want"; return (plugin); -}; \ No newline at end of file +}; diff --git a/plugins/session/CMakeLists.txt b/plugins/session/CMakeLists.txt new file mode 100644 index 00000000..ddd185df --- /dev/null +++ b/plugins/session/CMakeLists.txt @@ -0,0 +1,6 @@ +INCLUDE_DIRECTORIES(${include_dirs}) + +ADD_LIBRARY(token-api MODULE token-api.c) +SET_TARGET_PROPERTIES(token-api PROPERTIES PREFIX "") +INSTALL(TARGETS token-api + LIBRARY DESTINATION ${plugin_install_dir}) diff --git a/plugins/session/token-api.c b/plugins/session/token-api.c index b6ebb8ad..ba6d2761 100644 --- a/plugins/session/token-api.c +++ b/plugins/session/token-api.c @@ -94,7 +94,7 @@ STATIC AFB_restapi pluginApis[]= { {NULL} }; -PUBLIC AFB_plugin *tokenRegister () { +PUBLIC AFB_plugin *pluginRegister () { AFB_plugin *plugin = malloc (sizeof (AFB_plugin)); plugin->type = AFB_PLUGIN_JSON; plugin->info = "Application Framework Binder Service"; @@ -104,4 +104,4 @@ PUBLIC AFB_plugin *tokenRegister () { plugin->freeCtxCB= (void*) clientContextFree; return (plugin); -}; \ No newline at end of file +}; diff --git a/src/rest-api.c b/src/rest-api.c index 1635d445..da331678 100644 --- a/src/rest-api.c +++ b/src/rest-api.c @@ -22,6 +22,8 @@ #include "../include/local-def.h" +#include +#include #include #include @@ -629,20 +631,46 @@ STATIC AFB_plugin ** RegisterJsonPlugins(AFB_plugin **plugins) { } void initPlugins(AFB_session *session) { - static AFB_plugin * plugins[10]; + static AFB_plugin **plugins; + AFB_plugin* (*pluginRegisterFct)(void); + void *plugin; + char *pluginPath; + struct dirent *pluginDir; + DIR *dir; afbJsonType = json_object_new_string (AFB_MSG_JTYPE); int i = 0; - plugins[i++] = tokenRegister(session); - plugins[i++] = helloWorldRegister(session); - plugins[i++] = samplePostRegister(session); -#ifdef HAVE_AUDIO_PLUGIN - plugins[i++] = audioRegister(session); -#endif -#ifdef HAVE_RADIO_PLUGIN - plugins[i++] = radioRegister(session), -#endif + if ((dir = opendir(PLUGIN_INSTALL_DIR)) == NULL) { + fprintf(stderr, "Could not open plugin directory=%s\n", PLUGIN_INSTALL_DIR); + return; + } + + while ((pluginDir = readdir(dir)) != NULL) { + + if (!strstr (pluginDir->d_name, ".so")) + continue; + + asprintf (&pluginPath, PLUGIN_INSTALL_DIR "/%s", pluginDir->d_name); + plugin = dlopen (pluginPath, RTLD_NOW | RTLD_LOCAL); + pluginRegisterFct = dlsym (plugin, "pluginRegister"); + free (pluginPath); + if (!plugin) { + if (verbose) fprintf(stderr, "[%s] is not a binary plugin, continuing...\n", pluginDir->d_name); + continue; + } else if (!pluginRegisterFct) { + if (verbose) fprintf(stderr, "[%s] is not an AFB plugin, continuing...\n", pluginDir->d_name); + continue; + } + + if (verbose) fprintf(stderr, "[%s] is a valid AFB plugin, loading it\n", pluginDir->d_name); + plugins = (AFB_plugin **) realloc (plugins, (i+1)*sizeof(AFB_plugin)); + plugins[i] = (AFB_plugin *) malloc (sizeof(AFB_plugin)); + plugins[i] = (**pluginRegisterFct)(); + i++; + } plugins[i++] = NULL; + + closedir (dir); // complete plugins and save them within current sessions session->plugins = RegisterJsonPlugins(plugins);