Asterisk - The Open Source Telephony Project GIT-master-80b953f
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
res_pjsip_config_wizard.c File Reference

PJSIP Configuration Wizard. More...

#include "asterisk.h"
#include <regex.h>
#include <pjsip.h>
#include "asterisk/astobj2.h"
#include "asterisk/cli.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sorcery.h"
#include "asterisk/vector.h"
#include "asterisk/stasis.h"
#include "asterisk/acl.h"
#include "asterisk/security_events.h"
Include dependency graph for res_pjsip_config_wizard.c:

Go to the source code of this file.

Data Structures

struct  object_type_wizard
 Keeps track of the sorcery wizard and last config for each object type. More...
 
struct  string_vector
 A generic char * vector definition. More...
 

Macros

#define BASE_REGISTRAR   "res_pjsip_config_wizard"
 
#define MAX_ID_SUFFIX   20
 Defines the maximum number of characters that can be added to a wizard id.
 
#define NOT_EQUALS(a, b)   (a != b)
 
#define OTW_DELETE_CB(otw)
 
#define variable_list_append_return(existing, name, value)
 Appends a variable to the end of an existing list. On failure, cause the calling function to return -1.
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Callback for Named ACL changed.
 
static int add_extension (struct ast_context *context, const char *exten, int priority, const char *application)
 
static int add_hints (const char *context, const char *exten, const char *application, const char *id)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static AST_VECTOR_RW (object_type_wizards, struct object_type_wizard *)
 
static void * create_object (const struct ast_sorcery *sorcery, const char *id, const char *type, struct ast_variable *vars)
 Creates a sorcery object and applies a variable list.
 
static int delete_existing_cb (void *obj, void *arg, int flags)
 
static int delete_extens (const char *context, const char *exten)
 
static struct object_type_wizardfind_wizard (const char *object_type)
 Finds the otw for the object type.
 
static struct ast_variableget_object_variables (struct ast_variable *vars, char *prefix)
 We need to strip off the prefix from the name of each variable so they're suitable for objectset_apply. I.E. will transform outbound_auth/username to username.
 
