X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-v3.c;h=1381c18b7d66d1029dfa6ac395dbaa12f9fdbeb0;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=8c755f9430050c19d8e67918bae8d63cf0c7321d;hpb=4521c1e7ae5371ab9d639adc617d17fb4e8ded0c;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-v3.c b/src/afb-api-v3.c index 8c755f94..1381c18b 100644 --- a/src/afb-api-v3.c +++ b/src/afb-api-v3.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2017, 2018 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ #include "afb-export.h" #include "afb-xreq.h" #include "verbose.h" +#include "sig-monitor.h" /* * Description of a binding @@ -43,7 +44,9 @@ struct afb_api_v3 { int refcount; int count; struct afb_verb_v3 **verbs; +#if WITH_LEGACY_BINDING_V2 const struct afb_verb_v2 *verbsv2; +#endif const struct afb_verb_v3 *verbsv3; struct afb_export *export; const char *info; @@ -76,7 +79,9 @@ static struct afb_verb_v3 *search_dynamic_verb(struct afb_api_v3 *api, const cha void afb_api_v3_process_call(struct afb_api_v3 *api, struct afb_xreq *xreq) { const struct afb_verb_v3 *verbsv3; +#if WITH_LEGACY_BINDING_V2 const struct afb_verb_v2 *verbsv2; +#endif const char *name; name = xreq->request.called_verb; @@ -103,6 +108,7 @@ void afb_api_v3_process_call(struct afb_api_v3 *api, struct afb_xreq *xreq) return; } +#if WITH_LEGACY_BINDING_V2 /* look in legacy set */ verbsv2 = api->verbsv2; if (verbsv2) { @@ -115,15 +121,38 @@ void afb_api_v3_process_call(struct afb_api_v3 *api, struct afb_xreq *xreq) } } } - +#endif afb_xreq_reply_unknown_verb(xreq); } +static struct json_object *describe_verb_v3(const struct afb_verb_v3 *verb) +{ + struct json_object *f, *a, *g; + + f = json_object_new_object(); + + g = json_object_new_object(); + json_object_object_add(f, "get", g); + + a = afb_auth_json_x2(verb->auth, verb->session); + if (a) + json_object_object_add(g, "x-permissions", a); + + a = json_object_new_object(); + json_object_object_add(g, "responses", a); + g = json_object_new_object(); + json_object_object_add(a, "200", g); + json_object_object_add(g, "description", json_object_new_string(verb->info?:verb->verb)); + + return f; +} + struct json_object *afb_api_v3_make_description_openAPIv3(struct afb_api_v3 *api, const char *apiname) { char buffer[256]; - struct afb_verb_v3 **iter, **end, *verb; - struct json_object *r, *f, *a, *i, *p, *g; + struct afb_verb_v3 **iter, **end; + const struct afb_verb_v3 *verb; + struct json_object *r, *i, *p; r = json_object_new_object(); json_object_object_add(r, "openapi", json_object_new_string("3.0.0")); @@ -134,50 +163,47 @@ struct json_object *afb_api_v3_make_description_openAPIv3(struct afb_api_v3 *api json_object_object_add(i, "version", json_object_new_string("0.0.0")); json_object_object_add(i, "description", json_object_new_string(api->info)); + buffer[0] = '/'; + buffer[sizeof buffer - 1] = 0; + p = json_object_new_object(); json_object_object_add(r, "paths", p); iter = api->verbs; end = iter + api->count; while (iter != end) { verb = *iter++; - buffer[0] = '/'; - strncpy(buffer + 1, verb->verb, sizeof buffer - 1); - buffer[sizeof buffer - 1] = 0; - f = json_object_new_object(); - json_object_object_add(p, buffer, f); - g = json_object_new_object(); - json_object_object_add(f, "get", g); - - a = afb_auth_json_v2(verb->auth, verb->session); - if (a) - json_object_object_add(g, "x-permissions", a); - - a = json_object_new_object(); - json_object_object_add(g, "responses", a); - f = json_object_new_object(); - json_object_object_add(a, "200", f); - json_object_object_add(f, "description", json_object_new_string(verb->info?:verb->verb)); + strncpy(buffer + 1, verb->verb, sizeof buffer - 2); + json_object_object_add(p, buffer, describe_verb_v3(verb)); } + verb = api->verbsv3; + if (verb) + while(verb->verb) { + strncpy(buffer + 1, verb->verb, sizeof buffer - 2); + json_object_object_add(p, buffer, describe_verb_v3(verb)); + verb++; + } return r; } -struct afb_api_v3 *afb_api_v3_create( - struct afb_apiset *declare_set, +struct afb_api_v3 *afb_api_v3_create(struct afb_apiset *declare_set, struct afb_apiset *call_set, const char *apiname, const char *info, int noconcurrency, int (*preinit)(void*, struct afb_api_x3 *), void *closure, - int copy_info -) + int copy_info, + struct afb_export* creator, + const char* path) { struct afb_api_v3 *api; /* allocates the description */ api = calloc(1, sizeof *api + (copy_info && info ? 1 + strlen(info) : 0)); - if (!api) + if (!api) { + ERROR("out of memory"); goto oom; + } api->refcount = 1; if (!info) api->info = &nulchar; @@ -186,7 +212,7 @@ struct afb_api_v3 *afb_api_v3_create( else api->info = info; - api->export = afb_export_create_v3(declare_set, call_set, apiname, api); + api->export = afb_export_create_v3(declare_set, call_set, apiname, api, creator, path); if (!api->export) goto oom2; @@ -205,7 +231,6 @@ oom3: oom2: free(api); oom: - ERROR("out of memory"); return NULL; } @@ -220,6 +245,9 @@ void afb_api_v3_unref(struct afb_api_v3 *api) { if (api && !__atomic_sub_fetch(&api->refcount, 1, __ATOMIC_RELAXED)) { afb_export_destroy(api->export); + while (api->count) + free(api->verbs[--api->count]); + free(api->verbs); free(api); } } @@ -229,12 +257,14 @@ struct afb_export *afb_api_v3_export(struct afb_api_v3 *api) return api->export; } +#if WITH_LEGACY_BINDING_V2 void afb_api_v3_set_verbs_v2( struct afb_api_v3 *api, const struct afb_verb_v2 *verbs) { api->verbsv2 = verbs; } +#endif void afb_api_v3_set_verbs_v3( struct afb_api_v3 *api, @@ -303,19 +333,16 @@ int afb_api_v3_del_verb( const char *verb, void **vcbdata) { - struct afb_verb_v3 **v, **e, *i; + struct afb_verb_v3 *v; + int i; - v = api->verbs; - e = &v[api->count]; - while (v != e) { - i = *v++; - if (!strcasecmp(i->verb, verb)) { - api->count--; + for (i = 0 ; i < api->count ; i++) { + v = api->verbs[i]; + if (!strcasecmp(verb, v->verb)) { + api->verbs[i] = api->verbs[--api->count]; if (vcbdata) - *vcbdata = i->vcbdata; - if (v != e) - *--v = *--e; - free(i); + *vcbdata = v->vcbdata; + free(v); return 0; } } @@ -338,21 +365,49 @@ int afb_api_v3_set_binding_fields(const struct afb_binding_v3 *desc, struct afb_ if (!rc && desc->require_class) rc = afb_api_x3_require_class(api, desc->require_class); if (!rc && desc->require_api) - rc = afb_api_x3_require_api(api, desc->require_api, 1); + rc = afb_api_x3_require_api(api, desc->require_api, 0); return rc; } +struct safe_preinit_data +{ + int (*preinit)(struct afb_api_x3 *); + struct afb_api_x3 *api; + int result; +}; + +static void safe_preinit(int sig, void *closure) +{ + struct safe_preinit_data *spd = closure; + if (!sig) + spd->result = spd->preinit(spd->api); + else { + spd->result = -1; + errno = EFAULT; + } +} + +int afb_api_v3_safe_preinit(struct afb_api_x3 *api, int (*preinit)(struct afb_api_x3 *)) +{ + struct safe_preinit_data spd; + + spd.preinit = preinit; + spd.api = api; + sig_monitor(60, safe_preinit, &spd); + return spd.result; +} + static int init_binding(void *closure, struct afb_api_x3 *api) { const struct afb_binding_v3 *desc = closure; int rc = afb_api_v3_set_binding_fields(desc, api); if (!rc && desc->preinit) - rc = desc->preinit(api); + rc = afb_api_v3_safe_preinit(api, desc->preinit); return rc; } struct afb_api_v3 *afb_api_v3_from_binding(const struct afb_binding_v3 *desc, struct afb_apiset *declare_set, struct afb_apiset * call_set) { - return afb_api_v3_create(declare_set, call_set, desc->api, desc->info, desc->noconcurrency, init_binding, (void*)desc, 0); + return afb_api_v3_create(declare_set, call_set, desc->api, desc->info, desc->noconcurrency, init_binding, (void*)desc, 0, NULL, NULL); }