gam-resource-manager: adjust to updated proxied call callback signature.
[profile/ivi/murphy.git] / src / core / plugin.h
1 /*
2  * Copyright (c) 2012, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *  * Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *  * Neither the name of Intel Corporation nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef __MURPHY_PLUGIN_H__
31 #define __MURPHY_PLUGIN_H__
32
33 #include <stdbool.h>
34 #include <dlfcn.h>
35
36 #include <murphy/common/macros.h>
37 #include <murphy/common/mm.h>
38 #include <murphy/common/log.h>
39 #include <murphy/common/list.h>
40 #include <murphy/common/refcnt.h>
41 #include <murphy/common/json.h>
42 #include <murphy/core/context.h>
43 #include <murphy/core/console-command.h>
44
45 typedef struct mrp_plugin_s mrp_plugin_t;
46
47 #include <murphy/core/method.h>
48
49 #ifndef MRP_DEFAULT_PLUGIN_DIR
50 #    define MRP_DEFAULT_PLUGIN_DIR LIBDIR"/murphy/plugins"
51 #endif
52
53 #define MRP_PLUGIN_DESCRIPTOR "mrp_get_plugin_descriptor"
54
55
56 /*
57  * names of plugin-related events we emit
58  */
59
60 #define MRP_PLUGIN_BUS            "plugin-bus"
61 #define MRP_PLUGIN_EVENT_LOADED   "plugin-loaded"
62 #define MRP_PLUGIN_EVENT_STARTED  "plugin-started"
63 #define MRP_PLUGIN_EVENT_FAILED   "plugin-failed"
64 #define MRP_PLUGIN_EVENT_STOPPING "plugin-stopping"
65 #define MRP_PLUGIN_EVENT_STOPPED  "plugin-stopped"
66 #define MRP_PLUGIN_EVENT_UNLOADED "plugin-unloaded"
67
68
69 /*
70  * event message data tags
71  */
72
73 #define MRP_PLUGIN_TAG_PLUGIN     ((uint16_t)1)  /* plugin name string */
74 #define MRP_PLUGIN_TAG_INSTANCE   ((uint16_t)2)  /* plugin instance string */
75
76
77 /*
78  * plugin arguments
79  */
80
81 typedef enum {
82     MRP_PLUGIN_ARG_TYPE_UNKNOWN = 0,
83     MRP_PLUGIN_ARG_TYPE_STRING,
84     MRP_PLUGIN_ARG_TYPE_BOOL,
85     MRP_PLUGIN_ARG_TYPE_UINT32,
86     MRP_PLUGIN_ARG_TYPE_INT32,
87     MRP_PLUGIN_ARG_TYPE_DOUBLE,
88     MRP_PLUGIN_ARG_TYPE_OBJECT,
89     MRP_PLUGIN_ARG_TYPE_UNDECL,
90     /* add more as needed */
91 } mrp_plugin_arg_type_t;
92
93 typedef struct mrp_plugin_arg_s mrp_plugin_arg_t;
94
95 struct mrp_plugin_arg_s {
96     char                  *key;          /* plugin argument name */
97     mrp_plugin_arg_type_t  type;         /* plugin argument type */
98     union {                              /* default/supplied value */
99         char              *str;          /* string values */
100         bool               bln;          /* boolean values */
101         uint32_t           u32;          /* 32-bit unsigned values */
102         int32_t            i32;          /* 32-bit signed values */
103         double             dbl;          /* double prec. floating pt. values */
104         struct {                         /* a JSON object */
105             char       *str;
106             mrp_json_t *json;
107         } obj;
108         struct {                         /* other undeclared arguments */
109             mrp_plugin_arg_t *args;
110             int               narg;
111         } rest;
112     };
113 };
114
115
116 /** Macro for declaring a plugin argument table. */
117 #define MRP_PLUGIN_ARGUMENTS(table, ...)     \
118     static mrp_plugin_arg_t table[] =        \
119         __VA_ARGS__                          \
120
121
122 /** Convenience macros for setting up argument tables with type and defaults. */
123 #define MRP_PLUGIN_ARG_STRING(name, defval)                                \
124     { key: name, type: MRP_PLUGIN_ARG_TYPE_STRING, { str: defval } }
125
126 #define MRP_PLUGIN_ARG_BOOL(name, defval)                                  \
127     { key: name, type: MRP_PLUGIN_ARG_TYPE_BOOL  , { bln: !!defval } }
128
129 #define MRP_PLUGIN_ARG_UINT32(name, defval)                                \
130     { key: name, type: MRP_PLUGIN_ARG_TYPE_UINT32, { u32: defval } }
131
132 #define MRP_PLUGIN_ARG_INT32(name, defval)                                 \
133     { key: name, type: MRP_PLUGIN_ARG_TYPE_INT32 , { i32: defval } }
134
135 #define MRP_PLUGIN_ARG_DOUBLE(name, defval)                                \
136     { key: name, type: MRP_PLUGIN_ARG_TYPE_DOUBLE, { dbl: defval } }
137
138 #define MRP_PLUGIN_ARG_OBJECT(name, defval)                                \
139     { key: name, type: MRP_PLUGIN_ARG_TYPE_OBJECT,                         \
140             { obj: { str: defval, json: NULL } } }
141
142 #define MRP_PLUGIN_ARG_UNDECL(name, defval)                                \
143     { key: "*", type: MRP_PLUGIN_ARG_TYPE_UNDECL,  { str: NULL } }
144
145 /** Similar convenience macros for indexed argument access. */
146 #define MRP_PLUGIN_ARGIDX_STRING(idx, name, defval) \
147     [idx] MRP_PLUGIN_ARG_STRING(name, defval)
148
149 #define MRP_PLUGIN_ARGIDX_STRING(idx, name, defval) \
150     [idx] MRP_PLUGIN_ARG_STRING(name, defval)
151
152 #define MRP_PLUGIN_ARGIDX_BOOL(idx, name, defval)   \
153     [idx] MRP_PLUGIN_ARG_BOOL(name, defval)
154
155 #define MRP_PLUGIN_ARGIDX_UINT32(idx, name, defval) \
156     [idx] MRP_PLUGIN_ARG_UINT32(name, defval)
157
158 #define MRP_PLUGIN_ARGIDX_INT32(idx, name, defval)  \
159     [idx] MRP_PLUGIN_ARG_INT32(name, defval)
160
161 #define MRP_PLUGIN_ARGIDX_DOUBLE(idx, name, defval) \
162     [idx] MRP_PLUGIN_ARG_DOUBLE(name, defval)
163
164 #define MRP_PLUGIN_ARGIDX_OBJECT(idx, name, defval) \
165     [idx] MRP_PLUGIN_ARG_OBJECT(name, defval)
166
167 #define MRP_PLUGIN_ARGIDX_UNDECL(idx, name, defval) \
168     [idx] MRP_PLUGIN_ARG_UNDECL(name, defval)
169
170 /** Macro for looping through all collected undeclared arguments. */
171 #define mrp_plugin_foreach_undecl_arg(_undecl, _arg)                    \
172     for ((_arg) = (_undecl)->rest.args;                                 \
173          (_arg) - (_undecl)->rest.args < (_undecl)->rest.narg;          \
174          (_arg)++)
175
176
177 /**
178  * Generic convenience macro for indexed argument access.
179  *
180  * Here is how you can use these macros to declare and access your plugin
181  * arguments:
182  *
183  * #define TEST_HELP "Just a stupid test..."
184  * #define TEST_DESCRIPTION "A test plugin."
185  * #define TEST_AUTHORS "D. Duck <donald.duck@ducksburg.org>"
186  *
187  * enum {
188  *     ARG_FOO,
189  *     ARG_BAR,
190  *     ARG_FOOBAR,
191  *     ARG_BARFOO
192  * };
193  *
194  * mrp_plugin_arg_t test_args[] = {
195  *     MRP_PLUGIN_ARGIDX(ARG_FOO   , STRING, "foo"   , "default foo"),
196  *     MRP_PLUGIN_ARGIDX(ARG_BAR   , BOOL  , "bar"   , FALSE        ),
197  *     MRP_PLUGIN_ARGIDX(ARG_FOOBAR, UINT32, "foobar", 1984         ),
198  *     MRP_PLUGIN_ARGIDX(ARG_BARFOO, DOUBLE, "barfoo", 3.141        ),
199  * };
200  *
201  * static int test_init(mrp_plugin_t *plugin)
202  * {
203  *     mrp_plugin_arg_t *args = plugin->args;
204  *
205  *     if (args[ARG_BAR].bln) {
206  *         mrp_log_info("   foo: %s", args[ARG_FOO].str);
207  *         mrp_log_info("foobar: %u", args[ARG_FOOBAR].u32);
208  *         mrp_log_info("barfoo: %f", args[ARG_BARFOO].dbl);
209  *     }
210  *     else
211  *         mrp_log_info("I was not asked to dump my arguments...");
212  *     ...
213  * }
214  *
215  * MURPHY_REGISTER_PLUGIN("test", TEST_DESCRIPTION, TEST_AUTHORS, TEST_HELP,
216  *                        MRP_MULTIPLE, test_init, test_exit, test_args);
217  */
218
219 #define MRP_PLUGIN_ARGIDX(idx, type, name, defval) \
220     [idx] MRP_PLUGIN_ARG_##type(name, defval)
221
222
223 /*
224  * plugin API version
225  */
226
227 #define MRP_PLUGIN_API_MAJOR 0
228 #define MRP_PLUGIN_API_MINOR 1
229
230 #define MRP_PLUGIN_API_VERSION \
231     MRP_VERSION_INT(MRP_PLUGIN_API_MAJOR, MRP_PLUGIN_API_MINOR, 0)
232
233 #define MRP_PLUGIN_API_VERSION_STRING \
234     MRP_VERSION_STRING(MRP_PLUGIN_API_MAJOR, MRP_PLUGIN_API_MINOR, 0)
235
236
237 /*
238  * plugin descriptors
239  */
240
241
242 typedef int  (*mrp_plugin_init_t)(mrp_plugin_t *);
243 typedef void (*mrp_plugin_exit_t)(mrp_plugin_t *);
244
245 #define MRP_SINGLETON TRUE
246 #define MRP_MULTIPLE  FALSE
247
248 typedef struct {
249     char                *name;                 /* plugin name */
250     char                *path;                 /* plugin path */
251     mrp_plugin_init_t    init;                 /* initialize plugin */
252     mrp_plugin_exit_t    exit;                 /* cleanup plugin */
253     mrp_plugin_arg_t    *args;                 /* table of valid arguments */
254     int                  narg;                 /* number of valid arguments */
255     int                  core : 1;             /* is this a core plugin? */
256     int                  singleton : 1;        /* deny multiple instances? */
257     int                  ninstance;            /* number of instances */
258     /* miscallaneous plugin metadata */
259     int                  version;              /* plugin version */
260     int                  mrp_version;          /* murphy API version */
261     const char          *description;          /* plugin description */
262     const char          *authors;              /* plugin authors */
263     const char          *help;                 /* plugin help string */
264     mrp_console_group_t *cmds;                 /* default console commands */
265     mrp_method_descr_t  *exports;              /* exported methods */
266     int                  nexport;              /* number of exported methods */
267     mrp_method_descr_t  *imports;              /* imported methods */
268     int                  nimport;              /* number of imported methods */
269 } mrp_plugin_descr_t;
270
271
272 /*
273  * plugins
274  */
275
276 typedef enum {
277     MRP_PLUGIN_LOADED = 0,                     /* has been loaded */
278     MRP_PLUGIN_RUNNING,                        /* has been started */
279     MRP_PLUGIN_STOPPED,                        /* has been stopped */
280 } mrp_plugin_state_t;
281
282 struct mrp_plugin_s {
283     char                *path;                 /* plugin path */
284     char                *instance;             /* plugin instance */
285     mrp_list_hook_t      hook;                 /* hook to list of plugins */
286     mrp_context_t       *ctx;                  /* murphy context */
287     mrp_plugin_descr_t  *descriptor;           /* plugin descriptor */
288     void                *handle;               /* DSO handle */
289     mrp_plugin_state_t   state;                /* plugin state */
290     mrp_refcnt_t         refcnt;               /* reference count */
291     void                *data;                 /* private plugin data */
292     mrp_plugin_arg_t    *args;                 /* plugin arguments */
293     mrp_console_group_t *cmds;                 /* default console commands */
294     int                  may_fail : 1;         /* load / start may fail */
295 };
296
297
298 #ifdef __MURPHY_BUILTIN_PLUGIN__
299 /*   statically linked in plugins */
300 #    define __MURPHY_REGISTER_PLUGIN(_name,                               \
301                                      _version,                            \
302                                      _description,                        \
303                                      _authors,                            \
304                                      _help,                               \
305                                      _core,                               \
306                                      _single,                             \
307                                      _init,                               \
308                                      _exit,                               \
309                                      _args,                               \
310                                      _narg,                               \
311                                      _exports,                            \
312                                      _nexport,                            \
313                                      _imports,                            \
314                                      _nimport,                            \
315                                      _cmds)                               \
316                                                                           \
317     static void register_plugin(void) __attribute__((constructor));       \
318                                                                           \
319     static void register_plugin(void) {                                   \
320         char *path = __FILE__, *base;                                     \
321         static mrp_plugin_descr_t descriptor = {                          \
322             .name        = _name,                                         \
323             .version     = _version,                                      \
324             .description = _description,                                  \
325             .authors     = _authors,                                      \
326             .mrp_version = MRP_PLUGIN_API_VERSION,                        \
327             .help        = _help,                                         \
328             .init        = _init,                                         \
329             .exit        = _exit,                                         \
330             .core        = _core,                                         \
331             .singleton   = _single,                                       \
332             .ninstance   = 0,                                             \
333             .args        = _args,                                         \
334             .narg        = _narg,                                         \
335             .cmds        = _cmds,                                         \
336             .exports     = _exports,                                      \
337             .nexport     = _nexport,                                      \
338             .imports     = _imports,                                      \
339             .nimport     = _nimport,                                      \
340         };                                                                \
341                                                                           \
342         if ((base = strrchr(path, '/')) != NULL)                          \
343             descriptor.path = base + 1;                                   \
344         else                                                              \
345             descriptor.path = (char *)path;                               \
346                                                                           \
347         mrp_register_builtin_plugin(&descriptor);                         \
348     }                                                                     \
349     struct mrp_allow_trailing_semicolon
350 #else /* dynamically loaded plugins */
351 #    define __MURPHY_REGISTER_PLUGIN(_name,                               \
352                                      _version,                            \
353                                      _description,                        \
354                                      _authors,                            \
355                                      _help,                               \
356                                      _core,                               \
357                                      _single,                             \
358                                      _init,                               \
359                                      _exit,                               \
360                                      _args,                               \
361                                      _narg,                               \
362                                      _exports,                            \
363                                      _nexport,                            \
364                                      _imports,                            \
365                                      _nimport,                            \
366                                      _cmds)                               \
367                                                                           \
368     mrp_plugin_descr_t *mrp_get_plugin_descriptor(void) {                 \
369         static mrp_plugin_descr_t descriptor = {                          \
370             .name        = _name,                                         \
371             .version     = _version,                                      \
372             .description = _description,                                  \
373             .authors     = _authors,                                      \
374             .mrp_version = MRP_PLUGIN_API_VERSION,                        \
375             .help        = _help,                                         \
376             .init        = _init,                                         \
377             .exit        = _exit,                                         \
378             .core        = _core,                                         \
379             .singleton   = _single,                                       \
380             .ninstance   = 0,                                             \
381             .args        = _args,                                         \
382             .narg        = _narg,                                         \
383             .cmds        = _cmds,                                         \
384             .exports     = _exports,                                      \
385             .nexport     = _nexport,                                      \
386             .imports     = _imports,                                      \
387             .nimport     = _nimport,                                      \
388         };                                                                \
389                                                                           \
390         return &descriptor;                                               \
391     }                                                                     \
392     struct mrp_allow_trailing_semicolon
393 #endif
394
395
396 #define MURPHY_REGISTER_PLUGIN(_n, _v, _d, _a, _h, _s, _i, _e,          \
397                                _args, _narg,                            \
398                                _exports, _nexport,                      \
399                                _imports, _nimport,                      \
400                                _cmds)                                   \
401     __MURPHY_REGISTER_PLUGIN(_n, _v, _d, _a, _h, FALSE, _s, _i, _e,     \
402                              _args, _narg,                              \
403                              _exports, _nexport,                        \
404                              _imports, _nimport,                        \
405                              _cmds)
406
407 #define MURPHY_REGISTER_CORE_PLUGIN(_n, _v, _d, _a, _h, _s, _i, _e,     \
408                                     _args, _narg,                       \
409                                     _exports, _nexport,                 \
410                                     _imports, _nimport,                 \
411                                     _cmds)                              \
412     __MURPHY_REGISTER_PLUGIN(_n, _v, _d, _a, _h, TRUE, _s, _i, _e,      \
413                              _args, _narg,                              \
414                              _exports, _nexport,                        \
415                              _imports, _nimport,                        \
416                              _cmds)
417
418 #define MRP_REGISTER_PLUGIN MURPHY_REGISTER_PLUGIN
419 #define MRP_REGISTER_CORE_PLUGIN MURPHY_REGISTER_CORE_PLUGIN
420
421
422 int mrp_register_builtin_plugin(mrp_plugin_descr_t *descr);
423 int mrp_plugin_exists(mrp_context_t *ctx, const char *name);
424 mrp_plugin_t *mrp_load_plugin(mrp_context_t *ctx, const char *name,
425                               const char *instance, mrp_plugin_arg_t *args,
426                               int narg);
427 int mrp_load_all_plugins(mrp_context_t *ctx);
428 int mrp_unload_plugin(mrp_plugin_t *plugin);
429 int mrp_plugin_loaded(mrp_context_t *ctx, const char *name);
430 int mrp_start_plugins(mrp_context_t *ctx);
431 int mrp_start_plugin(mrp_plugin_t *plugin);
432 int mrp_plugin_running(mrp_context_t *ctx, const char *name);
433 int mrp_stop_plugin(mrp_plugin_t *plugin);
434 int mrp_request_plugin(mrp_context_t *ctx, const char *name,
435                        const char *instance);
436 void mrp_block_blacklisted_plugins(mrp_context_t *ctx);
437
438 mrp_plugin_arg_t *mrp_plugin_find_undecl_arg(mrp_plugin_arg_t *undecl,
439                                              const char *key,
440                                              mrp_plugin_arg_type_t type);
441
442
443 static inline mrp_plugin_t *mrp_ref_plugin(mrp_plugin_t *plugin)
444 {
445     return mrp_ref_obj(plugin, refcnt);
446 }
447
448
449 static inline int mrp_unref_plugin(mrp_plugin_t *plugin)
450 {
451     return mrp_unref_obj(plugin, refcnt);
452 }
453
454
455 #endif /* __MURPHY_PLUGIN_H__ */