summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Bachmann <manuel.bachmann@iot.bzh>2015-12-21 06:57:05 +0100
committerManuel Bachmann <manuel.bachmann@iot.bzh>2015-12-21 07:00:46 +0100
commit98f5843474dcec55827279b6f42007341c171ae0 (patch)
tree010c6328cda7ef2b2577eb00ffca14c931dfbc3b
parent03bebc12f0fd5006a72e430084146a36d2db7c8d (diff)
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 <manuel.bachmann@iot.bzh>
-rw-r--r--CMakeLists.txt9
-rw-r--r--include/proto-def.h6
-rw-r--r--plugins/CMakeLists.txt18
-rw-r--r--plugins/audio/CMakeLists.txt10
-rw-r--r--plugins/audio/audio-api.c2
-rw-r--r--plugins/radio/CMakeLists.txt10
-rw-r--r--plugins/radio/radio-api.c2
-rw-r--r--plugins/samples/CMakeLists.txt11
-rw-r--r--plugins/samples/HelloWorld.c4
-rw-r--r--plugins/samples/SamplePost.c4
-rw-r--r--plugins/session/CMakeLists.txt6
-rw-r--r--plugins/session/token-api.c4
-rw-r--r--src/rest-api.c48
13 files changed, 95 insertions, 39 deletions
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 $<TARGET_OBJECTS:src> $<TARGET_OBJECTS:plugins>)
+ADD_EXECUTABLE(afb-daemon $<TARGET_OBJECTS:src>)
+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 <dirent.h>
+#include <dlfcn.h>
#include <setjmp.h>
#include <signal.h>
@@ -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);