X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-export.c;h=cabb485825e2a06782f0c8f98737a904345ea33c;hb=42099d3e2bd791f64c75ce333a71a42d8c053698;hp=799ad73e72fe9dffd7ce218e7398808971de08fa;hpb=bebb8fa967f3b71b609119b293d2869d56036586;p=src%2Fapp-framework-binder.git diff --git a/src/afb-export.c b/src/afb-export.c index 799ad73e..cabb4858 100644 --- a/src/afb-export.c +++ b/src/afb-export.c @@ -24,6 +24,9 @@ #include #include +#if !defined(JSON_C_TO_STRING_NOSLASHESCAPE) +#define JSON_C_TO_STRING_NOSLASHESCAPE 0 +#endif #define AFB_BINDING_VERSION 0 #include @@ -48,6 +51,7 @@ #include "jobs.h" #include "verbose.h" #include "sig-monitor.h" +#include "wrap-json.h" /************************************************************************* * internal types @@ -136,6 +140,15 @@ struct afb_export /* event handler list */ struct event_handler *event_handlers; + /* creator if any */ + struct afb_export *creator; + + /* path indication if any */ + const char *path; + + /* settings */ + struct json_object *settings; + /* internal descriptors */ union { #if defined(WITH_LEGACY_BINDING_V1) @@ -192,6 +205,54 @@ struct afb_api_x3 *afb_export_to_api_x3(struct afb_export *export) return to_api_x3(export); } +/****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ****************************************************************************** + SETTINGS + ****************************************************************************** + ****************************************************************************** + ****************************************************************************** + ******************************************************************************/ + +static struct json_object *configuration; + +void afb_export_set_config(struct json_object *config) +{ + struct json_object *save = configuration; + configuration = json_object_get(config); + json_object_put(save); +} + +static struct json_object *make_settings(struct afb_export *export) +{ + struct json_object *result; + struct json_object *obj; + struct afb_export *iter; + char *path; + + /* clone the globals */ + if (json_object_object_get_ex(configuration, "*", &obj)) + result = wrap_json_clone(obj); + else + result = json_object_new_object(); + + /* add locals */ + if (json_object_object_get_ex(configuration, export->name, &obj)) + wrap_json_object_add(result, obj); + + /* add library path */ + for (iter = export ; iter && !iter->path ; iter = iter->creator); + if (iter) { + path = realpath(iter->path, NULL); + json_object_object_add(result, "binding-path", json_object_new_string(path)); + free(path); + } + + export->settings = result; + return result; +} + /****************************************************************************** ****************************************************************************** ****************************************************************************** @@ -213,7 +274,7 @@ static void vverbose_cb(struct afb_api_x3 *closure, int level, const char *file, if (!fmt || vasprintf(&p, fmt, args) < 0) vverbose(level, file, line, function, fmt, args); else { - verbose(level, file, line, function, "[API %s] %s", export->api.apiname, p); + verbose(level, file, line, function, (verbose_is_colorized() == 0 ? "[API %s] %s" : COLOR_API "[API %s]" COLOR_DEFAULT " %s"), export->api.apiname, p); free(p); } } @@ -252,7 +313,8 @@ static int event_broadcast_cb(struct afb_api_x3 *closure, const char *name, stru /* check daemon state */ if (export->state == Api_State_Pre_Init) { - ERROR("[API %s] Bad call to 'afb_daemon_event_broadcast(%s, %s)', must not be in PreInit", export->api.apiname, name, json_object_to_json_string(object)); + ERROR("[API %s] Bad call to 'afb_daemon_event_broadcast(%s, %s)', must not be in PreInit", + export->api.apiname, name, json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE)); errno = EINVAL; return 0; } @@ -290,6 +352,11 @@ static int require_api_cb(struct afb_api_x3 *closure, const char *name, int init int rc, rc2; char *iter, *end, save; + /* emit a warning about unexpected require in preinit */ + if (export->state == Api_State_Pre_Init) + WARNING("[API %s] requiring apis in pre-init may lead to unexpected result (requires%s: %s)", + export->api.apiname, initialized ? " initialized" : "", name); + /* scan the names in a local copy */ rc = 0; iter = strdupa(name); @@ -342,7 +409,11 @@ static struct afb_api_x3 *api_new_api_cb( void *preinit_closure) { struct afb_export *export = from_api_x3(closure); - struct afb_api_v3 *apiv3 = afb_api_v3_create(export->declare_set, export->call_set, api, info, noconcurrency, preinit, preinit_closure, 1); + struct afb_api_v3 *apiv3 = afb_api_v3_create( + export->declare_set, export->call_set, + api, info, noconcurrency, + preinit, preinit_closure, 1, + export, NULL); return apiv3 ? to_api_x3(afb_api_v3_export(apiv3)) : NULL; } @@ -863,6 +934,15 @@ static int delete_api_cb(struct afb_api_x3 *api) return 0; } +static struct json_object *settings_cb(struct afb_api_x3 *api) +{ + struct afb_export *export = from_api_x3(api); + struct json_object *result = export->settings; + if (!result) + result = make_settings(export); + return result; +} + static int hooked_api_set_verbs_v2_cb( struct afb_api_x3 *api, const struct afb_verb_v2 *verbs) @@ -976,6 +1056,14 @@ static int hooked_delete_api_cb(struct afb_api_x3 *api) return result; } +static struct json_object *hooked_settings_cb(struct afb_api_x3 *api) +{ + struct afb_export *export = from_api_x3(api); + struct json_object *result = settings_cb(api); + result = afb_hook_api_settings(export, result); + return result; +} + static const struct afb_api_x3_itf api_x3_itf = { .vverbose = (void*)vverbose_cb, @@ -1014,6 +1102,7 @@ static const struct afb_api_x3_itf api_x3_itf = { .class_require = class_require_cb, .delete_api = delete_api_cb, + .settings = settings_cb, }; static const struct afb_api_x3_itf hooked_api_x3_itf = { @@ -1054,6 +1143,7 @@ static const struct afb_api_x3_itf hooked_api_x3_itf = { .class_require = hooked_class_require_cb, .delete_api = hooked_delete_api_cb, + .settings = hooked_settings_cb, }; /****************************************************************************** @@ -1082,7 +1172,7 @@ static void listener_of_events(void *closure, const char *event, int eventid, st /* search the handler */ handler = export->event_handlers; while (handler) { - if (fnmatch(handler->pattern, event, 0)) { + if (!fnmatch(handler->pattern, event, 0)) { if (!(export->hooksvc & afb_hook_flag_api_on_event_handler)) handler->callback(handler->closure, event, object, to_api_x3(export)); else { @@ -1149,7 +1239,7 @@ int afb_export_event_handler_add( } /* create the event */ - handler = malloc(strlen(pattern) + strlen(pattern)); + handler = malloc(strlen(pattern) + sizeof * handler); if (!handler) { ERROR("[API %s] can't allocate event handler %s", export->api.apiname, pattern); errno = ENOMEM; @@ -1161,7 +1251,7 @@ int afb_export_event_handler_add( handler->callback = callback; handler->closure = closure; strcpy(handler->pattern, pattern); - export->event_handlers = handler; + *previous = handler; return 0; } @@ -1208,9 +1298,11 @@ static struct afb_export *create( struct afb_apiset *declare_set, struct afb_apiset *call_set, const char *apiname, + const char *path, enum afb_api_version version) { struct afb_export *export; + size_t lenapi; /* session shared with other exports */ if (common_session == NULL) { @@ -1218,13 +1310,18 @@ static struct afb_export *create( if (common_session == NULL) return NULL; } - export = calloc(1, sizeof *export + strlen(apiname)); + lenapi = strlen(apiname); + export = calloc(1, sizeof *export + lenapi + (path == apiname || !path ? 0 : strlen(path))); if (!export) errno = ENOMEM; else { export->refcount = 1; strcpy(export->name, apiname); export->api.apiname = export->name; + if (path == apiname) + export->path = export->name; + else if (path) + export->path = strcpy(&export->name[lenapi + 1], path); export->version = version; export->state = Api_State_Pre_Init; export->session = afb_session_addref(common_session); @@ -1261,6 +1358,8 @@ void afb_export_destroy(struct afb_export *export) afb_session_unref(export->session); afb_apiset_unref(export->declare_set); afb_apiset_unref(export->call_set); + json_object_put(export->settings); + afb_export_unref(export->creator); if (export->api.apiname != export->name) free((void*)export->api.apiname); free(export); @@ -1274,7 +1373,7 @@ struct afb_export *afb_export_create_none_for_path( int (*creator)(void*, struct afb_api_x3*), void *closure) { - struct afb_export *export = create(declare_set, call_set, path, Api_Version_None); + struct afb_export *export = create(declare_set, call_set, path, path, Api_Version_None); if (export) { afb_export_logmask_set(export, logmask); afb_export_update_hooks(export); @@ -1287,14 +1386,14 @@ struct afb_export *afb_export_create_none_for_path( } #if defined(WITH_LEGACY_BINDING_V1) -struct afb_export *afb_export_create_v1( - struct afb_apiset *declare_set, +struct afb_export *afb_export_create_v1(struct afb_apiset *declare_set, struct afb_apiset *call_set, const char *apiname, int (*init)(struct afb_service_x1), - void (*onevent)(const char*, struct json_object*)) + void (*onevent)(const char*, struct json_object*), + const char* path) { - struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_1); + struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_1); if (export) { export->init.v1 = init; export->on_any_event_v12 = onevent; @@ -1307,16 +1406,16 @@ struct afb_export *afb_export_create_v1( } #endif -struct afb_export *afb_export_create_v2( - struct afb_apiset *declare_set, +struct afb_export *afb_export_create_v2(struct afb_apiset *declare_set, struct afb_apiset *call_set, const char *apiname, const struct afb_binding_v2 *binding, struct afb_binding_data_v2 *data, int (*init)(), - void (*onevent)(const char*, struct json_object*)) + void (*onevent)(const char*, struct json_object*), + const char* path) { - struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_2); + struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_2); if (export) { export->init.v2 = init; export->on_any_event_v12 = onevent; @@ -1333,12 +1432,15 @@ struct afb_export *afb_export_create_v2( struct afb_export *afb_export_create_v3(struct afb_apiset *declare_set, struct afb_apiset *call_set, const char *apiname, - struct afb_api_v3 *apiv3) + struct afb_api_v3 *apiv3, + struct afb_export* creator, + const char* path) { - struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_3); + struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_3); if (export) { export->unsealed = 1; export->desc.v3 = apiv3; + export->creator = afb_export_addref(creator); afb_export_logmask_set(export, logmask); afb_export_update_hooks(export); } @@ -1729,7 +1831,7 @@ int afb_export_declare(struct afb_export *export, ERROR("can't declare export %s to set %s, ABORTING it!", export->api.apiname, afb_apiset_name(export->declare_set)); - afb_export_addref(export); + afb_export_unref(export); } } @@ -1762,5 +1864,6 @@ void afb_export_process_xreq(struct afb_export *export, struct afb_xreq *xreq) void afb_export_context_init(struct afb_export *export, struct afb_context *context) { afb_context_init(context, export->session, NULL); + context->validated = 1; }