static int handle_aor (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
 
static int handle_auth (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, char *direction)
 
static int handle_auths (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
 
static int handle_endpoint (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
 
static char * handle_export_primitives (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int handle_identify (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
 
static int handle_phoneprov (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
 
static int handle_registrations (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
 
static void instance_created_observer (const char *name, struct ast_sorcery *sorcery)
 When the res_pjsip instance is created, add an observer to it and initialize the wizard vector. Also, bump the module's ref count so it can't be unloaded before the sorcery instance is destroyed.
 
static void instance_destroying_observer (const char *name, struct ast_sorcery *sorcery)
 When the res_pjsip instance is destroyed, remove the observer and unref the module. This should then allow this module to unload cleanly.
 
static int is_one_of (const char *needle, const char *haystack[])
 
static int is_variable_true (struct ast_variable *vars, const char *name)
 Finds the last variable in a list and tests it.
 
static int load_module (void)
 
static void object_type_loaded_observer (const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
 Called after an object type is loaded/reloaded.
 
static void object_type_registered_observer (const char *name, struct ast_sorcery *sorcery, const char *object_type)
 When each object type is registered, map a memory wizard to it.
 
static int reload_module (void)
 
static int unload_module (void)
 
static int variable_list_append (struct ast_variable **existing, const char *name, const char *value)
 Appends a variable to the end of an existing list.
 
static int wizard_apply_handler (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Config Wizard" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
 
static int acl_change_detected = 0
 
static struct stasis_subscriptionacl_change_sub
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry config_wizard_cli []
 
static const struct ast_sorcery_global_observer global_observer
 
struct ast_sorcery_instance_observer observer
 

Detailed Description

PJSIP Configuration Wizard.

Author
George Joseph georg.nosp@m.e.jo.nosp@m.seph@.nosp@m.fair.nosp@m.view5.nosp@m..com

Definition in file res_pjsip_config_wizard.c.

Macro Definition Documentation

◆ BASE_REGISTRAR

#define BASE_REGISTRAR   "res_pjsip_config_wizard"

Definition at line 279 of file res_pjsip_config_wizard.c.

◆ MAX_ID_SUFFIX

#define MAX_ID_SUFFIX   20

Defines the maximum number of characters that can be added to a wizard id.

Definition at line 277 of file res_pjsip_config_wizard.c.

◆ NOT_EQUALS

#define NOT_EQUALS (   a,
  b 
)    (a != b)

◆ OTW_DELETE_CB

#define OTW_DELETE_CB (   otw)
Value:
({ \
ast_config_destroy(otw->last_config); \
ast_free(otw); \
})

◆ variable_list_append_return

#define variable_list_append_return (   existing,
  name,
  value 
)

Appends a variable to the end of an existing list. On failure, cause the calling function to return -1.

Definition at line 392 of file res_pjsip_config_wizard.c.

392 { \
393 struct ast_variable *new = ast_variable_new(name, value, ""); \
394 if (!new) { \
395 ast_log(LOG_ERROR, "Unable to allocate memory for new variable '%s'.\n", name); \
396 return -1; \
397 } \
398 ast_variable_list_append(existing, new); \
399})
static const char name[]
Definition format_mp3.c:68
#define ast_variable_new(name, value, filename)
#define LOG_ERROR
Structure for variables, used for configurations and for channel variables.
int value
Definition syslog.c:37

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1399 of file res_pjsip_config_wizard.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1399 of file res_pjsip_config_wizard.c.

◆ acl_change_stasis_cb()

static void acl_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Callback for Named ACL changed.

Definition at line 307 of file res_pjsip_config_wizard.c.

308{
310 return;
311 }
312
313 ast_debug(3, "PJSIP Wizard: Named ACL change detected via Stasis. Triggering reload.\n");
317}
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
static int acl_change_detected
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
Definition sorcery.c:1472

References acl_change_detected, ast_debug, ast_named_acl_change_type(), ast_sip_get_sorcery(), and ast_sorcery_reload().

Referenced by load_module().

◆ add_extension()

static int add_extension ( struct ast_context context,
const char *  exten,
int  priority,
const char *  application 
)
static

Definition at line 439 of file res_pjsip_config_wizard.c.

441{
442 struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
443 struct ast_exten *existing_exten;
444 char *data = NULL;
445 char *app = NULL;
446 void *free_ptr = NULL;
447 const char *paren;
448 const char *context_name;
449
450 if (!context || ast_strlen_zero(exten) || ast_strlen_zero(application)) {
451 return -1;
452 }
453
454 /* The incoming application has to be split into the app name and the
455 * arguments (data). The app name can be any storage type as add_extension
456 * copies it into its own buffer. Data however, needs to be dynamically
457 * allocated and a free function provided.
458 */
459
460 paren = strchr(application, '(');
461 if (!paren) {
462 app = (char *)application;
463 } else {
464 app = ast_strdupa(application);
465 app[paren - application] = '\0';
466 data = ast_strdup(paren + 1);
467 if (!data) {
468 return -1;
469 }
470 data[strlen(data) - 1] = '\0';
471 free_ptr = ast_free_ptr;
473 ast_free(data);
474 return -1;
475 }
476 }
477
478 /* Don't disturb existing, exact-match, entries. */
480 if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, context_name, exten,
481 priority, NULL, NULL, E_MATCH))) {
482 const char *existing_app = ast_get_extension_app(existing_exten);
483 const char *existing_data = ast_get_extension_app_data(existing_exten);
484 if (!strcmp(existing_app, app)
485 && !strcmp(existing_data ? existing_data : "", data ? data : "")) {
486 ast_free(data);
487 return 0;
488 }
489
491 }
492
494 app, data, free_ptr, BASE_REGISTRAR, NULL, 0)) {
495 return -1;
496 }
497
498 return 0;
499}
#define paren
Definition ael_lex.c:962
static const char app[]
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
void ast_free_ptr(void *ptr)
free() wrapper
Definition astmm.c:1739
static int priority
@ E_MATCH
Definition extconf.h:217
static const char context_name[]
void * ast_get_extension_app_data(struct ast_exten *e)
Definition pbx.c:8606
int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
This functionc locks given context, search for the right extension and fires out all peer in this ext...
Definition pbx.c:5014
const char * ast_get_extension_app(struct ast_exten *e)
Definition pbx.c:8601
const char * ast_get_context_name(struct ast_context *con)
Definition ael_main.c:421
int ast_add_extension2_nolock(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Same as ast_add_extension2, but assumes you have already locked context.
Definition pbx.c:7310
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition ael_main.c:152
#define BASE_REGISTRAR
#define NULL
Definition resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Definition pbx.c:252
char * exten
Definition pbx.c:253
void * data
Definition pbx.c:263

References app, ast_add_extension2_nolock(), ast_context_remove_extension2(), ast_free, ast_free_ptr(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_app_data(), ast_strdup, ast_strdupa, ast_strlen_zero(), BASE_REGISTRAR, context_name, ast_exten::data, E_MATCH, ast_exten::exten, NULL, paren, pbx_find_extension(), priority, and pbx_find_info::stacklen.

Referenced by add_hints().

◆ add_hints()

static int add_hints ( const char *  context,
const char *  exten,
const char *  application,
const char *  id 
)
static

Definition at line 501 of file res_pjsip_config_wizard.c.

502{
503 struct ast_context *hint_context;
504 char *hint_device;
505
506 hint_device = ast_alloca(strlen("PJSIP/") + strlen(id) + 1);
507 sprintf(hint_device, "PJSIP/%s", id);
508
509 /* We need the contexts list locked to safely be able to both read and lock the specific context within */
510 if (ast_wrlock_contexts()) {
511 ast_log(LOG_ERROR, "Failed to lock the contexts list.\n");
512 return -1;
513 }
514
515 if (!(hint_context = ast_context_find_or_create(NULL, NULL, context, BASE_REGISTRAR))) {
516 ast_log(LOG_ERROR, "Unable to find or create hint context '%s'\n", context);
517 if (ast_unlock_contexts()) {
518 ast_assert(0);
519 }
520 return -1;
521 }
522
523 /* Transfer the all-contexts lock to the specific context */
524 if (ast_wrlock_context(hint_context)) {
526 ast_log(LOG_ERROR, "failed to obtain write lock on context\n");
527 return -1;
528 }
530
531 if (add_extension(hint_context, exten, PRIORITY_HINT, hint_device)) {
532 ast_log(LOG_ERROR, "Failed to add hint '%s@%s' to the PBX.\n",
533 exten, context);
534 }
535
536 if (!ast_strlen_zero(application)) {
537 if (add_extension(hint_context, exten, 1, application)) {
538 ast_log(LOG_ERROR, "Failed to add hint '%s@%s' to the PBX.\n",
539 exten, context);
540 }
541 } else {
542 ast_context_remove_extension2(hint_context, exten, 1, BASE_REGISTRAR, 1);
543 }
544
545 ast_unlock_context(hint_context);
546
547 return 0;
548}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_log
Definition astobj2.c:42
int ast_wrlock_contexts(void)
Write locks the context list.
Definition pbx.c:8507
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition pbx.c:8525
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition pbx.c:6185
int ast_unlock_context(struct ast_context *con)
Definition pbx.c:8535
#define PRIORITY_HINT
Definition pbx.h:54
int ast_unlock_contexts(void)
Unlocks contexts.
Definition pbx.c:8517
static int add_extension(struct ast_context *context, const char *exten, int priority, const char *application)
ast_context: An extension context
Definition pbx.c:299
#define ast_assert(a)
Definition utils.h:779

References add_extension(), ast_alloca, ast_assert, ast_context_find_or_create(), ast_context_remove_extension2(), ast_log, ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_wrlock_context(), ast_wrlock_contexts(), BASE_REGISTRAR, LOG_ERROR, NULL, and PRIORITY_HINT.

Referenced by handle_endpoint().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1399 of file res_pjsip_config_wizard.c.

◆ AST_VECTOR_RW()

static AST_VECTOR_RW (   object_type_wizards,
struct object_type_wizard  
)
static

Definition at line 292 of file res_pjsip_config_wizard.c.

296 { \
297 ast_config_destroy(otw->last_config); \
298 ast_free(otw); \
299})
300
301const static char *object_types[] = {"phoneprov", "registration", "identify", "endpoint", "aor", "auth", NULL};

References NULL.

◆ create_object()

static void * create_object ( const struct ast_sorcery sorcery,
const char *  id,
const char *  type,
struct ast_variable vars 
)
static

Creates a sorcery object and applies a variable list.

Definition at line 350 of file res_pjsip_config_wizard.c.

352{
354
355 if (!obj) {
356 ast_log(LOG_ERROR, "Unable to allocate an object of type '%s' with id '%s'.\n", type, id);
357 return NULL;
358 }
359
360 if (ast_sorcery_objectset_apply(sorcery, obj, vars)) {
361 ast_log(LOG_ERROR, "Unable to apply object type '%s' with id '%s'. Check preceeding errors.\n", type, id);
362 ao2_ref(obj, -1);
363 return NULL;
364 }
365
366 return obj;
367}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
static const char type[]
static struct ast_sorcery * sorcery
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition sorcery.c:1808
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
Definition sorcery.c:1696
Structure for internal sorcery object information.
Definition sorcery.c:128

References ao2_ref, ast_log, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), LOG_ERROR, NULL, sorcery, and type.

Referenced by handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), and handle_registrations().

◆ delete_existing_cb()

static int delete_existing_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 844 of file res_pjsip_config_wizard.c.

845{
846 struct object_type_wizard *otw = arg;
847
848 if (!strcmp(otw->object_type, "endpoint")) {
849 const char *context = ast_sorcery_object_get_extended(obj, "hint_context");
850 const char *exten = ast_sorcery_object_get_extended(obj, "hint_exten");
851 if (!ast_strlen_zero(context) && !ast_strlen_zero(exten)) {
852 delete_extens(context, exten);
853 }
854 }
855
856 otw->wizard->delete(otw->sorcery, otw->wizard_data, obj);
857
858 return CMP_MATCH;
859}
@ CMP_MATCH
Definition astobj2.h:1027
static int delete_extens(const char *context, const char *exten)
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
Definition sorcery.c:2399
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
Definition sorcery.h:319
Keeps track of the sorcery wizard and last config for each object type.
struct ast_sorcery * sorcery
struct ast_sorcery_wizard * wizard

References ast_sorcery_object_get_extended(), ast_strlen_zero(), CMP_MATCH, ast_sorcery_wizard::delete, delete_extens(), object_type_wizard::object_type, object_type_wizard::sorcery, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by handle_registrations(), and object_type_loaded_observer().

◆ delete_extens()

static int delete_extens ( const char *  context,
const char *  exten 
)
static

Definition at line 424 of file res_pjsip_config_wizard.c.

425{
426 struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
427
428 if (pbx_find_extension(NULL, NULL, &find_info, context, exten, PRIORITY_HINT, NULL, NULL, E_MATCH)) {
430 }
431
432 if (pbx_find_extension(NULL, NULL, &find_info, context, exten, 1, NULL, NULL, E_MATCH)) {
434 }
435
436 return 0;
437}
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition pbx.c:4984

