Asterisk - The Open Source Telephony Project GIT-master-55f4e6d
geoloc_config.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2022, Sangoma Technologies Corporation
5 *
6 * George Joseph <gjoseph@sangoma.com>
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#include "asterisk.h"
20#include "asterisk/module.h"
21#include "asterisk/cli.h"
22#define AST_API_MODULE
23#include "geoloc_private.h"
24
26
27static const char *pidf_element_names[] = {
28 "<none>",
29 "device",
30 "tuple",
31 "person"
32};
33
34static const char *format_names[] = {
35 "<none>",
36 "civicAddress",
37 "GML",
38 "URI",
39};
40
41static const char * precedence_names[] = {
42 "prefer_incoming",
43 "prefer_config",
44 "discard_incoming",
45 "discard_config",
46};
47
48CONFIG_ENUM(location, format)
49CONFIG_VAR_LIST(location, location_info)
50CONFIG_VAR_LIST(location, confidence)
51
52static void geoloc_location_destructor(void *obj) {
53 struct ast_geoloc_location *location = obj;
54
58}
59
60static void *geoloc_location_alloc(const char *name)
61{
63 if (location) {
64 ast_string_field_init(location, 128);
65 }
66
67 return location;
68}
69
70CONFIG_ENUM(profile, pidf_element)
71CONFIG_ENUM(profile, precedence)
72CONFIG_VAR_LIST(profile, location_refinement)
73CONFIG_VAR_LIST(profile, location_variables)
74CONFIG_VAR_LIST(profile, usage_rules)
75
80
81static void geoloc_profile_destructor(void *obj) {
82 struct ast_geoloc_profile *profile = obj;
83
90}
91
92static void *geoloc_profile_alloc(const char *name)
93{
94 struct ast_geoloc_profile *profile = ast_sorcery_generic_alloc(sizeof(*profile),
96 if (profile) {
97 ast_string_field_init(profile, 128);
98 }
99
100 return profile;
101}
102
105{
107 const char *failed;
108 const char *uri;
109
110 switch (format) {
113 ast_log(LOG_ERROR, "Location '%s' must have a format\n", id);
114 return -1;
118 ast_log(LOG_ERROR, "Location '%s' has invalid item '%s' in the location\n",
119 id, failed);
120 return result;
121 }
122 break;
126 ast_log(LOG_ERROR, "%s for item '%s' in location '%s'\n",
128 return result;
129 }
130
131 break;
134 if (!uri) {
135 struct ast_str *str = ast_variable_list_join(location_info, ",", "=", "\"", NULL);
136
137 ast_log(LOG_ERROR, "Geolocation location '%s' format is set to '%s' but no 'URI' was found in location parameter '%s'\n",
139 ast_free(str);
141 }
142 break;
143 }
144
146}
147
148static int validate_location_source(const char *id, const char *location_source)
149{
150 if (!ast_strlen_zero(location_source)) {
151 struct ast_sockaddr loc_source_addr;
152 int rc = ast_sockaddr_parse(&loc_source_addr, location_source, PARSE_PORT_FORBID);
153 if (rc == 1) {
154 ast_log(LOG_ERROR, "Geolocation location '%s' location_source '%s' must be a FQDN."
155 " RFC8787 expressly forbids IP addresses.\n",
156 id, location_source);
157 return -1;
158 }
159 }
160
161 return 0;
162}
163
164static int geoloc_location_apply_handler(const struct ast_sorcery *sorcery, void *obj)
165{
166 struct ast_geoloc_location *location = obj;
167 const char *location_id = ast_sorcery_object_get_id(location);
169 int rc = 0;
170
171 if (!location->location_info) {
172 ast_log(LOG_ERROR, "Location '%s' is missing required element 'location_info'",
173 location_id);
174 return -1;
175 }
176
177 result = validate_location_info(location_id, location->format, location->location_info);
179 return -1;
180 }
181
182 rc = validate_location_source(location_id, location->location_source);
183 if (rc != 0) {
184 return -1;
185 }
186
187 return 0;
188}
189
190static int geoloc_profile_apply_handler(const struct ast_sorcery *sorcery, void *obj)
191{
192 struct ast_geoloc_profile *profile = obj;
193 struct ast_geoloc_location *location;
194 const char *id = ast_sorcery_object_get_id(profile);
197 int rc = 0;
198
199 if (!ast_strlen_zero(profile->location_reference)) {
200 if (profile->location_info ||
201 profile->format != AST_GEOLOC_FORMAT_NONE) {
202 ast_log(LOG_ERROR, "Profile '%s' can't have location_reference and location_info or format at the same time",
203 id);
204 return -1;
205 }
206 return 0;
207 }
208
209 if (profile->location_info) {
210 result = validate_location_info(id, profile->format, profile->location_info);
212 return -1;
213 }
214
215 rc = validate_location_source(id, profile->location_source);
216 if (rc != 0) {
217 return -1;
218 }
219
220 return 0;
221 }
222
223 if (!ast_strlen_zero(profile->location_reference)) {
224 location = ast_sorcery_retrieve_by_id(geoloc_sorcery, "location", profile->location_reference);
225 if (!location) {
226 ast_log(LOG_ERROR, "Profile '%s' has a location_reference '%s' that doesn't exist",
227 id, profile->location_reference);
228 return -1;
229 }
230 format = location->format;
231 ao2_ref(location, -1);
232 }
233
234 if (profile->location_refinement) {
237 return -1;
238 }
239 }
240
241 return 0;
242}
243
245{
247 return geoloc_sorcery;
248}
249
250static char *geoloc_config_list_locations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
251{
252 struct ao2_iterator iter;
253 struct ao2_container *sorted_container;
254 struct ao2_container *unsorted_container;
255 struct ast_geoloc_location *loc;
256 int using_regex = 0;
257 char *result = CLI_SUCCESS;
258 int ret = 0;
259 int count = 0;
260
261 switch (cmd) {
262 case CLI_INIT:
263 e->command = "geoloc list locations";
264 e->usage = "Usage: geoloc list locations [ like <pattern> ]\n"
265 " List Geolocation Location Objects\n";
266 return NULL;
267 case CLI_GENERATE:
268 return NULL;
269 }
270
271 if (a->argc != 3 && a->argc != 5) {
272 return CLI_SHOWUSAGE;
273 }
274
275 if (a->argc == 5) {
276 if (strcasecmp(a->argv[3], "like")) {
277 return CLI_SHOWUSAGE;
278 }
279 using_regex = 1;
280 }
281
284 if (!sorted_container) {
285 ast_cli(a->fd, "Geolocation Location Objects: Unable to allocate temporary container\n");
286 return CLI_FAILURE;
287 }
288
289 /* Get a sorted snapshot of the scheduled tasks */
290 if (using_regex) {
291 unsorted_container = ast_sorcery_retrieve_by_regex(geoloc_sorcery, "location", a->argv[4]);
292 } else {
293 unsorted_container = ast_sorcery_retrieve_by_fields(geoloc_sorcery, "location",
295 }
296
297 ret = ao2_container_dup(sorted_container, unsorted_container, 0);
298 ao2_ref(unsorted_container, -1);
299 if (ret != 0) {
300 ao2_ref(sorted_container, -1);
301 ast_cli(a->fd, "Geolocation Location Objects: Unable to sort temporary container\n");
302 return CLI_FAILURE;
303 }
304
305 ast_cli(a->fd, "Geolocation Location Objects:\n\n");
306
307 ast_cli(a->fd,
308 "<Object ID...................................> <Format.....> <Details.............>\n"
309 "===================================================================================\n");
310
311 iter = ao2_iterator_init(sorted_container, AO2_ITERATOR_UNLINK);
312 for (; (loc = ao2_iterator_next(&iter)); ao2_ref(loc, -1)) {
313 struct ast_str *str;
314
315 ao2_lock(loc);
316 str = ast_variable_list_join(loc->location_info, ",", "=", "\"", NULL);
317 if (!str) {
318 ao2_unlock(loc);
319 ao2_ref(loc, -1);
320 ast_cli(a->fd, "Geolocation Location Objects: Unable to allocate temp string for '%s'\n",
323 break;
324 }
325
326 ast_cli(a->fd, "%-46.46s %-13s %-s\n",
328 format_names[loc->format],
330 ao2_unlock(loc);
331 ast_free(str);
332 count++;
333 }
335 ao2_ref(sorted_container, -1);
336 ast_cli(a->fd, "\nTotal Location Objects: %d\n\n", count);
337
338 return result;
339}
340
341static char *geoloc_config_list_profiles(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
342{
343 struct ao2_iterator iter;
344 struct ao2_container *sorted_container;
345 struct ao2_container *unsorted_container;
346 struct ast_geoloc_profile *profile;
347 int using_regex = 0;
348 char *result = CLI_SUCCESS;
349 int ret = 0;
350 int count = 0;
351
352 switch (cmd) {
353 case CLI_INIT:
354 e->command = "geoloc list profiles";
355 e->usage = "Usage: geoloc list profiles [ like <pattern> ]\n"
356 " List Geolocation Profile Objects\n";
357 return NULL;
358 case CLI_GENERATE:
359 return NULL;
360 }
361
362 if (a->argc != 3 && a->argc != 5) {
363 return CLI_SHOWUSAGE;
364 }
365
366 if (a->argc == 5) {
367 if (strcasecmp(a->argv[3], "like")) {
368 return CLI_SHOWUSAGE;
369 }
370 using_regex = 1;
371 }
372
375 if (!sorted_container) {
376 ast_cli(a->fd, "Geolocation Profile Objects: Unable to allocate temporary container\n");
377 return CLI_FAILURE;
378 }
379
380 /* Get a sorted snapshot of the scheduled tasks */
381 if (using_regex) {
382 unsorted_container = ast_sorcery_retrieve_by_regex(geoloc_sorcery, "profile", a->argv[4]);
383 } else {
384 unsorted_container = ast_sorcery_retrieve_by_fields(geoloc_sorcery, "profile",
386 }
387
388 ret = ao2_container_dup(sorted_container, unsorted_container, 0);
389 ao2_ref(unsorted_container, -1);
390 if (ret != 0) {
391 ao2_ref(sorted_container, -1);
392 ast_cli(a->fd, "Geolocation Profile Objects: Unable to sort temporary container\n");
393 return CLI_FAILURE;
394 }
395
396 ast_cli(a->fd, "Geolocation Profile Objects:\n\n");
397
398 ast_cli(a->fd,
399 "<Object ID...................................> <Profile Action> <Location Reference> \n"
400 "=====================================================================================\n");
401
402 iter = ao2_iterator_init(sorted_container, AO2_ITERATOR_UNLINK);
403 for (; (profile = ao2_iterator_next(&iter)); ao2_ref(profile, -1)) {
404 ao2_lock(profile);
405
406 ast_cli(a->fd, "%-46.46s %-16s %-s\n",
409 profile->location_reference);
410 ao2_unlock(profile);
411 count++;
412 }
414 ao2_ref(sorted_container, -1);
415 ast_cli(a->fd, "\nTotal Profile Objects: %d\n\n", count);
416
417 return result;
418}
419
420static char *geoloc_config_show_profiles(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
421{
422 struct ao2_iterator iter;
423 struct ao2_container *sorted_container;
424 struct ao2_container *unsorted_container;
425 struct ast_geoloc_profile *profile;
426 int using_regex = 0;
427 char *result = CLI_SUCCESS;
428 int ret = 0;
429 int count = 0;
430
431 switch (cmd) {
432 case CLI_INIT:
433 e->command = "geoloc show profiles";
434 e->usage = "Usage: geoloc show profiles [ like <pattern> ]\n"
435 " List Geolocation Profile Objects\n";
436 return NULL;
437 case CLI_GENERATE:
438 return NULL;
439 }
440
441 if (a->argc != 3 && a->argc != 5) {
442 return CLI_SHOWUSAGE;
443 }
444
445 if (a->argc == 5) {
446 if (strcasecmp(a->argv[3], "like")) {
447 return CLI_SHOWUSAGE;
448 }
449 using_regex = 1;
450 }
451
452 /* Create an empty rb-tree container which always sorts its contents. */
455 if (!sorted_container) {
456 ast_cli(a->fd, "Geolocation Profile Objects: Unable to allocate temporary container\n");
457 return CLI_FAILURE;
458 }
459
460 /* Get an unsorted list of profile parameters */
461 if (using_regex) {
462 unsorted_container = ast_sorcery_retrieve_by_regex(geoloc_sorcery, "profile", a->argv[4]);
463 } else {
464 unsorted_container = ast_sorcery_retrieve_by_fields(geoloc_sorcery, "profile",
466 }
467
468 /* Copy the unsorted parameters into the rb-tree container which will sort them automatically. */
469 ret = ao2_container_dup(sorted_container, unsorted_container, 0);
470 ao2_ref(unsorted_container, -1);
471 if (ret != 0) {
472 ao2_ref(sorted_container, -1);
473 ast_cli(a->fd, "Geolocation Profile Objects: Unable to sort temporary container\n");
474 return CLI_FAILURE;
475 }
476
477 ast_cli(a->fd, "Geolocation Profile Objects:\n");
478
479 iter = ao2_iterator_init(sorted_container, AO2_ITERATOR_UNLINK);
480 for (; (profile = ao2_iterator_next(&iter)); ) {
481 struct ast_str *loc_str = NULL;
482 struct ast_str *refinement_str = NULL;
483 struct ast_str *variables_str = NULL;
484 struct ast_str *resolved_str = NULL;
485 struct ast_str *usage_rules_str = NULL;
486 struct ast_str *confidence_str = NULL;
488 ao2_ref(profile, -1);
489
490 loc_str = ast_variable_list_join(eprofile->location_info, ",", "=", "\"", NULL);
491 resolved_str = ast_variable_list_join(eprofile->effective_location, ",", "=", "\"", NULL);
492
493 refinement_str = ast_variable_list_join(eprofile->location_refinement, ",", "=", "\"", NULL);
494 variables_str = ast_variable_list_join(eprofile->location_variables, ",", "=", "\"", NULL);
495 usage_rules_str = ast_variable_list_join(eprofile->usage_rules, ",", "=", "\"", NULL);
496 confidence_str = ast_variable_list_join(eprofile->confidence, ",", "=", "\"", NULL);
497
498 ast_cli(a->fd,"\n"
499 "id: %-s\n"
500 "profile_precedence: %-s\n"
501 "pidf_element: %-s\n"
502 "location_reference: %-s\n"
503 "location_format: %-s\n"
504 "location_info: %-s\n"
505 "location_method: %-s\n"
506 "location_source: %-s\n"
507 "location_confidence: %-s\n"
508 "location_refinement: %-s\n"
509 "location_variables: %-s\n"
510 "allow_routing_use: %-s\n"
511 "suppress_empty_elements: %-s\n"
512 "effective_location: %-s\n"
513 "usage_rules: %-s\n"
514 "notes: %-s\n",
515 eprofile->id,
516 precedence_names[eprofile->precedence],
518 S_OR(eprofile->location_reference, "<none>"),
519 format_names[eprofile->format],
520 S_COR(loc_str, ast_str_buffer(loc_str), "<none>"),
521 S_OR(eprofile->method, "<none>"),
522 S_OR(eprofile->location_source, "<none>"),
523 S_COR(confidence_str, ast_str_buffer(confidence_str), "<none>"),
524 S_COR(refinement_str, ast_str_buffer(refinement_str), "<none>"),
525 S_COR(variables_str, ast_str_buffer(variables_str), "<none>"),
526 S_COR(eprofile->allow_routing_use, "yes", "no"),
527 S_COR(eprofile->suppress_empty_ca_elements, "yes", "no"),
528 S_COR(resolved_str, ast_str_buffer(resolved_str), "<none>"),
529 S_COR(usage_rules_str, ast_str_buffer(usage_rules_str), "<none>"),
530 S_OR(eprofile->notes, "<none>")
531 );
532 ao2_ref(eprofile, -1);
533
534 ast_free(loc_str);
535 ast_free(refinement_str);
536 ast_free(variables_str);
537 ast_free(resolved_str);
538 ast_free(usage_rules_str);
539 ast_free(confidence_str);
540 count++;
541 }
543 ao2_ref(sorted_container, -1);
544 ast_cli(a->fd, "\nTotal Profile Objects: %d\n\n", count);
545
546 return result;
547}
548
549static char *geoloc_config_cli_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
550{
551 char *result = CLI_SUCCESS;
552
553 switch (cmd) {
554 case CLI_INIT:
555 e->command = "geoloc reload";
556 e->usage = "Usage: geoloc reload\n"
557 " Reload Geolocation Configuration\n";
558 return NULL;
559 case CLI_GENERATE:
560 return NULL;
561 }
562
563 if (a->argc != 2) {
564 return CLI_SHOWUSAGE;
565 }
566
568 ast_cli(a->fd, "Geolocation Configuration reloaded.\n");
569
570 return result;
571}
572
574 AST_CLI_DEFINE(geoloc_config_list_locations, "List Geolocation Location Objects"),
575 AST_CLI_DEFINE(geoloc_config_list_profiles, "List Geolocation Profile Objects"),
576 AST_CLI_DEFINE(geoloc_config_show_profiles, "Show Geolocation Profile Objects"),
577 AST_CLI_DEFINE(geoloc_config_cli_reload, "Reload Geolocation Configuration"),
578};
579
581{
582 if (ast_strlen_zero(id)) {
583 return NULL;
584 }
585
586 return ast_sorcery_retrieve_by_id(geoloc_sorcery, "location", id);
587}
588
590{
591 if (ast_strlen_zero(id)) {
592 return NULL;
593 }
594
595 return ast_sorcery_retrieve_by_id(geoloc_sorcery, "profile", id);
596}
597
599{
600 if (geoloc_sorcery) {
602 }
604}
605
607{
609
612
613 if (geoloc_sorcery) {
615 }
617
618 return 0;
619}
620
621static int default_profile_create(const char *name)
622{
623 int rc = 0;
624 struct ast_geoloc_profile *profile;
625 char *id = ast_alloca(strlen(name) + 3 /* <, >, NULL */);
626
627 sprintf(id, "<%s>", name); /* Safe */
628 profile = ast_sorcery_alloc(geoloc_sorcery, "profile", id);
629 ast_assert_return(profile != NULL, 0);
630
631 profile->precedence = ast_geoloc_precedence_str_to_enum(name);
633 rc = ast_sorcery_create(geoloc_sorcery, profile);
634 /*
635 * We're either passing the ref to sorcery or there was an error.
636 * Either way we need to drop our reference.
637 */
638 ao2_ref(profile, -1);
639
640 /* ast_assert_return wants a true/false */
641 return rc == 0 ? 1 : 0;
642}
643
645{
646 /*
647 * If any of these fail, the module will fail to load
648 * and clean up the sorcery instance so no error cleanup
649 * is required here.
650 */
651 ast_assert_return(default_profile_create("prefer_config"), -1);
652 ast_assert_return(default_profile_create("discard_config"), -1);
653 ast_assert_return(default_profile_create("prefer_incoming"), -1);
654 ast_assert_return(default_profile_create("discard_incoming"), -1);
655
656 return 0;
657}
658
660{
662 int rc = 0;
663
664 if (!(geoloc_sorcery = ast_sorcery_open())) {
665 ast_log(LOG_ERROR, "Failed to open geolocation sorcery\n");
667 }
668
670 result = ast_sorcery_apply_default(geoloc_sorcery, "location", "config", "geolocation.conf,criteria=type=location");
672 ast_log(LOG_ERROR, "Failed to apply defaults for geoloc location object with sorcery\n");
674 }
675
677 if (rc != 0) {
678 ast_log(LOG_ERROR, "Failed to register geoloc location object with sorcery\n");
680 }
681
682 ast_sorcery_object_field_register(geoloc_sorcery, "location", "type", "", OPT_NOOP_T, 0, 0);
684 location_format_handler, location_format_to_str, NULL, 0, 0);
686 location_location_info_handler, location_location_info_to_str, location_location_info_dup, 0, 0);
688 location_confidence_handler, location_confidence_to_str, location_confidence_dup, 0, 0);
689 ast_sorcery_object_field_register(geoloc_sorcery, "location", "location_source", "", OPT_STRINGFIELD_T,
693
694
696 /*
697 * The memory backend is used to contain the built-in profiles.
698 */
701 ast_log(LOG_ERROR, "Failed to add memory wizard mapping to geoloc profile object\n");
703 }
704
706 "geolocation.conf,criteria=type=profile", 0);
708 ast_log(LOG_ERROR, "Failed to add memory wizard mapping to geoloc profile object\n");
710 }
712 if (rc != 0) {
713 ast_log(LOG_ERROR, "Failed to register geoloc profile object with sorcery\n");
715 }
716
717 ast_sorcery_object_field_register(geoloc_sorcery, "profile", "type", "", OPT_NOOP_T, 0, 0);
719 pidf_element_names[AST_PIDF_ELEMENT_DEVICE], profile_pidf_element_handler, profile_pidf_element_to_str, NULL, 0, 0);
720 ast_sorcery_object_field_register(geoloc_sorcery, "profile", "location_reference", "", OPT_STRINGFIELD_T,
722 ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "profile_precedence", "discard_incoming",
723 profile_precedence_handler, profile_precedence_to_str, NULL, 0, 0);
725 profile_usage_rules_handler, profile_usage_rules_to_str, profile_usage_rules_dup, 0, 0);
726 ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "location_info_refinement", NULL,
727 profile_location_refinement_handler, profile_location_refinement_to_str, profile_location_refinement_dup, 0, 0);
728 ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "location_variables", NULL,
729 profile_location_variables_handler, profile_location_variables_to_str, profile_location_variables_dup, 0, 0);
732 ast_sorcery_object_field_register(geoloc_sorcery, "profile", "allow_routing_use",
734 ast_sorcery_object_field_register(geoloc_sorcery, "profile", "suppress_empty_ca_elements",
736
738 profile_format_handler, profile_format_to_str, NULL, 0, 0);
740 profile_location_info_handler, profile_location_info_to_str, profile_location_info_dup, 0, 0);
742 profile_confidence_handler, profile_confidence_to_str, profile_confidence_dup, 0, 0);
743 ast_sorcery_object_field_register(geoloc_sorcery, "profile", "location_source", "", OPT_STRINGFIELD_T,
747
748
750
752 if (rc != 0) {
753 ast_log(LOG_ERROR, "Failed to load default geoloc profiles\n");
755 }
756
757
759
761}
762
764{
765 return 1;
766}
767
const char * str
Definition: app_jack.c:147
enum queue_result id
Definition: app_queue.c:1638
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
@ AO2_ITERATOR_UNLINK
Definition: astobj2.h:1863
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition: astobj2.h:1349
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static PGresult * result
Definition: cel_pgsql.c:84
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
static const char name[]
Definition: format_mp3.c:68
static char * geoloc_config_list_locations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * geoloc_location_alloc(const char *name)
Definition: geoloc_config.c:60
static char * geoloc_config_list_profiles(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_geoloc_location *AST_OPTIONAL_API_NAME() ast_geoloc_get_location(const char *id)
Retrieve a geolocation location object by id.
static const char * precedence_names[]
Definition: geoloc_config.c:41
static struct ast_sorcery * geoloc_sorcery
Definition: geoloc_config.c:25
static void geoloc_profile_destructor(void *obj)
Definition: geoloc_config.c:81
int AST_OPTIONAL_API_NAME() ast_geoloc_is_loaded(void)
Check if res_geolocation is available.
int geoloc_config_reload(void)
static void * geoloc_profile_alloc(const char *name)
Definition: geoloc_config.c:92
int geoloc_config_unload(void)
static int validate_location_source(const char *id, const char *location_source)
static const char * format_names[]
Definition: geoloc_config.c:34
static int geoloc_location_apply_handler(const struct ast_sorcery *sorcery, void *obj)
static const char * pidf_element_names[]
Definition: geoloc_config.c:27
int geoloc_config_load(void)
static enum ast_geoloc_validate_result validate_location_info(const char *id, enum ast_geoloc_format format, struct ast_variable *location_info)
static void geoloc_location_destructor(void *obj)
Definition: geoloc_config.c:52
static char * geoloc_config_show_profiles(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * geoloc_config_cli_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int geoloc_profile_apply_handler(const struct ast_sorcery *sorcery, void *obj)
struct ast_sorcery * geoloc_get_sorcery(void)
static int geoloc_load_default_profiles(void)
struct ast_geoloc_profile *AST_OPTIONAL_API_NAME() ast_geoloc_get_profile(const char *id)
Retrieve a geolocation profile by id.
static int default_profile_create(const char *name)
static struct ast_cli_entry geoloc_location_cli_commands[]
#define CONFIG_ENUM_HANDLER(_object, _stem)
#define CONFIG_VAR_LIST(_object, _stem)
#define CONFIG_ENUM_TO_STR(_object, _stem)
#define CONFIG_ENUM(_object, _stem)
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
Definition: main/config.c:919
struct ast_str * ast_variable_list_join(const struct ast_variable *head, const char *item_separator, const char *name_value_separator, const char *quote_char, struct ast_str **str)
Join an ast_variable list with specified separators and quoted values.
Definition: main/config.c:700
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define LOG_ERROR
Asterisk module definitions.
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define AST_OPTIONAL_API_NAME(name)
Expands to the name of the implementation function.
Definition: optional_api.h:228
static int notes
Definition: pval.c:66
const char * ast_geoloc_validate_result_to_str(enum ast_geoloc_validate_result result)
Definition: geoloc_common.c:32
ast_geoloc_validate_result
@ AST_GEOLOC_VALIDATE_SUCCESS
@ AST_GEOLOC_VALIDATE_NOT_ENOUGH_VARNAMES
enum ast_geoloc_validate_result ast_geoloc_civicaddr_validate_varlist(const struct ast_variable *varlist, const char **result)
Validate that the names of the variables in the list are valid codes or synonyms.
@ AST_PIDF_ELEMENT_DEVICE
ast_geoloc_format
@ AST_GEOLOC_FORMAT_GML
@ AST_GEOLOC_FORMAT_CIVIC_ADDRESS
@ AST_GEOLOC_FORMAT_LAST
@ AST_GEOLOC_FORMAT_URI
@ AST_GEOLOC_FORMAT_NONE
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
Allocate a new effective profile from an existing profile.
enum ast_geoloc_validate_result ast_geoloc_gml_validate_varlist(const struct ast_variable *varlist, const char **result)
Validate that the variables in the list represent a valid GML shape.
Definition: geoloc_gml.c:124
const char * method
Definition: res_pjsip.c:1279
static struct ast_sorcery * sorcery
#define NULL
Definition: resample.c:96
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching)
Apply additional object wizard mappings.
Definition: sorcery.h:510
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
Definition: sorcery.h:1500
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
Definition: sorcery.c:1377
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
Definition: sorcery.c:2062
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
Definition: sorcery.c:1408
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition: sorcery.c:1954
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
Definition: sorcery.c:1061
void ast_sorcery_ref(struct ast_sorcery *sorcery)
Increase the reference count of a sorcery structure.
Definition: sorcery.c:1473
#define ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:455
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2440
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
#define ast_sorcery_open()
Open a new sorcery structure.
Definition: sorcery.h:406
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
ast_sorcery_apply_result
Definition: sorcery.h:423
@ AST_SORCERY_APPLY_SUCCESS
Definition: sorcery.h:427
@ AST_SORCERY_APPLY_FAIL
Definition: sorcery.h:425
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
struct ast_variable * effective_location
const ast_string_field location_reference
enum ast_geoloc_format format
enum ast_geoloc_pidf_element pidf_element
const ast_string_field method
struct ast_variable * location_refinement
enum ast_geoloc_precedence precedence
const ast_string_field notes
const ast_string_field id
struct ast_variable * location_variables
struct ast_variable * confidence
struct ast_variable * usage_rules
const ast_string_field location_source
struct ast_variable * location_info
enum ast_geoloc_format format
struct ast_variable * confidence
const ast_string_field location_source
struct ast_variable * location_info
const ast_string_field location_reference
enum ast_geoloc_format format
enum ast_geoloc_pidf_element pidf_element
struct ast_variable * location_refinement
enum ast_geoloc_precedence precedence
struct ast_variable * location_variables
struct ast_variable * confidence
struct ast_variable * usage_rules
const ast_string_field location_source
struct ast_variable * location_info
Socket address structure.
Definition: netsock2.h:97
Full structure for sorcery.
Definition: sorcery.c:230
Support for dynamic strings.
Definition: strings.h:623
Structure for variables, used for configurations and for channel variables.
static struct test_val a
#define ast_assert_return(a,...)
Definition: utils.h:740
#define ARRAY_LEN(a)
Definition: utils.h:666