X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-monitor.c;h=18ea606b32a2ee74f7b31c7b32d0f31492d08950;hb=428dd77c7ef528dd1769d7c9bb95cd0fb2eaf2a8;hp=5d5c12d1f1d7ace74d9a5c322e5cd867f3540117;hpb=1164734afd826ca8cef0a624aa4f4c59ecb1e228;p=src%2Fapp-framework-binder.git diff --git a/src/afb-monitor.c b/src/afb-monitor.c index 5d5c12d1..18ea606b 100644 --- a/src/afb-monitor.c +++ b/src/afb-monitor.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2017 "IoT.bzh" + * Copyright (C) 2016, 2017, 2018 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,85 +21,28 @@ #include +#define AFB_BINDING_VERSION 0 +#include + #include "afb-api.h" #include "afb-apiset.h" -#include "afb-ditf.h" +#include "afb-api-so-v2.h" +#include "afb-evt.h" #include "afb-xreq.h" +#include "afb-trace.h" +#include "afb-session.h" #include "verbose.h" +#include "wrap-json.h" -extern struct afb_apiset *main_apiset; - -/* CAUTION! KEEP VERBS SORTED */ -#define VERBS \ - V(get) \ - V(hook) \ - V(set) - -/** - * Declare functions of verbs - */ -#define F(x) static void f_##x(struct afb_xreq *xreq) -#define V(x) F(x); - VERBS -#undef V - -/** - * Name of the known verbs - */ -static const struct { - const char *name; - void (*function)(struct afb_xreq*); -} verbs[] = { -#define V(x) { .name = #x, .function = f_##x }, - VERBS -#undef V -}; - -/** - * get the function of a verb - * @param verb the name of the verb - * @return the function for the verb or NULL when no verb of name exists - */ -static void (*lookfun(const char *verb))(struct afb_xreq*) -{ - int l, u, i, c; - - l = 0; - u = (int)(sizeof verbs / sizeof *verbs); - while (l < u) { - i = (l + u) >> 1; - c = strcmp(verb, verbs[i].name); - if (c == 0) - return verbs[i].function; - if (c < 0) - u = i; - else - l = i + 1; - } - return NULL; -} - -static void call_cb(void *closure, struct afb_xreq *xreq) -{ - void (*fun)(struct afb_xreq*); +#include "monitor-api.inc" - fun = lookfun(xreq->verb); - if (!fun) - afb_xreq_fail_unknown_verb(xreq); - else - fun(xreq); -} +extern struct afb_apiset *main_apiset; -static struct afb_api_itf monitor_api_itf = { - .call = call_cb -}; +static struct afb_binding_data_v2 datav2; int afb_monitor_init() { - struct afb_api api; - api.closure = NULL; - api.itf = &monitor_api_itf; - return afb_apiset_add(main_apiset, "monitor", api); + return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &datav2); } /****************************************************************************** @@ -121,31 +64,30 @@ static int decode_verbosity(struct json_object *v) { const char *s; int level = -1; - if (json_object_is_type(v, json_type_int)) { - level = json_object_get_int(v); - level = level < 0 ? 0 : level > 3 ? 3 : level; - } else if (json_object_is_type(v, json_type_string)) { - s = json_object_get_string(v); + + if (!wrap_json_unpack(v, "i", &level)) { + level = level < Verbosity_Level_Error ? Verbosity_Level_Error : level > Verbosity_Level_Debug ? Verbosity_Level_Debug : level; + } else if (!wrap_json_unpack(v, "s", &s)) { switch(*s&~' ') { case 'D': if (!strcasecmp(s, _debug_)) - level = 3; + level = Verbosity_Level_Debug; break; case 'I': if (!strcasecmp(s, _info_)) - level = 2; + level = Verbosity_Level_Info; break; case 'N': if (!strcasecmp(s, _notice_)) - level = 1; + level = Verbosity_Level_Notice; break; case 'W': if (!strcasecmp(s, _warning_)) - level = 1; + level = Verbosity_Level_Warning; break; case 'E': if (!strcasecmp(s, _error_)) - level = 0; + level = Verbosity_Level_Error; break; } } @@ -173,7 +115,7 @@ static void set_verbosity_to(const char *name, int level) if (!name || !name[0]) verbosity = level; else if (name[0] == '*' && !name[1]) - afb_apiset_enum(main_apiset, set_verbosity_to_all_cb, (void*)(intptr_t)level); + afb_apiset_enum(main_apiset, 1, set_verbosity_to_all_cb, (void*)(intptr_t)level); else afb_apiset_set_verbosity(main_apiset, name, level); } @@ -207,16 +149,17 @@ static void set_verbosity(struct json_object *spec) /** * Translate verbosity level to a protocol indication. - * @param level the verbosity + * @param level the verbosity * @return the encoded verbosity */ static struct json_object *encode_verbosity(int level) { switch(level) { - case 0: return json_object_new_string(_error_); - case 1: return json_object_new_string(_notice_); - case 2: return json_object_new_string(_info_); - case 3: return json_object_new_string(_debug_); + case Verbosity_Level_Error: return json_object_new_string(_error_); + case Verbosity_Level_Warning: return json_object_new_string(_warning_); + case Verbosity_Level_Notice: return json_object_new_string(_notice_); + case Verbosity_Level_Info: return json_object_new_string(_info_); + case Verbosity_Level_Debug: return json_object_new_string(_debug_); default: return json_object_new_int(level); } } @@ -246,7 +189,7 @@ static void get_verbosity_of(struct json_object *resu, const char *name) if (!name || !name[0]) json_object_object_add(resu, "", encode_verbosity(verbosity)); else if (name[0] == '*' && !name[1]) - afb_apiset_enum(main_apiset, get_verbosity_of_all_cb, resu); + afb_apiset_enum(main_apiset, 1, get_verbosity_of_all_cb, resu); else { l = afb_apiset_get_verbosity(main_apiset, name); if (l >= 0) @@ -259,11 +202,13 @@ static void get_verbosity_of(struct json_object *resu, const char *name) * @param resu the json object to build * @param spec specification of the verbosity to set */ -static void get_verbosity(struct json_object *resu, struct json_object *spec) +static struct json_object *get_verbosity(struct json_object *spec) { int i, n; + struct json_object *resu; struct json_object_iterator it, end; + resu = json_object_new_object(); if (json_object_is_type(spec, json_type_object)) { it = json_object_iter_begin(spec); end = json_object_iter_end(spec); @@ -275,10 +220,13 @@ static void get_verbosity(struct json_object *resu, struct json_object *spec) n = json_object_array_length(spec); for (i = 0 ; i < n ; i++) get_verbosity_of(resu, json_object_get_string(json_object_array_get_idx(spec, i))); + } else if (json_object_is_type(spec, json_type_string)) { + get_verbosity_of(resu, json_object_get_string(spec)); } else if (json_object_get_boolean(spec)) { get_verbosity_of(resu, ""); get_verbosity_of(resu, "*"); } + return resu; } /****************************************************************************** @@ -293,14 +241,10 @@ static void get_verbosity(struct json_object *resu, struct json_object *spec) static void get_one_api(struct json_object *resu, const char *name, struct json_object *spec) { struct json_object *o; - struct afb_api api; - int rc; - rc = afb_apiset_lookup(main_apiset, name, &api); - if (!rc) { - o = api.itf->describe ? api.itf->describe(api.closure) : NULL; + o = afb_apiset_describe(main_apiset, name); + if (o || afb_apiset_lookup(main_apiset, name, 1)) json_object_object_add(resu, name, o); - } } /** @@ -320,11 +264,13 @@ static void get_apis_of_all_cb(struct afb_apiset *set, const char *name, void *c * @param resu the json object to build * @param spec specification of the verbosity to set */ -static void get_apis(struct json_object *resu, struct json_object *spec) +static struct json_object *get_apis(struct json_object *spec) { int i, n; + struct json_object *resu; struct json_object_iterator it, end; + resu = json_object_new_object(); if (json_object_is_type(spec, json_type_object)) { it = json_object_iter_begin(spec); end = json_object_iter_end(spec); @@ -336,9 +282,12 @@ static void get_apis(struct json_object *resu, struct json_object *spec) n = json_object_array_length(spec); for (i = 0 ; i < n ; i++) get_one_api(resu, json_object_get_string(json_object_array_get_idx(spec, i)), NULL); + } else if (json_object_is_type(spec, json_type_string)) { + get_one_api(resu, json_object_get_string(spec), NULL); } else if (json_object_get_boolean(spec)) { - afb_apiset_enum(main_apiset, get_apis_of_all_cb, resu); + afb_apiset_enum(main_apiset, 1, get_apis_of_all_cb, resu); } + return resu; } /****************************************************************************** @@ -347,54 +296,95 @@ static void get_apis(struct json_object *resu, struct json_object *spec) static const char _verbosity_[] = "verbosity"; static const char _apis_[] = "apis"; +static const char _refresh_token_[] = "refresh-token"; -static void f_get(struct afb_xreq *xreq) +static void f_get(struct afb_req req) { - struct json_object *o, *v, *r, *x; + struct json_object *r; + struct json_object *apis = NULL; + struct json_object *verbosity = NULL; + + wrap_json_unpack(afb_req_json(req), "{s?:o,s?:o}", _verbosity_, &verbosity, _apis_, &apis); + if (verbosity) + verbosity = get_verbosity(verbosity); + if (apis) + apis = get_apis(apis); + + wrap_json_pack(&r, "{s:o*,s:o*}", _verbosity_, verbosity, _apis_, apis); + afb_req_success(req, r, NULL); +} - r = json_object_new_object(); - o = afb_xreq_json(xreq); +static void f_set(struct afb_req req) +{ + struct json_object *verbosity = NULL; - if (json_object_object_get_ex(o, _verbosity_, &v)) { - x = json_object_new_object(); - json_object_object_add(r, _verbosity_, x); - get_verbosity(x, v); - } + wrap_json_unpack(afb_req_json(req), "{s?:o}", _verbosity_, &verbosity); + if (verbosity) + set_verbosity(verbosity); - if (json_object_object_get_ex(o, _apis_, &v)) { - x = json_object_new_object(); - json_object_object_add(r, _apis_, x); - get_apis(x, v); - } + afb_req_success(req, NULL, NULL); +} - if (!xreq->replied) - afb_xreq_success(xreq, json_object_get(r), NULL); - json_object_put(r); +static void *context_create() +{ + return afb_trace_create(_afb_binding_v2_monitor.api, NULL); } -static void f_set(struct afb_xreq *xreq) +static void context_destroy(void *pointer) { - struct json_object *o, *v; + struct afb_trace *trace = pointer; + afb_trace_unref(trace); +} - o = afb_xreq_json(xreq); - if (json_object_object_get_ex(o, _verbosity_, &v)) { - set_verbosity(v); +static void f_trace(struct afb_req req) +{ + int rc; + struct json_object *add = NULL; + struct json_object *drop = NULL; + struct afb_trace *trace; + + trace = afb_req_context(req, context_create, context_destroy); + wrap_json_unpack(afb_req_json(req), "{s?o s?o}", "add", &add, "drop", &drop); + if (add) { + rc = afb_trace_add(req, add, trace); + if (rc) + goto end; } - - if (!xreq->replied) - afb_xreq_success(xreq, NULL, NULL); + if (drop) { + rc = afb_trace_drop(req, drop, trace); + if (rc) + goto end; + } + afb_req_success(req, NULL, NULL); +end: + afb_apiset_update_hooks(main_apiset, NULL); + afb_evt_update_hooks(); } -static void f_hook(struct afb_xreq *xreq) +static void f_session(struct afb_req req) { - struct json_object *o, *v; - - o = afb_xreq_json(xreq); - if (json_object_object_get_ex(o, _verbosity_, &v)) { - set_verbosity(v); + struct json_object *r = NULL; + int refresh = 0; + struct afb_xreq *xreq = xreq_from_request(req.closure); + + /* check right to call it */ + if (xreq->context.super) { + afb_req_fail(req, "invalid", "reserved to direct clients"); + return; } - if (!xreq->replied) - afb_xreq_success(xreq, NULL, NULL); + /* renew the token if required */ + wrap_json_unpack(afb_req_json(req), "{s?:b}", _refresh_token_, &refresh); + if (refresh) + afb_context_refresh(&xreq->context); + + /* make the result */ + wrap_json_pack(&r, "{s:s,s:s,s:i,s:i}", + "uuid", afb_session_uuid(xreq->context.session), + "token", afb_session_token(xreq->context.session), + "timeout", afb_session_timeout(xreq->context.session), + "remain", afb_session_what_remains(xreq->context.session)); + afb_req_success(req, r, NULL); } +