References ast_context_remove_extension(), BASE_REGISTRAR, E_MATCH, NULL, pbx_find_extension(), PRIORITY_HINT, and pbx_find_info::stacklen.

Referenced by delete_existing_cb(), and handle_endpoint().

◆ find_wizard()

static struct object_type_wizard * find_wizard ( const char *  object_type)
static

Finds the otw for the object type.

Definition at line 332 of file res_pjsip_config_wizard.c.

333{
334 int idx;
335
336 AST_VECTOR_RW_RDLOCK(&object_type_wizards);
337 for(idx = 0; idx < AST_VECTOR_SIZE(&object_type_wizards); idx++) {
338 struct object_type_wizard *otw = AST_VECTOR_GET(&object_type_wizards, idx);
339 if (!strcmp(otw->object_type, object_type)) {
340 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
341 return otw;
342 }
343 }
344 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
345
346 return NULL;
347}
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:620
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition vector.h:908
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition vector.h:888
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

References AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, NULL, and object_type_wizard::object_type.

Referenced by object_type_loaded_observer().

◆ get_object_variables()

static struct ast_variable * get_object_variables ( struct ast_variable vars,
char *  prefix 
)
static

We need to strip off the prefix from the name of each variable so they're suitable for objectset_apply. I.E. will transform outbound_auth/username to username.

Definition at line 405 of file res_pjsip_config_wizard.c.

406{
407 struct ast_variable *return_vars = NULL;
408 struct ast_variable *v = vars;
409 int plen = strlen(prefix);
410
411 for(; v; v = v->next) {
412 if (ast_begins_with(v->name, prefix) && strlen(v->name) > plen) {
413 if (variable_list_append(&return_vars, v->name + plen, v->value)) {
414 ast_variables_destroy(return_vars);
415 return NULL;
416 }
417 }
418 }
419
420 return return_vars;
421}
static char prefix[MAX_PREFIX]
Definition http.c:145
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260
static int variable_list_append(struct ast_variable **existing, const char *name, const char *value)
Appends a variable to the end of an existing list.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition strings.h:97
struct ast_variable * next

References ast_begins_with(), ast_variables_destroy(), ast_variable::name, ast_variable::next, NULL, prefix, ast_variable::value, and variable_list_append().

Referenced by handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), and handle_registrations().

◆ handle_aor()

static int handle_aor ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz,
struct string_vector remote_hosts_vector 
)
static

Definition at line 620 of file res_pjsip_config_wizard.c.

622{
623 struct ast_variable *wizvars = ast_category_first(wiz);
624 struct ast_sorcery_object *obj = NULL;
625 const char *id = ast_category_get_name(wiz);
626 const char *contact_pattern;
627 const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
628 int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
629 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "aor/"), ast_variables_destroy);
630
631 variable_list_append(&vars, "@pjsip_wizard", id);
632
633 if (!ast_strlen_zero(outbound_proxy)) {
634 variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
635 }
636
637 /* If the user explicitly specified an aor/contact, don't use remote hosts. */
638 if (!ast_variable_find_last_in_list(vars, "contact")) {
639 if (!(contact_pattern = ast_variable_find_last_in_list(wizvars, "contact_pattern"))) {
640 contact_pattern = "sip:${REMOTE_HOST}";
641 }
642
643 if (host_count > 0 && !ast_strlen_zero(contact_pattern)) {
644 int host_counter;
645
646 /* ast_str_substitute_variables operate on a varshead list so we have
647 * to create one to hold the REPORT_HOST substitution, do the substitution,
648 * then append the result to the ast_variable list.
649 */
650 for (host_counter = 0; host_counter < host_count; host_counter++) {
651 RAII_VAR(struct ast_str *, new_str, ast_str_create(64), ast_free);
653 struct ast_var_t *var = ast_var_assign("REMOTE_HOST",
654 AST_VECTOR_GET(remote_hosts_vector, host_counter));
655
656 AST_VAR_LIST_INSERT_TAIL(subst_vars, var);
657 ast_str_substitute_variables_varshead(&new_str, 0, subst_vars,
658 contact_pattern);
659
660 variable_list_append_return(&vars, "contact", ast_str_buffer(new_str));
661 }
662 }
663 }
664
665 obj = create_object(sorcery, id, "aor", vars);
666 if (!obj) {
667 return -1;
668 }
669
670 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
671 otw->wizard->create(sorcery, otw->wizard_data, obj);
672 }
673 ao2_ref(obj, -1);
674
675 return 0;
676}
#define var
Definition ast_expr2f.c:605
void ast_var_list_destroy(struct varshead *head)
Definition chanvars.c:109
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
Definition chanvars.h:51
#define ast_var_assign(name, value)
Definition chanvars.h:40
struct varshead * ast_var_list_create(void)
Definition chanvars.c:97
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
const char * ast_variable_find_last_in_list(const struct ast_variable *list, const char *variable)
Gets the value of the LAST occurrence of a variable from a variable list.
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
#define variable_list_append_return(existing, name, value)
Appends a variable to the end of an existing list. On failure, cause the calling function to return -...
static void * create_object(const struct ast_sorcery *sorcery, const char *id, const char *type, struct ast_variable *vars)
Creates a sorcery object and applies a variable list.
static struct ast_variable * get_object_variables(struct ast_variable *vars, char *prefix)
We need to strip off the prefix from the name of each variable so they're suitable for objectset_appl...
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition sorcery.h:293
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition sorcery.h:316
Support for dynamic strings.
Definition strings.h:623
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References ao2_ref, ast_category_first(), ast_category_get_name(), ast_free, ast_str_buffer(), ast_str_create, ast_str_substitute_variables_varshead(), ast_strlen_zero(), ast_var_assign, ast_var_list_create(), ast_var_list_destroy(), AST_VAR_LIST_INSERT_TAIL(), ast_variable_find_last_in_list(), ast_variables_destroy(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sorcery_wizard::create, create_object(), get_object_variables(), NULL, RAII_VAR, sorcery, ast_sorcery_wizard::update, var, variable_list_append(), variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

◆ handle_auth()

static int handle_auth ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz,
char *  direction 
)
static

Definition at line 550 of file res_pjsip_config_wizard.c.

552{
553 struct ast_variable *wizvars = ast_category_first(wiz);
554 struct ast_sorcery_object *obj = NULL;
555 const char *id = ast_category_get_name(wiz);
556 char new_id[strlen(id) + MAX_ID_SUFFIX];
557 char prefix[strlen(direction) + strlen("_auth/") + 1];
558 char *test_variable = NULL;
560
561 snprintf(prefix, sizeof(prefix), "%s_auth/", direction);
562 vars = get_object_variables(wizvars, prefix);
563
564 if (!strcmp(direction, "outbound")) {
565 snprintf(new_id, sizeof(new_id), "%s-oauth", id);
566 test_variable = "sends_auth";
567 } else {
568 snprintf(new_id, sizeof(new_id), "%s-iauth", id);
569 test_variable = "accepts_auth";
570 }
571
572 if (is_variable_true(wizvars, test_variable)) {
573 if (!ast_variable_find_last_in_list(vars, "username")) {
575 "Wizard '%s' must have '%s_auth/username' if it %s.\n", id, direction, test_variable);
576 return -1;
577 }
578 } else {
579 /* Delete auth if sends or accepts is now false. */
580 obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "auth", new_id);
581 if (obj) {
582 otw->wizard->delete(sorcery, otw->wizard_data, obj);
583 ao2_ref(obj, -1);
584 }
585 return 0;
586 }
587
588 variable_list_append_return(&vars, "@pjsip_wizard", id);
589
590 /* If the user set auth_type, don't override it. */
591 if (!ast_variable_find_last_in_list(vars, "auth_type")) {
592 variable_list_append_return(&vars, "auth_type", "userpass");
593 }
594
595 obj = create_object(sorcery, new_id, "auth", vars);
596 if (!obj) {
597 return -1;
598 }
599
600 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
601 otw->wizard->create(sorcery, otw->wizard_data, obj);
602 }
603 ao2_ref(obj, -1);
604
605 return 0;
606}
direction
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
Definition sorcery.h:296

