X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-export.c;h=3afd8c14597fb40660228665c9da9fdfb81a6327;hb=de0527f7cf5b4a4278698ab034a332cf75723300;hp=fbf77f8660b541822a2cef01a3b23ee99a9710f8;hpb=4521c1e7ae5371ab9d639adc617d17fb4e8ded0c;p=src%2Fapp-framework-binder.git diff --git a/src/afb-export.c b/src/afb-export.c index fbf77f86..3afd8c14 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 @@ -47,6 +50,8 @@ #include "afb-calls.h" #include "jobs.h" #include "verbose.h" +#include "sig-monitor.h" +#include "wrap-json.h" /************************************************************************* * internal types @@ -135,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) @@ -191,6 +205,50 @@ 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; + + /* 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) + json_object_object_add(result, "binding-path", json_object_new_string(iter->path)); + + export->settings = result; + return result; +} + /****************************************************************************** ****************************************************************************** ****************************************************************************** @@ -251,7 +309,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; } @@ -341,7 +400,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; } @@ -862,6 +925,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) @@ -975,6 +1047,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, @@ -1013,6 +1093,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 = { @@ -1053,6 +1134,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, }; /****************************************************************************** @@ -1148,7 +1230,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; @@ -1160,7 +1242,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; } @@ -1207,9 +1289,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) { @@ -1217,13 +1301,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); @@ -1260,6 +1349,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); @@ -1273,7 +1364,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); @@ -1286,14 +1377,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; @@ -1306,16 +1397,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; @@ -1332,12 +1423,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); } @@ -1511,28 +1605,63 @@ void afb_export_userdata_set(struct afb_export *export, void *data) ****************************************************************************** ******************************************************************************/ -int afb_export_start(struct afb_export *export, int share_session, int onneed) +struct init { + int return_code; + struct afb_export *export; +}; + +static void do_init(int sig, void *closure) +{ + int rc = -1; + struct init *init = closure; + struct afb_export *export; + + if (sig) + errno = EFAULT; + else { + export = init->export; + switch (export->version) { +#if defined(WITH_LEGACY_BINDING_V1) + case Api_Version_1: + rc = export->init.v1 ? export->init.v1( + (struct afb_service_x1){ + .itf = &hooked_service_itf, + .closure = to_api_x3(export) }) : 0; + break; +#endif + case Api_Version_2: + rc = export->init.v2 ? export->init.v2() : 0; + break; + case Api_Version_3: + rc = export->init.v3 ? export->init.v3(to_api_x3(export)) : 0; + break; + default: + errno = EINVAL; + break; + } + } + init->return_code = rc; +}; + + +int afb_export_start(struct afb_export *export) +{ + struct init init; int rc; /* check state */ - if (export->state != Api_State_Pre_Init) { - /* not an error when onneed */ - if (onneed != 0) - goto done; + switch (export->state) { + case Api_State_Run: + return 0; - /* already started: it is an error */ - ERROR("Service of API %s already started", export->api.apiname); + case Api_State_Init: + /* starting in progress: it is an error */ + ERROR("Service of API %s required started while starting", export->api.apiname); return -1; - } - /* unshare the session if asked */ - if (!share_session) { - rc = afb_export_unshare_session(export); - if (rc < 0) { - ERROR("Can't unshare the session for %s", export->api.apiname); - return -1; - } + default: + break; } /* set event handling */ @@ -1541,9 +1670,11 @@ int afb_export_start(struct afb_export *export, int share_session, int onneed) case Api_Version_1: #endif case Api_Version_2: - if (export->on_any_event_v12) + if (export->on_any_event_v12) { rc = afb_export_handle_events_v12(export, export->on_any_event_v12); - break; + break; + } + /*@fallthrough@*/ default: rc = 0; break; @@ -1558,23 +1689,9 @@ int afb_export_start(struct afb_export *export, int share_session, int onneed) afb_hook_api_start_before(export); export->state = Api_State_Init; - switch (export->version) { -#if defined(WITH_LEGACY_BINDING_V1) - case Api_Version_1: - rc = export->init.v1 ? export->init.v1((struct afb_service_x1){ .itf = &hooked_service_itf, .closure = to_api_x3(export) }) : 0; - break; -#endif - case Api_Version_2: - rc = export->init.v2 ? export->init.v2() : 0; - break; - case Api_Version_3: - rc = export->init.v3 ? export->init.v3(to_api_x3(export)) : 0; - break; - default: - errno = EINVAL; - rc = -1; - break; - } + init.export = export; + sig_monitor(0, do_init, &init); + rc = init.return_code; export->state = Api_State_Run; if (export->hooksvc & afb_hook_flag_api_start) @@ -1586,7 +1703,6 @@ int afb_export_start(struct afb_export *export, int share_session, int onneed) return rc; } -done: return 0; } @@ -1638,11 +1754,11 @@ static struct json_object *api_describe_cb(void *closure) return result; } -static int api_service_start_cb(void *closure, int share_session, int onneed) +static int api_service_start_cb(void *closure) { struct afb_export *export = closure; - return afb_export_start(export, share_session, onneed); + return afb_export_start(export); } static void api_update_hooks_cb(void *closure) @@ -1706,7 +1822,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); } } @@ -1739,5 +1855,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; }