Asterisk - The Open Source Telephony Project  18.5.0
json.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * David M. Lee, II <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief JSON abstraction layer.
22  *
23  * This is a very thin wrapper around the Jansson API. For more details on it,
24  * see its docs at http://www.digip.org/jansson/doc/2.11/apiref.html.
25  *
26  * \author David M. Lee, II <[email protected]>
27  */
28 
29 /*** MODULEINFO
30  <depend>jansson</depend>
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 #include "asterisk/json.h"
37 #include "asterisk/localtime.h"
38 #include "asterisk/module.h"
39 #include "asterisk/utils.h"
40 #include "asterisk/astobj2.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/callerid.h"
43 
44 #include <jansson.h>
45 #include <time.h>
46 
47 void *ast_json_malloc(size_t size)
48 {
49  return ast_malloc(size);
50 }
51 
52 void ast_json_free(void *p)
53 {
54  ast_free(p);
55 }
56 
57 void ast_json_set_alloc_funcs(void *(*malloc_fn)(size_t), void (*free_fn)(void*))
58 {
59  json_set_alloc_funcs(malloc_fn, free_fn);
60 }
61 
63 {
64  json_set_alloc_funcs(ast_json_malloc, ast_json_free);
65 }
66 
67 struct ast_json *ast_json_ref(struct ast_json *json)
68 {
69  json_incref((json_t *)json);
70  return json;
71 }
72 
73 void ast_json_unref(struct ast_json *json)
74 {
75  json_decref((json_t *) json);
76 }
77 
78 enum ast_json_type ast_json_typeof(const struct ast_json *json)
79 {
80  int r = json_typeof((json_t*)json);
81  switch(r) {
82  case JSON_OBJECT: return AST_JSON_OBJECT;
83  case JSON_ARRAY: return AST_JSON_ARRAY;
84  case JSON_STRING: return AST_JSON_STRING;
85  case JSON_INTEGER: return AST_JSON_INTEGER;
86  case JSON_REAL: return AST_JSON_REAL;
87  case JSON_TRUE: return AST_JSON_TRUE;
88  case JSON_FALSE: return AST_JSON_FALSE;
89  case JSON_NULL: return AST_JSON_NULL;
90  }
91  ast_assert(0); /* Unexpect return from json_typeof */
92  return r;
93 }
94 
96 {
97  switch (type) {
98  case AST_JSON_OBJECT: return "object";
99  case AST_JSON_ARRAY: return "array";
100  case AST_JSON_STRING: return "string";
101  case AST_JSON_INTEGER: return "integer";
102  case AST_JSON_REAL: return "real";
103  case AST_JSON_TRUE: return "boolean";
104  case AST_JSON_FALSE: return "boolean";
105  case AST_JSON_NULL: return "null";
106  }
107  ast_assert(0);
108  return "?";
109 }
110 
111 /* Ported from libjansson utf.c:utf8_check_first() */
112 static size_t json_utf8_check_first(char byte)
113 {
114  unsigned char ch = (unsigned char) byte;
115 
116  if (ch < 0x80) {
117  return 1;
118  }
119 
120  if (0x80 <= ch && ch <= 0xBF) {
121  /* second, third or fourth byte of a multi-byte
122  sequence, i.e. a "continuation byte" */
123  return 0;
124  } else if (ch == 0xC0 || ch == 0xC1) {
125  /* overlong encoding of an ASCII byte */
126  return 0;
127  } else if (0xC2 <= ch && ch <= 0xDF) {
128  /* 2-byte sequence */
129  return 2;
130  } else if (0xE0 <= ch && ch <= 0xEF) {
131  /* 3-byte sequence */
132  return 3;
133  } else if (0xF0 <= ch && ch <= 0xF4) {
134  /* 4-byte sequence */
135  return 4;
136  } else { /* ch >= 0xF5 */
137  /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
138  UTF-8 */
139  return 0;
140  }
141 }
142 
143 /* Ported from libjansson utf.c:utf8_check_full() */
144 static size_t json_utf8_check_full(const char *str, size_t len)
145 {
146  size_t pos;
147  int32_t value;
148  unsigned char ch = (unsigned char) str[0];
149 
150  if (len == 2) {
151  value = ch & 0x1F;
152  } else if (len == 3) {
153  value = ch & 0xF;
154  } else if (len == 4) {
155  value = ch & 0x7;
156  } else {
157  return 0;
158  }
159 
160  for (pos = 1; pos < len; ++pos) {
161  ch = (unsigned char) str[pos];
162  if (ch < 0x80 || ch > 0xBF) {
163  /* not a continuation byte */
164  return 0;
165  }
166 
167  value = (value << 6) + (ch & 0x3F);
168  }
169 
170  if (value > 0x10FFFF) {
171  /* not in Unicode range */
172  return 0;
173  } else if (0xD800 <= value && value <= 0xDFFF) {
174  /* invalid code point (UTF-16 surrogate halves) */
175  return 0;
176  } else if ((len == 2 && value < 0x80)
177  || (len == 3 && value < 0x800)
178  || (len == 4 && value < 0x10000)) {
179  /* overlong encoding */
180  return 0;
181  }
182 
183  return 1;
184 }
185 
186 int ast_json_utf8_check_len(const char *str, size_t len)
187 {
188  size_t pos;
189  size_t count;
190  int res = 1;
191 
192  if (!str) {
193  return 0;
194  }
195 
196  /*
197  * Since the json library does not make the check function
198  * public we recreate/copy the function in our interface
199  * module.
200  *
201  * Loop ported from libjansson utf.c:utf8_check_string()
202  */
203  for (pos = 0; pos < len; pos += count) {
204  count = json_utf8_check_first(str[pos]);
205  if (count == 0) {
206  res = 0;
207  break;
208  } else if (count > 1) {
209  if (count > len - pos) {
210  /* UTF-8 needs more than we have left in the string. */
211  res = 0;
212  break;
213  }
214 
215  if (!json_utf8_check_full(&str[pos], count)) {
216  res = 0;
217  break;
218  }
219  }
220  }
221 
222  if (!res) {
223  ast_debug(1, "String '%.*s' is not UTF-8 for json conversion\n", (int) len, str);
224  }
225  return res;
226 }
227 
228 int ast_json_utf8_check(const char *str)
229 {
230  return str ? ast_json_utf8_check_len(str, strlen(str)) : 0;
231 }
232 
233 struct ast_json *ast_json_true(void)
234 {
235  return (struct ast_json *)json_true();
236 }
237 
239 {
240  return (struct ast_json *)json_false();
241 }
242 
244 {
245  return (struct ast_json *)json_boolean(value);
246 }
247 
248 struct ast_json *ast_json_null(void)
249 {
250  return (struct ast_json *)json_null();
251 }
252 
253 int ast_json_is_true(const struct ast_json *json)
254 {
255  return json_is_true((const json_t *)json);
256 }
257 
258 int ast_json_is_false(const struct ast_json *json)
259 {
260  return json_is_false((const json_t *)json);
261 }
262 
263 int ast_json_is_null(const struct ast_json *json)
264 {
265  return json_is_null((const json_t *)json);
266 }
267 
269 {
270  return (struct ast_json *)json_string(value);
271 }
272 
273 const char *ast_json_string_get(const struct ast_json *string)
274 {
275  return json_string_value((json_t *)string);
276 }
277 
278 int ast_json_string_set(struct ast_json *string, const char *value)
279 {
280  return json_string_set((json_t *)string, value);
281 }
282 
283 struct ast_json *ast_json_stringf(const char *format, ...)
284 {
285  struct ast_json *ret;
286  va_list args;
287  va_start(args, format);
288  ret = ast_json_vstringf(format, args);
289  va_end(args);
290  return ret;
291 }
292 
293 struct ast_json *ast_json_vstringf(const char *format, va_list args)
294 {
295  json_t *ret = NULL;
296 
297  if (format) {
298  /* json_pack was not introduced until jansson-2.0 so Asterisk could never
299  * be compiled against older versions. The version check can never match
300  * anything older than 2.12. */
301 #if defined(HAVE_JANSSON_BUNDLED) || JANSSON_MAJOR_VERSION > 2 || JANSSON_MINOR_VERSION > 11
302  ret = json_vsprintf(format, args);
303 #else
304  char *str = NULL;
305  int err = ast_vasprintf(&str, format, args);
306 
307  if (err >= 0) {
308  ret = json_string(str);
309  ast_free(str);
310  }
311 #endif
312  }
313 
314  return (struct ast_json *)ret;
315 }
316 
318 {
319  return (struct ast_json *)json_integer(value);
320 }
321 
322 intmax_t ast_json_integer_get(const struct ast_json *integer)
323 {
324  return json_integer_value((json_t *)integer);
325 }
326 
328 {
329  return json_integer_set((json_t *)integer, value);
330 }
331 
333 {
334  return (struct ast_json *)json_real(value);
335 }
336 
337 double ast_json_real_get(const struct ast_json *real)
338 {
339  return json_real_value((json_t *)real);
340 }
341 
342 int ast_json_real_set(struct ast_json *real, double value)
343 {
344  return json_real_set((json_t *)real, value);
345 }
346 
347 int ast_json_equal(const struct ast_json *lhs, const struct ast_json *rhs)
348 {
349  return json_equal((json_t *)lhs, (json_t *)rhs);
350 }
351 
353 {
354  return (struct ast_json *)json_array();
355 }
356 size_t ast_json_array_size(const struct ast_json *array)
357 {
358  return json_array_size((json_t *)array);
359 }
360 struct ast_json *ast_json_array_get(const struct ast_json *array, size_t index)
361 {
362  return (struct ast_json *)json_array_get((json_t *)array, index);
363 }
364 int ast_json_array_set(struct ast_json *array, size_t index, struct ast_json *value)
365 {
366  return json_array_set_new((json_t *)array, index, (json_t *)value);
367 }
369 {
370  return json_array_append_new((json_t *)array, (json_t *)value);
371 }
372 int ast_json_array_insert(struct ast_json *array, size_t index, struct ast_json *value)
373 {
374  return json_array_insert_new((json_t *)array, index, (json_t *)value);
375 }
376 int ast_json_array_remove(struct ast_json *array, size_t index)
377 {
378  return json_array_remove((json_t *)array, index);
379 }
381 {
382  return json_array_clear((json_t *)array);
383 }
384 int ast_json_array_extend(struct ast_json *array, struct ast_json *tail)
385 {
386  return json_array_extend((json_t *)array, (json_t *)tail);
387 }
388 
390 {
391  return (struct ast_json *)json_object();
392 }
393 size_t ast_json_object_size(struct ast_json *object)
394 {
395  return json_object_size((json_t *)object);
396 }
397 struct ast_json *ast_json_object_get(struct ast_json *object, const char *key)
398 {
399  if (!key) {
400  return NULL;
401  }
402  return (struct ast_json *)json_object_get((json_t *)object, key);
403 }
404 int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
405 {
406  return json_object_set_new((json_t *)object, key, (json_t *)value);
407 }
408 int ast_json_object_del(struct ast_json *object, const char *key)
409 {
410  return json_object_del((json_t *)object, key);
411 }
412 int ast_json_object_clear(struct ast_json *object)
413 {
414  return json_object_clear((json_t *)object);
415 }
416 int ast_json_object_update(struct ast_json *object, struct ast_json *other)
417 {
418  return json_object_update((json_t *)object, (json_t *)other);
419 }
420 int ast_json_object_update_existing(struct ast_json *object, struct ast_json *other)
421 {
422  return json_object_update_existing((json_t *)object, (json_t *)other);
423 }
424 int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other)
425 {
426  return json_object_update_missing((json_t *)object, (json_t *)other);
427 }
428 
430 {
431  return json_object_iter((json_t *)object);
432 }
433 struct ast_json_iter *ast_json_object_iter_at(struct ast_json *object, const char *key)
434 {
435  return json_object_iter_at((json_t *)object, key);
436 }
437 struct ast_json_iter *ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
438 {
439  return json_object_iter_next((json_t *)object, iter);
440 }
441 const char *ast_json_object_iter_key(struct ast_json_iter *iter)
442 {
443  return json_object_iter_key(iter);
444 }
446 {
447  return (struct ast_json *)json_object_iter_value(iter);
448 }
449 int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value)
450 {
451  return json_object_iter_set_new((json_t *)object, iter, (json_t *)value);
452 }
453 
454 /*!
455  * \brief Default flags for JSON encoding.
456  */
458 {
459  return format == AST_JSON_PRETTY ?
460  JSON_INDENT(2) | JSON_PRESERVE_ORDER : JSON_COMPACT;
461 }
462 
464 {
465  return json_dumps((json_t *)root, dump_flags(format));
466 }
467 
468 static int write_to_ast_str(const char *buffer, size_t size, void *data)
469 {
470  struct ast_str **dst = data;
471  size_t str_size = ast_str_size(*dst);
472  size_t remaining = str_size - ast_str_strlen(*dst);
473  int ret;
474 
475  /* While ast_str_append will grow the ast_str, it won't report
476  * allocation errors. Fortunately, it's not that hard.
477  */
478 
479  /* Remaining needs to be big enough for buffer, plus null char */
480  while (remaining < size + 1) {
481  /* doubling the size of the buffer gives us 'amortized
482  * constant' time.
483  * See http://stackoverflow.com/a/249695/115478 for info.
484  */
485  str_size *= 2;
486  remaining = str_size - ast_str_strlen(*dst);
487  }
488 
489  ret = ast_str_make_space(dst, str_size);
490  if (ret == -1) {
491  /* Could not alloc; fail */
492  return -1;
493  }
494 
495  ast_str_append_substr(dst, -1, buffer, size);
496  return 0;
497 }
498 
500 {
501  return json_dump_callback((json_t *)root, write_to_ast_str, dst, dump_flags(format));
502 }
503 
504 
506 {
507  if (!root || !output) {
508  return -1;
509  }
510  return json_dumpf((json_t *)root, output, dump_flags(format));
511 }
513 {
514  if (!root || !path) {
515  return -1;
516  }
517  return json_dump_file((json_t *)root, path, dump_flags(format));
518 }
519 
520 /*!
521  * \brief Copy Jansson error struct to ours.
522  */
523 static void copy_error(struct ast_json_error *error, const json_error_t *jansson_error)
524 {
525  if (error && jansson_error) {
526  error->line = jansson_error->line;
527  error->column = jansson_error->column;
528  error->position = jansson_error->position;
529  ast_copy_string(error->text, jansson_error->text, sizeof(error->text));
530  ast_copy_string(error->source, jansson_error->source, sizeof(error->source));
531  }
532 
533 }
534 
535 static void parse_error(struct ast_json_error *error, const char *text, const char *source)
536 {
537  if (error != NULL) {
538  error->line = 0;
539  error->column = 0;
540  error->position = 0;
541  strncpy(error->text, text, sizeof(error->text));
542  strncpy(error->source, source, sizeof(error->text));
543  }
544 }
545 
547 {
548  json_error_t jansson_error = {};
549  struct ast_json *r = NULL;
550  if (input != NULL) {
551  r = (struct ast_json *)json_loads(input, 0, &jansson_error);
552  copy_error(error, &jansson_error);
553  } else {
554  parse_error(error, "NULL input string", "<null>");
555  }
556  return r;
557 }
558 
560 {
561  return ast_json_load_string(ast_str_buffer(input), error);
562 }
563 
564 struct ast_json *ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
565 {
566  json_error_t jansson_error = {};
567  struct ast_json *r = (struct ast_json *)json_loadb(buffer, buflen, 0, &jansson_error);
568  copy_error(error, &jansson_error);
569  return r;
570 }
572 {
573  json_error_t jansson_error = {};
574  struct ast_json *r = NULL;
575  if (input != NULL) {
576  r = (struct ast_json *)json_loadf(input, 0, &jansson_error);
577  copy_error(error, &jansson_error);
578  } else {
579  parse_error(error, "NULL input file", "<null>");
580  }
581  return r;
582 }
583 struct ast_json *ast_json_load_new_file(const char *path, struct ast_json_error *error)
584 {
585  json_error_t jansson_error = {};
586  struct ast_json *r = (struct ast_json *)json_load_file(path, 0, &jansson_error);
587  copy_error(error, &jansson_error);
588  return r;
589 }
590 
591 struct ast_json *ast_json_pack(char const *format, ...)
592 {
593  struct ast_json *ret;
594  va_list args;
595  va_start(args, format);
596  ret = ast_json_vpack(format, args);
597  va_end(args);
598  return ret;
599 }
600 struct ast_json *ast_json_vpack(char const *format, va_list ap)
601 {
602  json_error_t error;
603  struct ast_json *r = NULL;
604  if (format) {
605  r = (struct ast_json *)json_vpack_ex(&error, 0, format, ap);
606  if (!r && !ast_strlen_zero(error.text)) {
608  "Error building JSON from '%s': %s.\n",
609  format, error.text);
611  }
612  }
613  return r;
614 }
615 
616 struct ast_json *ast_json_copy(const struct ast_json *value)
617 {
618  return (struct ast_json *)json_copy((json_t *)value);
619 }
621 {
622  return (struct ast_json *)json_deep_copy((json_t *)value);
623 }
624 
625 struct ast_json *ast_json_name_number(const char *name, const char *number)
626 {
627  return ast_json_pack("{s: s, s: s}",
628  "name", AST_JSON_UTF8_VALIDATE(name),
629  "number", AST_JSON_UTF8_VALIDATE(number));
630 }
631 
633  const char *context, const char *exten, int priority, const char *app_name, const char *app_data)
634 {
635  return ast_json_pack("{s: s?, s: s?, s: o, s: s?, s: s?}",
636  "context", context,
637  "exten", exten,
638  "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null(),
639  "app_name", app_name,
640  "app_data", app_data
641  );
642 }
643 
644 struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority)
645 {
646  return ast_json_dialplan_cep_app(context, exten, priority, "", "");
647 }
648 
649 struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone)
650 {
651  char buf[AST_ISO8601_LEN];
652  struct ast_tm tm = {};
653 
654  ast_localtime(&tv, &tm, zone);
655 
656  ast_strftime(buf, sizeof(buf),AST_ISO8601_FORMAT, &tm);
657 
658  return ast_json_string_create(buf);
659 }
660 
661 struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type)
662 {
663  struct ast_str *string = ast_str_alloca(64);
664 
665  if (!string) {
666  return NULL;
667  }
668 
669  ast_str_set(&string, 0, (ast_sockaddr_is_ipv4(addr) ||
670  ast_sockaddr_is_ipv4_mapped(addr)) ? "IPV4/" : "IPV6/");
671 
672  if (transport_type) {
673  char *transport_string = NULL;
674 
675  /* NOTE: None will be applied if multiple transport types are specified in transport_type */
676  switch(transport_type) {
677  case AST_TRANSPORT_UDP:
678  transport_string = "UDP";
679  break;
680  case AST_TRANSPORT_TCP:
681  transport_string = "TCP";
682  break;
683  case AST_TRANSPORT_TLS:
684  transport_string = "TLS";
685  break;
686  case AST_TRANSPORT_WS:
687  transport_string = "WS";
688  break;
689  case AST_TRANSPORT_WSS:
690  transport_string = "WSS";
691  break;
692  }
693 
694  if (transport_string) {
695  ast_str_append(&string, 0, "%s/", transport_string);
696  }
697  }
698 
699  ast_str_append(&string, 0, "%s", ast_sockaddr_stringify_addr(addr));
700  ast_str_append(&string, 0, "/%s", ast_sockaddr_stringify_port(addr));
701 
702  return ast_json_string_create(ast_str_buffer(string));
703 }
704 
705 int ast_json_init(void)
706 {
707  json_t *version_check;
708 
709  /* Setup to use Asterisk custom allocators */
711 
712  /* We depend on functionality of jansson-2.11 but don't actually use
713  * any symbols. If we link at runtime to less than 2.11 this json_pack
714  * will return NULL. */
715  version_check = json_pack("{s: o?, s: o*}",
716  "JSON", NULL,
717  "Bourne", NULL);
718  if (!version_check) {
719  ast_log(LOG_ERROR, "There was a problem finding jansson 2.11 runtime libraries.\n"
720  "Please rebuild Asterisk using ./configure --with-jansson-bundled.\n");
721  return -1;
722  }
723 
724  json_decref(version_check);
725 
726  return 0;
727 }
728 
729 static void json_payload_destructor(void *obj)
730 {
731  struct ast_json_payload *payload = obj;
732  ast_json_unref(payload->json);
733 }
734 
736 {
737  struct ast_json_payload *payload;
738 
739  if (!(payload = ao2_alloc(sizeof(*payload), json_payload_destructor))) {
740  return NULL;
741  }
742 
743  ast_json_ref(json);
744  payload->json = json;
745 
746  return payload;
747 }
748 
750 {
751  if (!number->valid) {
752  return NULL;
753  }
754  return ast_json_pack("{s: s, s: i, s: i, s: s}",
755  "number", AST_JSON_UTF8_VALIDATE(number->str),
756  "plan", number->plan,
757  "presentation", number->presentation,
758  "presentation_txt", ast_describe_caller_presentation(number->presentation));
759 }
760 
762 {
763  if (!name->valid) {
764  return NULL;
765  }
766  return ast_json_pack("{s: s, s: s, s: i, s: s}",
767  "name", AST_JSON_UTF8_VALIDATE(name->str),
768  "character_set", ast_party_name_charset_describe(name->char_set),
769  "presentation", name->presentation,
770  "presentation_txt", ast_describe_caller_presentation(name->presentation));
771 }
772 
773 static struct ast_json *json_party_subaddress(struct ast_party_subaddress *subaddress)
774 {
775  if (!subaddress->valid) {
776  return NULL;
777  }
778  return ast_json_pack("{s: s, s: i, s: b}",
779  "subaddress", AST_JSON_UTF8_VALIDATE(subaddress->str),
780  "type", subaddress->type,
781  "odd", subaddress->odd_even_indicator);
782 }
783 
785 {
786  int pres = ast_party_id_presentation(party);
787 
788  /* Combined party presentation */
789  return ast_json_pack("{s: i, s: s, s: o*, s: o*, s: o*}",
790  "presentation", pres,
791  "presentation_txt", ast_describe_caller_presentation(pres),
792  "number", json_party_number(&party->number),
793  "name", json_party_name(&party->name),
794  "subaddress", json_party_subaddress(&party->subaddress));
795 }
796 
797 enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
798 {
799  struct ast_json_iter *it_json_var;
800  struct ast_variable *tail = NULL;
801 
802  *variables = NULL;
803 
804  for (it_json_var = ast_json_object_iter(json_variables); it_json_var;
805  it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) {
806  struct ast_variable *new_var;
807  const char *key = ast_json_object_iter_key(it_json_var);
808  const char *value;
809  struct ast_json *json_value;
810 
811  if (ast_strlen_zero(key)) {
812  continue;
813  }
814 
815  json_value = ast_json_object_iter_value(it_json_var);
816  if (ast_json_typeof(json_value) != AST_JSON_STRING) {
817  /* Error: Only strings allowed */
818  ast_variables_destroy(*variables);
819  *variables = NULL;
821  }
822  value = ast_json_string_get(json_value);
823  /* Should never be NULL. Otherwise, how could it be a string type? */
824  ast_assert(value != NULL);
825  if (!value) {
826  /* To be safe. */
827  continue;
828  }
829  new_var = ast_variable_new(key, value, "");
830  if (!new_var) {
831  /* Error: OOM */
832  ast_variables_destroy(*variables);
833  *variables = NULL;
835  }
836 
837  tail = ast_variable_list_append_hint(variables, tail, new_var);
838  }
839 
841 }
842 
843 struct ast_json *ast_json_channel_vars(struct varshead *channelvars)
844 {
845  struct ast_json *ret;
846  struct ast_var_t *var;
847 
848  ret = ast_json_object_create();
849  AST_LIST_TRAVERSE(channelvars, var, entries) {
851  }
852 
853  return ret;
854 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_json * ast_json_vpack(char const *format, va_list ap)
Helper for creating complex JSON values simply.
Definition: json.c:600
static const char type[]
Definition: chan_ooh323.c:109
Information needed to identify an endpoint in a call.
Definition: channel.h:339
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:278
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
int ast_json_utf8_check_len(const char *str, size_t len)
Check the string of the given length for UTF-8 format.
Definition: json.c:186
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
Definition: json.c:445
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
struct ast_json * ast_json_ref(struct ast_json *json)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_load_str(const struct ast_str *input, struct ast_json_error *error)
Parse ast_str into a JSON object or array.
Definition: json.c:559
Asterisk main include file. File version handling, generic pbx functions.
static void json_payload_destructor(void *obj)
Definition: json.c:729
size_t ast_json_object_size(struct ast_json *object)
Get size of JSON object.
Definition: json.c:393
int ast_json_object_clear(struct ast_json *object)
Delete all elements from a JSON object.
Definition: json.c:412
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
static struct ast_json * json_party_subaddress(struct ast_party_subaddress *subaddress)
Definition: json.c:773
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
int position
Definition: json.h:835
void * ast_json_malloc(size_t size)
Asterisk&#39;s custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:47
char text[AST_JSON_ERROR_TEXT_LENGTH]
Definition: json.h:837
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1164
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
Time-related functions and macros.
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
int ast_json_array_extend(struct ast_json *array, struct ast_json *tail)
Append all elements from tail to array.
Definition: json.c:384
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
ast_transport
Definition: netsock2.h:59
Iterator for JSON object key/values.
int ast_json_array_set(struct ast_json *array, size_t index, struct ast_json *value)
Change an element in an array.
Definition: json.c:364
struct ast_json * ast_json_copy(const struct ast_json *value)
Copy a JSON value, but not its children.
Definition: json.c:616
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
void ast_json_reset_alloc_funcs(void)
Change alloc funcs back to the resource module defaults.
Definition: json.c:62
static struct ast_json * json_party_number(struct ast_party_number *number)
Definition: json.c:749
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct ast_json * json
Definition: json.h:1025
ast_json_type
Valid types of a JSON element.
Definition: json.h:162
int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value)
Set the value of the field pointed to by an iterator.
Definition: json.c:449
int ast_json_dump_file_format(struct ast_json *root, FILE *output, enum ast_json_encoding_format format)
Encode a JSON value to a FILE.
Definition: json.c:505
int char_set
Character set the name is using.
Definition: channel.h:273
char * str
Subscriber name (Malloced)
Definition: channel.h:265
#define AST_ISO8601_LEN
Max length of an null terminated, millisecond resolution, ISO8601 timestamp string.
Definition: localtime.h:105
int ast_json_is_false(const struct ast_json *json)
Check if value is JSON false.
Definition: json.c:258
struct ast_json * ast_json_channel_vars(struct varshead *channelvars)
Construct a JSON object from a ast_var_t list.
Definition: json.c:843
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:329
static size_t json_utf8_check_full(const char *str, size_t len)
Definition: json.c:144
#define ast_assert(a)
Definition: utils.h:695
char * text
Definition: app_queue.c:1508
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define ast_vasprintf(ret, fmt, ap)
A wrapper for vasprintf()
Definition: astmm.h:280
struct ast_json * ast_json_load_file(FILE *input, struct ast_json_error *error)
Parse a FILE into JSON object or array.
Definition: json.c:571
const char * str
Definition: app_jack.c:147
const char * args
char * str
Malloced subaddress string.
Definition: channel.h:314
#define NULL
Definition: resample.c:96
char * ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format)
Encode a JSON value to a string.
Definition: json.c:463
int value
Definition: syslog.c:37
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1584
static int priority
Socket address structure.
Definition: netsock2.h:97
unsigned char odd_even_indicator
TRUE if odd number of address signals.
Definition: channel.h:327
struct ast_json * ast_json_dialplan_cep_app(const char *context, const char *exten, int priority, const char *app_name, const char *app_data)
Construct a context/exten/priority/application/application_data as JSON.
Definition: json.c:632
JSON parsing error information.
Definition: json.h:829
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
Utility functions.
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition: json.c:389
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_log_backtrace(void)
Log a backtrace of the current thread&#39;s execution stack to the Asterisk log.
Definition: logger.c:2158
int ast_json_array_clear(struct ast_json *array)
Remove all elements from an array.
Definition: json.c:380
Number structure.
Definition: app_followme.c:154
Conversion failed because invalid value type supplied.
Definition: json.h:1058
struct ast_json * ast_json_true(void)
Get the JSON true value.
Definition: json.c:233
Custom localtime functions for multiple timezones.
struct ast_json * ast_json_name_number(const char *name, const char *number)
Common JSON rendering functions for common &#39;objects&#39;.
Definition: json.c:625
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:404
struct ast_json * ast_json_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
Definition: json.c:546
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
Asterisk JSON abstraction layer.
#define AST_ISO8601_FORMAT
ast_strftime for ISO8601 formatting timestamps.
Definition: localtime.h:103
struct ast_json * ast_json_load_new_file(const char *path, struct ast_json_error *error)
Parse file at path into JSON object or array.
Definition: json.c:583
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
Definition: strings.h:1014
struct ast_json * ast_json_stringf(const char *format,...)
Create a JSON string, printf style.
Definition: json.c:283
int ast_json_array_insert(struct ast_json *array, size_t index, struct ast_json *value)
Insert into an array.
Definition: json.c:372
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:368
static void parse_error(struct ast_json_error *error, const char *text, const char *source)
Definition: json.c:535
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
struct ast_json * ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
Parse buffer with known length into a JSON object or array.
Definition: json.c:564
#define ast_variable_new(name, value, filename)
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:322
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:360
enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
Convert a ast_json list of key/value pair tuples into a ast_variable list.
Definition: json.c:797
struct ast_variable * ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *new_var)
Appends a variable list to the end of another list.
Definition: main/config.c:648
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition: json.c:735
int ast_json_array_remove(struct ast_json *array, size_t index)
Remove an element from an array.
Definition: json.c:376
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
Definition: json.c:441
static struct ast_json * json_party_name(struct ast_party_name *name)
Definition: json.c:761
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:345
int ast_json_utf8_check(const char *str)
Check the nul terminated string for UTF-8 format.
Definition: json.c:228
Conversion successful.
Definition: json.h:1053
char name[0]
Definition: chanvars.h:31
#define LOG_ERROR
Definition: logger.h:285
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_json_free(void *p)
Asterisk&#39;s custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
static void copy_error(struct ast_json_error *error, const json_error_t *jansson_error)
Copy Jansson error struct to ours.
Definition: json.c:523
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
int column
Definition: json.h:833
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
struct ast_json * ast_json_dialplan_cep(const char *context, const char *exten, int priority)
Construct a context/exten/priority as JSON.
Definition: json.c:644
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * value
Definition: chanvars.h:30
enum ast_json_type ast_json_typeof(const struct ast_json *json)
Get the type of value.
Definition: json.c:78
float real
Definition: lpc10.h:79
void ast_json_set_alloc_funcs(void *(*malloc_fn)(size_t), void(*free_fn)(void *))
Set custom allocators instead of the standard ast_malloc() and ast_free().
Definition: json.c:57
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other)
Add new fields to object with the fields of other.
Definition: json.c:424
int ast_json_equal(const struct ast_json *lhs, const struct ast_json *rhs)
Compare two JSON objects.
Definition: json.c:347
Conversion failed because of allocation failure. (Out Of Memory)
Definition: json.h:1060
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
struct ast_var_t::@249 entries
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:507
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
void ast_json_unref(struct ast_json *json)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_json_integer_set(struct ast_json *integer, intmax_t value)
Set the value of a JSON integer.
Definition: json.c:327
struct ast_json * ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type)
Construct an IP address as JSON.
Definition: json.c:661
struct ast_json * ast_json_real_create(double value)
Create a JSON real number.
Definition: json.c:332
struct ast_json * ast_json_vstringf(const char *format, va_list args)
Create a JSON string, vprintf style.
Definition: json.c:293
double ast_json_real_get(const struct ast_json *real)
Get the value from a JSON real number.
Definition: json.c:337
struct ast_json_iter * ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
Get the next iterator.
Definition: json.c:437
char source[AST_JSON_ERROR_TEXT_LENGTH]
Definition: json.h:839
int type
Q.931 subaddress type.
Definition: channel.h:321
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
int ast_json_string_set(struct ast_json *string, const char *value)
Change the value of a JSON string.
Definition: json.c:278
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
Definition: json.c:429
static size_t json_utf8_check_first(char byte)
Definition: json.c:112
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
Information needed to specify a number in a call.
Definition: channel.h:290
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
struct ast_json * ast_json_deep_copy(const struct ast_json *value)
Copy a JSON value, and its children.
Definition: json.c:620
Abstract JSON element (object, array, string, int, ...).
const char * ast_json_typename(enum ast_json_type type)
Get the string name for the given type.
Definition: json.c:95
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
int error(const char *format,...)
Definition: utils/frame.c:999
int ast_json_is_true(const struct ast_json *json)
Check if value is JSON true.
Definition: json.c:253
int ast_json_is_null(const struct ast_json *json)
Check if value is JSON null.
Definition: json.c:263
int int32_t
Definition: db.h:60
int line
Definition: json.h:831
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
Information needed to specify a subaddress in a call.
Definition: channel.h:308
static int write_to_ast_str(const char *buffer, size_t size, void *data)
Definition: json.c:468
struct ast_json * ast_json_false(void)
Get the JSON false value.
Definition: json.c:238
struct ast_json * ast_json_boolean(int value)
Get the JSON boolean corresponding to value.
Definition: json.c:243
int ast_json_real_set(struct ast_json *real, double value)
Set the value of a JSON real number.
Definition: json.c:342
int ast_json_dump_new_file_format(struct ast_json *root, const char *path, enum ast_json_encoding_format format)
Encode a JSON value to a file at the given location.
Definition: json.c:512
Asterisk module definitions.
static snd_pcm_format_t format
Definition: chan_alsa.c:102
struct ast_json_iter * ast_json_object_iter_at(struct ast_json *object, const char *key)
Get an iterator pointing to a specified key in object.
Definition: json.c:433
int ast_json_object_update(struct ast_json *object, struct ast_json *other)
Update object with all of the fields of other.
Definition: json.c:416
ast_json_to_ast_vars_code
Definition: json.h:1051
Information needed to specify a name in a call.
Definition: channel.h:263
#define AST_JSON_UTF8_VALIDATE(str)
Check str for UTF-8 and replace with an empty string if fails the check.
Definition: json.h:224
int ast_json_object_update_existing(struct ast_json *object, struct ast_json *other)
Update existing fields in object with the fields of other.
Definition: json.c:420
int ast_json_init(void)
Initialize the JSON library.
Definition: json.c:705
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
const char * ast_party_name_charset_describe(int data)
Convert ast_party_name.char_set value to explanatory string.
Definition: callerid.c:1347
int ast_json_object_del(struct ast_json *object, const char *key)
Delete a field from a JSON object.
Definition: json.c:408
struct ast_json * ast_json_integer_create(intmax_t value)
Create a JSON integer.
Definition: json.c:317
INT32 integer
Definition: lpc10.h:80
struct ast_json * ast_json_party_id(struct ast_party_id *party)
Construct an ast_party_id as JSON.
Definition: json.c:784
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:356
static size_t dump_flags(enum ast_json_encoding_format format)
Default flags for JSON encoding.
Definition: json.c:457
ast_json_encoding_format
Encoding format type.
Definition: json.h:745
int ast_json_dump_str_format(struct ast_json *root, struct ast_str **dst, enum ast_json_encoding_format format)
Encode a JSON value to an ast_str.
Definition: json.c:499
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343