References ao2_ref, ast_category_first(), ast_category_get_name(), ast_log, ast_variable_find_last_in_list(), ast_variables_destroy(), ast_sorcery_wizard::create, create_object(), ast_sorcery_wizard::delete, get_object_variables(), is_variable_true(), LOG_ERROR, MAX_ID_SUFFIX, NULL, prefix, RAII_VAR, ast_sorcery_wizard::retrieve_id, sorcery, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by handle_auths().

◆ handle_auths()

static int handle_auths ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz 
)
static

Definition at line 608 of file res_pjsip_config_wizard.c.

610{
611 int rc;
612
613 if ((rc = handle_auth(sorcery, otw, wiz, "outbound"))) {
614 return rc;
615 }
616
617 return handle_auth(sorcery, otw, wiz, "inbound");
618}
static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, char *direction)

References handle_auth(), and sorcery.

Referenced by wizard_apply_handler().

◆ handle_endpoint()

static int handle_endpoint ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz 
)
static

Definition at line 678 of file res_pjsip_config_wizard.c.

680{
681 struct ast_variable *wizvars = ast_category_first(wiz);
682 struct ast_sorcery_object *obj = NULL;
683 const char *id = ast_category_get_name(wiz);
684 const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
685 const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
686 const char *hint_context = hint_context = ast_variable_find_last_in_list(wizvars, "hint_context");
687 const char *hint_exten = ast_variable_find_last_in_list(wizvars, "hint_exten");
688 const char *hint_application= ast_variable_find_last_in_list(wizvars, "hint_application");
689 char new_id[strlen(id) + MAX_ID_SUFFIX];
690 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "endpoint/"), ast_variables_destroy);
691
692 variable_list_append_return(&vars, "@pjsip_wizard", id);
693 variable_list_append_return(&vars, "aors", id);
694
695 if (!ast_strlen_zero(outbound_proxy)) {
696 variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
697 }
698
699 if (ast_strlen_zero(hint_context)) {
700 hint_context = ast_variable_find_last_in_list(vars, "context");
701 }
702
703 if (ast_strlen_zero(hint_context)) {
704 hint_context = "default";
705 }
706
707 if (!ast_strlen_zero(hint_exten)) {
708 /* These are added so we can find and delete the hints when the endpoint gets deleted */
709 variable_list_append_return(&vars, "@hint_context", hint_context);
710 variable_list_append_return(&vars, "@hint_exten", hint_exten);
711 }
712
713 if (!ast_strlen_zero(transport)) {
714 variable_list_append_return(&vars, "transport", transport);
715 }
716
717 if (is_variable_true(wizvars, "sends_auth")) {
718 snprintf(new_id, sizeof(new_id), "%s-oauth", id);
719 variable_list_append_return(&vars, "outbound_auth", new_id);
720 }
721
722 if (is_variable_true(wizvars, "accepts_auth")) {
723 snprintf(new_id, sizeof(new_id), "%s-iauth", id);
724 variable_list_append_return(&vars, "auth", new_id);
725 }
726
727 obj = create_object(sorcery, id, "endpoint", vars);
728 if (!obj) {
729 return -1;
730 }
731
732 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
733 otw->wizard->create(sorcery, otw->wizard_data, obj);
734 }
735 ao2_ref(obj, -1);
736
737 if (!ast_strlen_zero(hint_exten)) {
738 if (is_variable_true(wizvars, "has_hint")) {
739 add_hints(hint_context, hint_exten, hint_application, id);
740 } else {
741 delete_extens(hint_context, hint_exten);
742 }
743 }
744
745 return 0;
746}
static int add_hints(const char *context, const char *exten, const char *application, const char *id)

References add_hints(), ao2_ref, ast_category_first(), ast_category_get_name(), ast_strlen_zero(), ast_variable_find_last_in_list(), ast_variables_destroy(), ast_sorcery_wizard::create, create_object(), delete_extens(), get_object_variables(), is_variable_true(), MAX_ID_SUFFIX, NULL, RAII_VAR, sorcery, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

◆ handle_export_primitives()

static char * handle_export_primitives ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1237 of file res_pjsip_config_wizard.c.

1238{
1239 struct ast_sorcery *sorcery;
1240 int idx;
1241 FILE *f = NULL;
1242 const char *fn = NULL;
1243
1244 switch (cmd) {
1245 case CLI_INIT:
1246 e->command = "pjsip export config_wizard primitives [to]";
1247 e->usage =
1248 "Usage: pjsip export config_wizard primitives [ to <filename ]\n"
1249 " Export the config_wizard objects as pjsip primitives to\n"
1250 " the console or to <filename>\n";
1251 return NULL;
1252 case CLI_GENERATE:
1253 return NULL;
1254 }
1255
1256 if (a->argc > 5) {
1257 char date[256]="";
1258 time_t t;
1259 fn = a->argv[5];
1260
1261 time(&t);
1262 ast_copy_string(date, ctime(&t), sizeof(date));
1263 f = fopen(fn, "w");
1264 if (!f) {
1265 ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
1266 return CLI_FAILURE;
1267 }
1268
1269 fprintf(f, ";!\n");
1270 fprintf(f, ";! Automatically generated configuration file\n");
1271 fprintf(f, ";! Filename: %s\n", fn);
1272 fprintf(f, ";! Generator: %s\n", "'pjsip export config_wizard primitives'");
1273 fprintf(f, ";! Creation Date: %s", date);
1274 fprintf(f, ";!\n");
1275 }
1276
1278
1279 AST_VECTOR_RW_RDLOCK(&object_type_wizards);
1280 for(idx = 0; idx < AST_VECTOR_SIZE(&object_type_wizards); idx++) {
1281 struct object_type_wizard *otw = AST_VECTOR_GET(&object_type_wizards, idx);
1282 struct ao2_container *container;
1283 struct ao2_iterator i;
1284 void *o;
1285
1287 if (!container) {
1288 continue;
1289 }
1290
1292 while ((o = ao2_iterator_next(&i))) {
1293 struct ast_variable *vars;
1294 struct ast_variable *v;
1295
1297 if (vars && ast_variable_find_in_list(vars, "@pjsip_wizard")) {
1298 if (f) {
1299 fprintf(f, "\n[%s]\ntype = %s\n", ast_sorcery_object_get_id(o), otw->object_type);
1300 } else {
1301 ast_cli(a->fd, "\n[%s]\ntype = %s\n", ast_sorcery_object_get_id(o), otw->object_type);
1302 }
1303 for (v = vars; v; v = v->next) {
1304 if (!ast_strlen_zero(v->value)) {
1305 if (f) {
1306 fprintf(f, "%s = %s\n", v->name, v->value);
1307 } else {
1308 ast_cli(a->fd, "%s = %s\n", v->name, v->value);
1309 }
1310 }
1311 }
1312 }
1314 ao2_ref(o, -1);
1315 }
1318 }
1319 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
1320
1321 if (f) {
1322 fclose(f);
1323 ast_cli(a->fd, "Wrote configuration to %s\n", fn);
1324 }
1325
1326
1327 return CLI_SUCCESS;
1328}
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
#define ao2_cleanup(obj)
Definition astobj2.h:1934
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define CLI_SUCCESS
Definition cli.h:44
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
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.
int errno
struct ao2_container * container
Definition res_fax.c:603
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition sorcery.h:1137
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition sorcery.h:120
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:1961
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
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
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
Full structure for sorcery.
Definition sorcery.c:231
static struct test_val a

