2 * Copyright (C) 2016, 2017 "IoT.bzh"
3 * Author José Bollo <jose.bollo@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
22 #include <json-c/json.h>
25 #include "afb-apiset.h"
30 extern struct afb_apiset *main_apiset;
32 /* CAUTION! KEEP VERBS SORTED */
39 * Declare functions of verbs
41 #define F(x) static void f_##x(struct afb_xreq *xreq)
47 * Name of the known verbs
51 void (*function)(struct afb_xreq*);
53 #define V(x) { .name = #x, .function = f_##x },
59 * get the function of a verb
60 * @param verb the name of the verb
61 * @return the function for the verb or NULL when no verb of name exists
63 static void (*lookfun(const char *verb))(struct afb_xreq*)
68 u = (int)(sizeof verbs / sizeof *verbs);
71 c = strcmp(verb, verbs[i].name);
73 return verbs[i].function;
82 static void call_cb(void *closure, struct afb_xreq *xreq)
84 void (*fun)(struct afb_xreq*);
86 fun = lookfun(xreq->verb);
88 afb_xreq_fail_unknown_verb(xreq);
93 static struct afb_api_itf monitor_api_itf = {
97 int afb_monitor_init()
101 api.itf = &monitor_api_itf;
102 return afb_apiset_add(main_apiset, "monitor", api);
105 /******************************************************************************
106 **** Monitoring verbosity
107 ******************************************************************************/
109 static const char _debug_[] = "debug";
110 static const char _info_[] = "info";
111 static const char _notice_[] = "notice";
112 static const char _warning_[] = "warning";
113 static const char _error_[] = "error";
116 * Translate verbosity indication to an integer value.
117 * @param v the verbosity indication
118 * @return the verbosity level (0, 1, 2 or 3) or -1 in case of error
120 static int decode_verbosity(struct json_object *v)
124 if (json_object_is_type(v, json_type_int)) {
125 level = json_object_get_int(v);
126 level = level < 0 ? 0 : level > 3 ? 3 : level;
127 } else if (json_object_is_type(v, json_type_string)) {
128 s = json_object_get_string(v);
131 if (!strcasecmp(s, _debug_))
135 if (!strcasecmp(s, _info_))
139 if (!strcasecmp(s, _notice_))
143 if (!strcasecmp(s, _warning_))
147 if (!strcasecmp(s, _error_))
156 * callback for setting verbosity on all apis
157 * @param set the apiset
158 * @param the name of the api to set
159 * @param closure the verbosity to set as an integer casted to a pointer
161 static void set_verbosity_to_all_cb(struct afb_apiset *set, const char *name, void *closure)
163 afb_apiset_set_verbosity(set, name, (int)(intptr_t)closure);
167 * set the verbosity 'level' of the api of 'name'
168 * @param name the api name or "*" for any api or NULL or "" for global verbosity
169 * @param level the verbosity level to set
171 static void set_verbosity_to(const char *name, int level)
173 if (!name || !name[0])
175 else if (name[0] == '*' && !name[1])
176 afb_apiset_enum(main_apiset, set_verbosity_to_all_cb, (void*)(intptr_t)level);
178 afb_apiset_set_verbosity(main_apiset, name, level);
182 * Set verbosities accordling to specification in 'spec'
183 * @param spec specification of the verbosity to set
185 static void set_verbosity(struct json_object *spec)
188 struct json_object_iterator it, end;
190 if (json_object_is_type(spec, json_type_object)) {
191 it = json_object_iter_begin(spec);
192 end = json_object_iter_end(spec);
193 while (!json_object_iter_equal(&it, &end)) {
194 l = decode_verbosity(json_object_iter_peek_value(&it));
196 set_verbosity_to(json_object_iter_peek_name(&it), l);
197 json_object_iter_next(&it);
200 l = decode_verbosity(spec);
202 set_verbosity_to("", l);
203 set_verbosity_to("*", l);
209 * Translate verbosity level to a protocol indication.
210 * @param level the verbosity
211 * @return the encoded verbosity
213 static struct json_object *encode_verbosity(int level)
216 case 0: return json_object_new_string(_error_);
217 case 1: return json_object_new_string(_notice_);
218 case 2: return json_object_new_string(_info_);
219 case 3: return json_object_new_string(_debug_);
220 default: return json_object_new_int(level);
225 * callback for getting verbosity of all apis
226 * @param set the apiset
227 * @param the name of the api to set
228 * @param closure the json object to build
230 static void get_verbosity_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
232 struct json_object *resu = closure;
233 int l = afb_apiset_get_verbosity(set, name);
235 json_object_object_add(resu, name, encode_verbosity(l));
239 * get in resu the verbosity of the api of 'name'
240 * @param resu the json object to build
241 * @param name the api name or "*" for any api or NULL or "" for global verbosity
243 static void get_verbosity_of(struct json_object *resu, const char *name)
246 if (!name || !name[0])
247 json_object_object_add(resu, "", encode_verbosity(verbosity));
248 else if (name[0] == '*' && !name[1])
249 afb_apiset_enum(main_apiset, get_verbosity_of_all_cb, resu);
251 l = afb_apiset_get_verbosity(main_apiset, name);
253 json_object_object_add(resu, name, encode_verbosity(l));
258 * get verbosities accordling to specification in 'spec'
259 * @param resu the json object to build
260 * @param spec specification of the verbosity to set
262 static void get_verbosity(struct json_object *resu, struct json_object *spec)
265 struct json_object_iterator it, end;
267 if (json_object_is_type(spec, json_type_object)) {
268 it = json_object_iter_begin(spec);
269 end = json_object_iter_end(spec);
270 while (!json_object_iter_equal(&it, &end)) {
271 get_verbosity_of(resu, json_object_iter_peek_name(&it));
272 json_object_iter_next(&it);
274 } else if (json_object_is_type(spec, json_type_array)) {
275 n = json_object_array_length(spec);
276 for (i = 0 ; i < n ; i++)
277 get_verbosity_of(resu, json_object_get_string(json_object_array_get_idx(spec, i)));
278 } else if (json_object_get_boolean(spec)) {
279 get_verbosity_of(resu, "");
280 get_verbosity_of(resu, "*");
284 /******************************************************************************
286 ******************************************************************************/
289 * get apis accordling to specification in 'spec'
290 * @param resu the json object to build
291 * @param spec specification of the verbosity to set
293 static void get_one_api(struct json_object *resu, const char *name, struct json_object *spec)
295 struct json_object *o;
299 rc = afb_apiset_lookup(main_apiset, name, &api);
301 o = api.itf->describe ? api.itf->describe(api.closure) : NULL;
302 json_object_object_add(resu, name, o);
307 * callback for getting verbosity of all apis
308 * @param set the apiset
309 * @param the name of the api to set
310 * @param closure the json object to build
312 static void get_apis_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
314 struct json_object *resu = closure;
315 get_one_api(resu, name, NULL);
319 * get apis accordling to specification in 'spec'
320 * @param resu the json object to build
321 * @param spec specification of the verbosity to set
323 static void get_apis(struct json_object *resu, struct json_object *spec)
326 struct json_object_iterator it, end;
328 if (json_object_is_type(spec, json_type_object)) {
329 it = json_object_iter_begin(spec);
330 end = json_object_iter_end(spec);
331 while (!json_object_iter_equal(&it, &end)) {
332 get_one_api(resu, json_object_iter_peek_name(&it), json_object_iter_peek_value(&it));
333 json_object_iter_next(&it);
335 } else if (json_object_is_type(spec, json_type_array)) {
336 n = json_object_array_length(spec);
337 for (i = 0 ; i < n ; i++)
338 get_one_api(resu, json_object_get_string(json_object_array_get_idx(spec, i)), NULL);
339 } else if (json_object_get_boolean(spec)) {
340 afb_apiset_enum(main_apiset, get_apis_of_all_cb, resu);
344 /******************************************************************************
345 **** Implementation monitoring verbs
346 ******************************************************************************/
348 static const char _verbosity_[] = "verbosity";
349 static const char _apis_[] = "apis";
351 static void f_get(struct afb_xreq *xreq)
353 struct json_object *o, *v, *r, *x;
355 r = json_object_new_object();
356 o = afb_xreq_json(xreq);
358 if (json_object_object_get_ex(o, _verbosity_, &v)) {
359 x = json_object_new_object();
360 json_object_object_add(r, _verbosity_, x);
364 if (json_object_object_get_ex(o, _apis_, &v)) {
365 x = json_object_new_object();
366 json_object_object_add(r, _apis_, x);
371 afb_xreq_success(xreq, json_object_get(r), NULL);
375 static void f_set(struct afb_xreq *xreq)
377 struct json_object *o, *v;
379 o = afb_xreq_json(xreq);
380 if (json_object_object_get_ex(o, _verbosity_, &v)) {
385 afb_xreq_success(xreq, NULL, NULL);
388 static void f_hook(struct afb_xreq *xreq)
390 struct json_object *o, *v;
392 o = afb_xreq_json(xreq);
393 if (json_object_object_get_ex(o, _verbosity_, &v)) {
398 afb_xreq_success(xreq, NULL, NULL);