References a, ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), ast_copy_string(), ast_log, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_objectset_create, ast_sorcery_retrieve_by_fields(), ast_strlen_zero(), ast_variable_find_in_list(), ast_variables_destroy(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, container, errno, LOG_ERROR, ast_variable::name, ast_variable::next, NULL, object_type_wizard::object_type, sorcery, ast_cli_entry::usage, and ast_variable::value.

◆ handle_identify()

static int handle_identify ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz,
struct string_vector remote_hosts_vector 
)
static

Definition at line 748 of file res_pjsip_config_wizard.c.

750{
751 struct ast_variable *wizvars = ast_category_first(wiz);
752 struct ast_sorcery_object *obj = NULL;
753 const char *id = ast_category_get_name(wiz);
754 char new_id[strlen(id) + MAX_ID_SUFFIX];
755 int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
756 int host_counter;
757 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "identify/"), ast_variables_destroy);
758
759 snprintf(new_id, sizeof(new_id), "%s-identify", id);
760
761 /* If accepting registrations or we're sending line, we don't need an identify. */
762 if (is_variable_true(wizvars, "accepts_registrations")
763 || is_variable_true(wizvars, "sends_line_with_registrations")) {
764 /* If one exists, delete it. */
765 obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "identify", new_id);
766 if (obj) {
767 otw->wizard->delete(sorcery, otw->wizard_data, obj);
768 ao2_ref(obj, -1);
769 }
770 return 0;
771 }
772
773 if (!host_count) {
775 "Wizard '%s' must have 'remote_hosts' if it doesn't accept registrations.\n", id);
776 return -1;
777 }
778
779 variable_list_append_return(&vars, "endpoint", id);
780 variable_list_append_return(&vars, "@pjsip_wizard", id);
781
782 if (!ast_variable_find_last_in_list(vars, "match")) {
783 for (host_counter = 0; host_counter < host_count; host_counter++) {
784 variable_list_append_return(&vars, "match",
785 AST_VECTOR_GET(remote_hosts_vector, host_counter));
786 }
787 }
788
789 obj = create_object(sorcery, new_id, "identify", vars);
790 if (!obj) {
791 return -1;
792 }
793
794 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
795 otw->wizard->create(sorcery, otw->wizard_data, obj);
796 }
797 ao2_ref(obj, -1);
798
799 return 0;
800}

References ao2_ref, ast_category_first(), ast_category_get_name(), ast_log, ast_variable_find_last_in_list(), ast_variables_destroy(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sorcery_wizard::create, create_object(), ast_sorcery_wizard::delete, get_object_variables(), is_variable_true(), LOG_ERROR, MAX_ID_SUFFIX, NULL, RAII_VAR, ast_sorcery_wizard::retrieve_id, sorcery, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

◆ handle_phoneprov()

static int handle_phoneprov ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz 
)
static

Definition at line 802 of file res_pjsip_config_wizard.c.

804{
805 struct ast_variable *wizvars = ast_category_first(wiz);
806 struct ast_sorcery_object *obj = NULL;
807 const char *id = ast_category_get_name(wiz);
808 char new_id[strlen(id) + MAX_ID_SUFFIX];
809 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "phoneprov/"), ast_variables_destroy);
810
811 snprintf(new_id, sizeof(new_id), "%s-phoneprov", id);
812
813 if (!is_variable_true(wizvars, "has_phoneprov")) {
814 obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "phoneprov", new_id);
815 if (obj) {
816 otw->wizard->delete(sorcery, otw->wizard_data, obj);
817 ao2_ref(obj, -1);
818 }
819 return 0;
820 }
821
822 if (!ast_variable_find_last_in_list(wizvars, "phoneprov/MAC")) {
824 "Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n", id);
825 return -1;
826 }
827
828 variable_list_append_return(&vars, "endpoint", id);
829 variable_list_append_return(&vars, "@pjsip_wizard", id);
830
831 obj = create_object(sorcery, new_id, "phoneprov", vars);
832 if (!obj) {
833 return -1;
834 }
835
836 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
837 otw->wizard->create(sorcery, otw->wizard_data, obj);
838 }
839 ao2_ref(obj, -1);
840
841 return 0;
842}

References ao2_ref, ast_category_first(), ast_category_get_name(), ast_log, ast_variable_find_last_in_list(), ast_variables_destroy(), ast_sorcery_wizard::create, create_object(), ast_sorcery_wizard::delete, get_object_variables(), is_variable_true(), LOG_ERROR, MAX_ID_SUFFIX, NULL, RAII_VAR, ast_sorcery_wizard::retrieve_id, sorcery, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

◆ handle_registrations()

static int handle_registrations ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz,
struct string_vector remote_hosts_vector 
)
static

Definition at line 861 of file res_pjsip_config_wizard.c.

863{
864 struct ast_variable *search;
865 struct ast_variable *wizvars = ast_category_first(wiz);
866 const char *id = ast_category_get_name(wiz);
867 const char *server_uri_pattern;
868 const char *client_uri_pattern;
869 const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
870 const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
871 const char *username;
872 char new_id[strlen(id) + MAX_ID_SUFFIX];
873 int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
874 int host_counter;
875 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "registration/"), ast_variables_destroy);
876 RAII_VAR(struct ao2_container *, existing,
878
879 if (!existing) {
880 return -1;
881 }
882
883 /* Find any existing registrations. */
884 search = ast_variable_new("@pjsip_wizard", id, "");
885 if (!search) {
886 return -1;
887 }
888
889 if (!ast_strlen_zero(outbound_proxy)) {
890 variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
891 }
892
893 otw->wizard->retrieve_multiple(sorcery, otw->wizard_data, "registration", existing, search);
894 ast_variables_destroy(search);
895
896 /* If not sending registrations, delete ALL existing registrations for this wizard. */
897 if (!is_variable_true(wizvars, "sends_registrations")) {
898 if (ao2_container_count(existing) > 0) {
900 }
901 return 0;
902 }
903
904 if (!host_count) {
905 ast_log(LOG_ERROR, "Wizard '%s' must have 'remote_hosts' if it sends registrations.\n", id);
906 return -1;
907 }
908
909 variable_list_append_return(&vars, "@pjsip_wizard", id);
910
911 if (!(server_uri_pattern = ast_variable_find_last_in_list(wizvars, "server_uri_pattern"))) {
912 server_uri_pattern = "sip:${REMOTE_HOST}";
913 }
914
915 if (!(client_uri_pattern = ast_variable_find_last_in_list(wizvars, "client_uri_pattern"))) {
916 client_uri_pattern = "sip:${USERNAME}@${REMOTE_HOST}";
917 }
918
919 if (is_variable_true(wizvars, "sends_auth")) {
920 if (!(username = ast_variable_find_last_in_list(wizvars, "outbound_auth/username"))) {
921 ast_log(LOG_ERROR, "Wizard '%s' must have 'outbound_auth/username' if it sends"
922 " authentication.\n", id);
923 return -1;
924 }
925 } else {
926 username = id;
927 }
928
929
930 /* Unlike aor and identify, we need to create a separate registration object
931 * for each remote host.
932 */
933 for (host_counter = 0; host_counter < host_count; host_counter++) {
934 struct ast_var_t *rh = ast_var_assign("REMOTE_HOST",
935 AST_VECTOR_GET(remote_hosts_vector, host_counter));
936 struct ast_var_t *un = ast_var_assign("USERNAME", username);
937 struct ast_sorcery_object *obj;
938 RAII_VAR(struct ast_str *, uri, ast_str_create(64), ast_free);
940 RAII_VAR(struct ast_variable *, registration_vars, vars ? ast_variables_dup(vars) : NULL, ast_variables_destroy);
941
942 AST_VAR_LIST_INSERT_TAIL(subst_vars, rh);
943 AST_VAR_LIST_INSERT_TAIL(subst_vars, un);
944
945 if (!ast_strlen_zero(server_uri_pattern)) {
946 ast_str_substitute_variables_varshead(&uri, 0, subst_vars,
947 server_uri_pattern);
948 variable_list_append_return(&registration_vars, "server_uri", ast_str_buffer(uri));
949 }
950
951 if (!ast_strlen_zero(client_uri_pattern)) {
952 ast_str_reset(uri);
953 ast_str_substitute_variables_varshead(&uri, 0, subst_vars,
954 client_uri_pattern);
955 variable_list_append_return(&registration_vars, "client_uri", ast_str_buffer(uri));
956 }
957
958 if (is_variable_true(wizvars, "sends_auth")) {
959 snprintf(new_id, sizeof(new_id), "%s-oauth", id);
960 variable_list_append_return(&registration_vars, "outbound_auth", new_id);
961 }
962
963 if (!ast_strlen_zero(transport)) {
964 variable_list_append_return(&registration_vars, "transport", transport);
965 }
966
967 if (is_variable_true(wizvars, "sends_line_with_registrations")) {
968 variable_list_append_return(&registration_vars, "line", "yes");
969 variable_list_append_return(&registration_vars, "endpoint", id);
970 }
971
972 snprintf(new_id, sizeof(new_id), "%s-reg-%d", id, host_counter);
973
974 obj = create_object(sorcery, new_id, "registration", registration_vars);
975 if (!obj) {
976 return -1;
977 }
978
979 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
980 otw->wizard->create(sorcery, otw->wizard_data, obj);
981 }
982 ao2_ref(obj, -1);
983
984 /* Unlink it from the 'existing' container. Any left will be deleted from
985 * sorcery. If it wasn't in the existing container, no harm.
986 */
988 }
989
990 /* If there are any excess registrations, delete them. */
991 if (ao2_container_count(existing) > 0) {
993 }
994
995 return 0;
996}
enum queue_result id
Definition app_queue.c:1790
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
@ OBJ_NODATA
Definition astobj2.h:1044
@ OBJ_MULTIPLE
Definition astobj2.h:1049
@ OBJ_UNLINK
Definition astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition astobj2.h:1101
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition astobj2.h:1327
static rc_handle * rh
Definition cdr_radius.c:96
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
static int delete_existing_cb(void *obj, void *arg, int flags)
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition sorcery.c:2528
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition strings.h:693
void(* retrieve_multiple)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
Optional callback for retrieving multiple objects using some optional field criteria.
Definition sorcery.h:313

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_ref, ast_category_first(), ast_category_get_name(), ast_free, ast_log, ast_sorcery_object_id_compare(), ast_str_buffer(), ast_str_create, ast_str_reset(), ast_str_substitute_variables_varshead(), ast_strlen_zero(), ast_var_assign, ast_var_list_create(), ast_var_list_destroy(), AST_VAR_LIST_INSERT_TAIL(), ast_variable_find_last_in_list(), ast_variable_new, ast_variables_destroy(), ast_variables_dup(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sorcery_wizard::create, create_object(), delete_existing_cb(), get_object_variables(), id, is_variable_true(), LOG_ERROR, MAX_ID_SUFFIX, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, RAII_VAR, ast_sorcery_wizard::retrieve_multiple, rh, sorcery, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

◆ instance_created_observer()

static void instance_created_observer ( const char *  name,
struct ast_sorcery sorcery 
)
static

When the res_pjsip instance is created, add an observer to it and initialize the wizard vector. Also, bump the module's ref count so it can't be unloaded before the sorcery instance is destroyed.

Definition at line 1215 of file res_pjsip_config_wizard.c.

1216{
1217 if (strcmp(name, "res_pjsip")) {
1218 return;
1219 }
1222}
#define ast_module_ref(mod)
Hold a reference to the module.
Definition module.h:457
struct ast_sorcery_instance_observer observer
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
Definition sorcery.c:584
struct ast_module * self
Definition module.h:356

References ast_module_ref, ast_sorcery_instance_observer_add(), name, observer, ast_module_info::self, and sorcery.

◆ instance_destroying_observer()

static void instance_destroying_observer ( const char *  name,
struct ast_sorcery sorcery 
)
static

When the res_pjsip instance is destroyed, remove the observer and unref the module. This should then allow this module to unload cleanly.

Definition at line 1227 of file res_pjsip_config_wizard.c.

1228{
1229 if (strcmp(name, "res_pjsip")) {
1230 return;
1231 }
1232
1235}
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
Definition sorcery.c:601

References ast_module_unref, ast_sorcery_instance_observer_remove(), name, observer, ast_module_info::self, and sorcery.

◆ is_one_of()

static int is_one_of ( const char *  needle,
const char *  haystack[] 
)
static

Definition at line 319 of file res_pjsip_config_wizard.c.

320{
321 int i;
322 for (i = 0; haystack[i]; i++) {
323 if (!strcmp(needle, haystack[i])) {
324 return 1;
325 }
326 }
327
328 return 0;
329}

Referenced by object_type_registered_observer().

◆ is_variable_true()

static int is_variable_true ( struct ast_variable vars,
const char *  name 
)
static

Finds the last variable in a list and tests it.

Definition at line 370 of file res_pjsip_config_wizard.c.

371{
373}
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition utils.c:2233

References ast_true(), ast_variable_find_last_in_list(), and name.

Referenced by handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), and handle_registrations().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1340 of file res_pjsip_config_wizard.c.

1341{
1342 AST_VECTOR_RW_INIT(&object_type_wizards, 12);
1345
1347
1348 /* If the PJSIP sorcery instance exists it means that we have been explicitly
1349 * loaded and things are potentially already set up. Since we won't receive any
1350 * observer callbacks informing us of this we add ourselves to the instance
1351 * as an observer in case it goes away, and determine which object types have
1352 * been registered and synthesize the observer callbacks for them. Once done
1353 * we force a reload so we are aware of the state of things.
1354 */
1355 if (ast_sip_get_sorcery()) {
1356 int i;
1357
1360
1361 /* See which object types already exist */
1362 for (i = 0; i < ARRAY_LEN(object_types); ++i) {
1363 if (!object_types[i]) {
1364 break;
1365 } else if (!ast_sorcery_get_object_type(ast_sip_get_sorcery(), object_types[i])) {
1366 continue;
1367 }
1368
1370 object_types[i]);
1371 }
1372
1374 }
1375
1377}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
static struct stasis_subscription * acl_change_sub
static const struct ast_sorcery_global_observer global_observer
static void object_type_registered_observer(const char *name, struct ast_sorcery *sorcery, const char *object_type)
When each object type is registered, map a memory wizard to it.
static struct ast_cli_entry config_wizard_cli[]
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Callback for Named ACL changed.
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
Definition sorcery.c:2558
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
Definition sorcery.c:562
#define stasis_subscribe(topic, callback, data)
Definition stasis.h:649
#define ARRAY_LEN(a)
Definition utils.h:706
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition vector.h:169

References acl_change_stasis_cb(), acl_change_sub, ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_SUCCESS, ast_module_ref, ast_security_topic(), ast_sip_get_sorcery(), ast_sorcery_get_object_type(), ast_sorcery_global_observer_add(), ast_sorcery_instance_observer_add(), ast_sorcery_reload(), AST_VECTOR_RW_INIT, config_wizard_cli, global_observer, NULL, object_type_registered_observer(), observer, ast_module_info::self, and stasis_subscribe.

◆ object_type_loaded_observer()

static void object_type_loaded_observer ( const char *  name,
const struct ast_sorcery sorcery,
const char *  object_type,
int  reloaded 
)
static

Called after an object type is loaded/reloaded.

Definition at line 1066 of file res_pjsip_config_wizard.c.

1068{
1069 struct ast_category *category = NULL;
1070 struct object_type_wizard *otw = NULL;
1071 char *filename = "pjsip_wizard.conf";
1072 struct ast_flags flags = { 0 };
1073 struct ast_config *cfg;
1074
1075 if (!strstr("auth aor endpoint identify registration phoneprov", object_type)) {
1076 /* Not interested. */
1077 return;
1078 }
1079
1080 otw = find_wizard(object_type);
1081 if (!otw) {
1082 ast_log(LOG_ERROR, "There was no wizard for object type '%s'\n", object_type);
1083 return;
1084 }
1085
1086 /* Only use the FILEUNCHANGED optimization if the ACLs haven't changed.
1087 * If ACLs changed, we force a reload of the config file to re-evaluate rules. */
1088 if (reloaded && otw->last_config && !acl_change_detected) {
1090 }
1091
1092 cfg = ast_config_load2(filename, object_type, flags);
1093
1094 if (!cfg) {
1095 ast_log(LOG_ERROR, "Unable to load config file '%s'\n", filename);
1096 return;
1097 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
1098 ast_debug(2, "Config file '%s' was unchanged for '%s'.\n", filename, object_type);
1099 return;
1100 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
1101 ast_log(LOG_ERROR, "Contents of config file '%s' are invalid and cannot be parsed\n", filename);
1102 return;
1103 }
1104
1105 while ((category = ast_category_browse_filtered(cfg, NULL, category, "type=^wizard$"))) {
1106 const char *id = ast_category_get_name(category);
1107 struct ast_category *last_cat = NULL;
1108 int changes = 0;
1109
1110 if (otw->last_config) {
1111 last_cat = ast_category_get(otw->last_config, id, "type=^wizard$");
1112 changes = !ast_variable_lists_match(ast_category_first(category), ast_category_first(last_cat), 1);
1113
1114 /* If the ACL has changed, we assume EVERYTHING might have changed.
1115 * We force an update for all wizard objects. */
1116 if (!changes && reloaded && acl_change_detected) {
1117 ast_debug(3, "Forcing update of wizard '%s' due to global ACL change.\n", id);
1118 changes = 1;
1119 }
1120
1121 if (last_cat) {
1122 ast_category_delete(otw->last_config, last_cat);
1123 }
1124 }
1125
1126 if (!last_cat || changes) {
1127 ast_debug(3, "%s: %s(s) for wizard '%s'\n", reloaded ? "Reload" : "Load", object_type, id);
1128 if (wizard_apply_handler(sorcery, otw, category)) {
1129 ast_log(LOG_ERROR, "Unable to create objects for wizard '%s'\n", id);
1130 }
1131 }
1132 }
1133
1134 if (!otw->last_config) {
1135 otw->last_config = cfg;
1136 return;
1137 }
1138
1139 /* Only wizards that weren't in the new config are left in last_config now so we need to delete
1140 * all objects belonging to them.
1141 */
1142 category = NULL;
1143 while ((category = ast_category_browse_filtered(otw->last_config, NULL, category, "type=^wizard$"))) {
1144 const char *id = ast_category_get_name(category);
1145 struct ast_variable *search;
1146 RAII_VAR(struct ao2_container *, existing,
1148
1149 if (!existing) {
1150 ast_log(LOG_ERROR, "Unable to allocate temporary container.\n");
1151 break;
1152 }
1153
1154 search = ast_variable_new("@pjsip_wizard", id, "");
1155 if (!search) {
1156 ast_log(LOG_ERROR, "Unable to allocate memory for vaiable '@pjsip_wizard'.\n");
1157 break;
1158 }
1159 otw->wizard->retrieve_multiple(sorcery, otw->wizard_data, object_type, existing, search);
1160 ast_variables_destroy(search);
1161
1162 if (ao2_container_count(existing) > 0) {
1163 ast_debug(3, "Delete on %s: %d %s(s) for wizard: %s\n",
1164 reloaded ? "Reload" : "Load", ao2_container_count(existing), object_type, id);
1166 delete_existing_cb, otw);
1167 }
1168 }
1169
1171 otw->last_config = cfg;
1172}
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *cat)
Delete a category.
#define CONFIG_STATUS_FILEUNCHANGED
@ CONFIG_FLAG_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
int ast_variable_lists_match(const struct ast_variable *left, const struct ast_variable *right, int exact_match)
Tests 2 variable lists to see if they match.
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
static struct object_type_wizard * find_wizard(const char *object_type)
Finds the otw for the object type.
static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
Structure used to handle boolean flags.
Definition utils.h:220
unsigned int flags
Definition utils.h:221
struct ast_config * last_config

References acl_change_detected, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ast_category_browse_filtered(), ast_category_delete(), ast_category_first(), ast_category_get(), ast_category_get_name(), ast_config_destroy(), ast_config_load2(), ast_debug, ast_log, ast_variable_lists_match(), ast_variable_new, ast_variables_destroy(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, delete_existing_cb(), find_wizard(), ast_flags::flags, id, object_type_wizard::last_config, LOG_ERROR, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, RAII_VAR, ast_sorcery_wizard::retrieve_multiple, sorcery, object_type_wizard::wizard, wizard_apply_handler(), and object_type_wizard::wizard_data.

◆ object_type_registered_observer()

static void object_type_registered_observer ( const char *  name,
struct ast_sorcery sorcery,
const char *  object_type 
)
static

When each object type is registered, map a memory wizard to it.

Definition at line 1175 of file res_pjsip_config_wizard.c.

1177{
1178 struct ast_sorcery_wizard *wizard;
1179 void *wizard_data;
1180 struct object_type_wizard *otw;
1181
1182 if (is_one_of(object_type, object_types)) {
1186 ast_log(LOG_ERROR, "Unable to apply sangoma wizard to object type '%s'\n", object_type);
1187 return;
1188 }
1189
1190 otw = ast_malloc(sizeof(*otw) + strlen(object_type) + 1);
1191 if (!otw) {
1192 return;
1193 }
1194
1195 otw->sorcery = sorcery;
1196 otw->wizard = wizard;
1197 otw->wizard_data = wizard_data;
1198 otw->last_config = NULL;
1199 strcpy(otw->object_type, object_type); /* Safe */
1200 AST_VECTOR_RW_WRLOCK(&object_type_wizards);
1201 if (AST_VECTOR_APPEND(&object_type_wizards, otw)) {
1202 ast_free(otw);
1203 } else {
1204 ast_debug(1, "Wizard mapped for object_type '%s'\n", object_type);
1205 }
1206 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
1207
1208 }
1209}
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
static int is_one_of(const char *needle, const char *haystack[])
@ AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
Definition sorcery.h:583
@ AST_SORCERY_WIZARD_APPLY_READONLY
Definition sorcery.h:581
@ AST_SORCERY_APPLY_SUCCESS
Definition sorcery.h:427
#define ast_sorcery_object_type_apply_wizard(sorcery, object_type_name, wizard_type_name, wizard_args, flags, wizard, wizard_data)
Apply additional object wizard mappings returning wizard information.
Definition sorcery.h:678
Interface for a sorcery wizard.
Definition sorcery.h:276
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition vector.h:898
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition vector.h:267

References ast_debug, ast_free, ast_log, ast_malloc, AST_SORCERY_APPLY_SUCCESS, ast_sorcery_object_type_apply_wizard, AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE, AST_SORCERY_WIZARD_APPLY_READONLY, AST_VECTOR_APPEND, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, is_one_of(), object_type_wizard::last_config, LOG_ERROR, NULL, object_type_wizard::object_type, sorcery, object_type_wizard::sorcery, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by load_module().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1334 of file res_pjsip_config_wizard.c.

1335{
1337 return 0;
1338}

References ast_sip_get_sorcery(), and ast_sorcery_reload().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1379 of file res_pjsip_config_wizard.c.

1380{
1381 if (acl_change_sub) {
1383 }
1384
1388 AST_VECTOR_RW_FREE(&object_type_wizards);
1389
1390 return 0;
1391}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
#define NOT_EQUALS(a, b)
#define OTW_DELETE_CB(otw)
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
Definition sorcery.c:578
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition stasis.c:1201
#define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove all elements from a vector that matches the given comparison.
Definition vector.h:472
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
Definition vector.h:213

References acl_change_sub, ARRAY_LEN, ast_cli_unregister_multiple(), ast_sorcery_global_observer_remove(), AST_VECTOR_REMOVE_ALL_CMP_UNORDERED, AST_VECTOR_RW_FREE, config_wizard_cli, global_observer, NOT_EQUALS, NULL, OTW_DELETE_CB, and stasis_unsubscribe_and_join().

◆ variable_list_append()

static int variable_list_append ( struct ast_variable **  existing,
const char *  name,
const char *  value 
)
static

Appends a variable to the end of an existing list.

Definition at line 376 of file res_pjsip_config_wizard.c.

377{
378 struct ast_variable *new = ast_variable_new(name, value, "");
379
380 if (!new) {
381 ast_log(LOG_ERROR, "Unable to allocate memory for new variable '%s'.\n", name);
382 return -1;
383 }
384
385 ast_variable_list_append(existing, new);
386
387 return 0;
388}
#define ast_variable_list_append(head, new_var)

References ast_log, ast_variable_list_append, ast_variable_new, LOG_ERROR, name, and value.

Referenced by get_object_variables(), and handle_aor().

◆ wizard_apply_handler()

static int wizard_apply_handler ( const struct ast_sorcery sorcery,
struct object_type_wizard otw,
struct ast_category wiz 
)
static

Definition at line 998 of file res_pjsip_config_wizard.c.

1000{
1001 struct ast_variable *wizvars = ast_category_first(wiz);
1002 struct string_vector remote_hosts_vector;
1003 const char *remote_hosts;
1004 int rc = -1;
1005
1006 AST_VECTOR_INIT(&remote_hosts_vector, 16);
1007 remote_hosts = ast_variable_find_last_in_list(wizvars, "remote_hosts");
1008
1009 if (!ast_strlen_zero(remote_hosts)) {
1010 char *host;
1011 char *hosts = ast_strdupa(remote_hosts);
1012
1013 while ((host = ast_strsep(&hosts, ',', AST_STRSEP_TRIM))) {
1014 host = ast_strdup(host);
1015 if (host && AST_VECTOR_APPEND(&remote_hosts_vector, host)) {
1016 ast_free(host);
1017 }
1018 }
1019 }
1020
1021 ast_debug(4, "%s handler starting.\n", otw->object_type);
1022
1023 if (!strcmp(otw->object_type, "auth")) {
1024 rc = handle_auths(sorcery, otw, wiz);
1025 } else if (!strcmp(otw->object_type, "aor")) {
1026 rc = handle_aor(sorcery, otw, wiz, &remote_hosts_vector);
1027 } else if (!strcmp(otw->object_type, "endpoint")) {
1028 rc = handle_endpoint(sorcery, otw, wiz);
1029 } else if (!strcmp(otw->object_type, "identify")) {
1030 rc = handle_identify(sorcery, otw, wiz, &remote_hosts_vector);
1031 } else if (!strcmp(otw->object_type, "phoneprov")) {
1032 rc = handle_phoneprov(sorcery, otw, wiz);
1033 } else if (!strcmp(otw->object_type, "registration")) {
1034 rc = handle_registrations(sorcery, otw, wiz, &remote_hosts_vector);
1035 }
1036
1038 AST_VECTOR_FREE(&remote_hosts_vector);
1039
1040 ast_debug(4, "%s handler complete. rc: %d\n", otw->object_type, rc);
1041
1042 return rc;
1043}
static int handle_aor(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
static int handle_registrations(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
static int handle_identify(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
static int handle_auths(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
static int handle_phoneprov(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
@ AST_STRSEP_TRIM
Definition strings.h:256
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition utils.c:1869
A generic char * vector definition.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition vector.h:185
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition vector.h:124

References ast_category_first(), ast_debug, ast_free, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_strsep(), AST_STRSEP_TRIM, ast_variable_find_last_in_list(), AST_VECTOR_APPEND, AST_VECTOR_FREE, AST_VECTOR_INIT, AST_VECTOR_REMOVE_ALL_CMP_UNORDERED, handle_aor(), handle_auths(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), NOT_EQUALS, NULL, object_type_wizard::object_type, and sorcery.

Referenced by object_type_loaded_observer().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Config Wizard" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
static

Definition at line 1399 of file res_pjsip_config_wizard.c.

◆ acl_change_detected

int acl_change_detected = 0
static

Definition at line 303 of file res_pjsip_config_wizard.c.

Referenced by acl_change_stasis_cb(), and object_type_loaded_observer().

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

Definition at line 304 of file res_pjsip_config_wizard.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1399 of file res_pjsip_config_wizard.c.

◆ config_wizard_cli

struct ast_cli_entry config_wizard_cli[]
static
Initial value:
= {
{ .handler = handle_export_primitives , .summary = "Export config wizard primitives" ,},
}
static char * handle_export_primitives(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 1330 of file res_pjsip_config_wizard.c.

1330 {
1331 AST_CLI_DEFINE(handle_export_primitives, "Export config wizard primitives"),
1332};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by load_module(), and unload_module().

◆ global_observer

const struct ast_sorcery_global_observer global_observer
static
Initial value:
= {
.instance_created = instance_created_observer,
.instance_destroying = instance_destroying_observer,
}
static void instance_destroying_observer(const char *name, struct ast_sorcery *sorcery)
When the res_pjsip instance is destroyed, remove the observer and unref the module....
static void instance_created_observer(const char *name, struct ast_sorcery *sorcery)
When the res_pjsip instance is created, add an observer to it and initialize the wizard vector....

Definition at line 1055 of file res_pjsip_config_wizard.c.

1055 {
1056 .instance_created = instance_created_observer,
1057 .instance_destroying = instance_destroying_observer,
1058};

Referenced by load_module(), and unload_module().

◆ observer

Initial value:
= {
.object_type_registered = object_type_registered_observer,
.object_type_loaded = object_type_loaded_observer,
}
static void object_type_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Called after an object type is loaded/reloaded.

Definition at line 1060 of file res_pjsip_config_wizard.c.

1060 {
1061 .object_type_registered = object_type_registered_observer,
1062 .object_type_loaded = object_type_loaded_observer,
1063};

Referenced by ast_mwi_add_observer(), ast_mwi_remove_observer(), ast_sorcery_observer_add(), instance_created_observer(), instance_destroying_observer(), load_module(), sorcery_generic_observer_remove(), sorcery_observer_notify_create(), sorcery_observer_notify_delete(), sorcery_observer_notify_loaded(), sorcery_observer_notify_update(), sorcery_observer_remove(), stasis_state_add_observer(), and stasis_state_remove_observer().