Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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 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. More...
 
#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. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static int wizard_apply_handler (const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
 
static void wizard_mapped_observer (const char *name, struct ast_sorcery *sorcery, const char *object_type, struct ast_sorcery_wizard *wizard, const char *wizard_args, void *wizard_data)
 When each wizard is mapped, save it off to the vector. More...
 

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 = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
 
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 276 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 274 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 373 of file res_pjsip_config_wizard.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1339 of file res_pjsip_config_wizard.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1339 of file res_pjsip_config_wizard.c.

◆ add_extension()

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

Definition at line 420 of file res_pjsip_config_wizard.c.

422{
423 struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
424 struct ast_exten *existing_exten;
425 char *data = NULL;
426 char *app = NULL;
427 void *free_ptr = NULL;
428 char *paren;
429 const char *context_name;
430
431 if (!context || ast_strlen_zero(exten) || ast_strlen_zero(application)) {
432 return -1;
433 }
434
435 /* The incoming application has to be split into the app name and the
436 * arguments (data). The app name can be any storage type as add_extension
437 * copies it into its own buffer. Data however, needs to be dynamically
438 * allocated and a free function provided.
439 */
440
441 paren = strchr(application, '(');
442 if (!paren) {
443 app = (char *)application;
444 } else {
445 app = ast_strdupa(application);
446 app[paren - application] = '\0';
447 data = ast_strdup(paren + 1);
448 if (!data) {
449 return -1;
450 }
451 data[strlen(data) - 1] = '\0';
452 free_ptr = ast_free_ptr;
454 ast_free(data);
455 return -1;
456 }
457 }
458
459 /* Don't disturb existing, exact-match, entries. */
461 if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, context_name, exten,
462 priority, NULL, NULL, E_MATCH))) {
463 const char *existing_app = ast_get_extension_app(existing_exten);
464 const char *existing_data = ast_get_extension_app_data(existing_exten);
465 if (!strcmp(existing_app, app)
466 && !strcmp(existing_data ? existing_data : "", data ? data : "")) {
467 ast_free(data);
468 return 0;
469 }
470
472 }
473
475 app, data, free_ptr, BASE_REGISTRAR, NULL, 0)) {
476 return -1;
477 }
478
479 return 0;
480}
#define paren
Definition: ael_lex.c:962
static const char app[]
Definition: app_adsiprog.c:56
#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:8562
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:4978
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:8557
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:7266
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:237
char * exten
Definition: pbx.c:238
void * data
Definition: pbx.c:248
int stacklen
Definition: extconf.h:237

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, voicemailpwcheck::context, 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 482 of file res_pjsip_config_wizard.c.

483{
484 struct ast_context *hint_context;
485 char *hint_device;
486
487 hint_device = ast_alloca(strlen("PJSIP/") + strlen(id) + 1);
488 sprintf(hint_device, "PJSIP/%s", id);
489
490 /* We need the contexts list locked to safely be able to both read and lock the specific context within */
491 if (ast_wrlock_contexts()) {
492 ast_log(LOG_ERROR, "Failed to lock the contexts list.\n");
493 return -1;
494 }
495
496 if (!(hint_context = ast_context_find_or_create(NULL, NULL, context, BASE_REGISTRAR))) {
497 ast_log(LOG_ERROR, "Unable to find or create hint context '%s'\n", context);
498 if (ast_unlock_contexts()) {
499 ast_assert(0);
500 }
501 return -1;
502 }
503
504 /* Transfer the all-contexts lock to the specific context */
505 if (ast_wrlock_context(hint_context)) {
507 ast_log(LOG_ERROR, "failed to obtain write lock on context\n");
508 return -1;
509 }
511
512 if (add_extension(hint_context, exten, PRIORITY_HINT, hint_device)) {
513 ast_log(LOG_ERROR, "Failed to add hint '%s@%s' to the PBX.\n",
514 exten, context);
515 }
516
517 if (!ast_strlen_zero(application)) {
518 if (add_extension(hint_context, exten, 1, application)) {
519 ast_log(LOG_ERROR, "Failed to add hint '%s@%s' to the PBX.\n",
520 exten, context);
521 }
522 } else {
523 ast_context_remove_extension2(hint_context, exten, 1, BASE_REGISTRAR, 1);
524 }
525
526 ast_unlock_context(hint_context);
527
528 return 0;
529}
#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
#define LOG_ERROR
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8463
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8481
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:6149
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8491
#define PRIORITY_HINT
Definition: pbx.h:54
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8473
static int add_extension(struct ast_context *context, const char *exten, int priority, const char *application)
ast_context: An extension context
Definition: pbx.c:284
#define ast_assert(a)
Definition: utils.h:739

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, voicemailpwcheck::context, 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 1339 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 289 of file res_pjsip_config_wizard.c.

293 { \
294 ast_config_destroy(otw->last_config); \
295 ast_free(otw); \
296})
297
298const 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 331 of file res_pjsip_config_wizard.c.

333{
335
336 if (!obj) {
337 ast_log(LOG_ERROR, "Unable to allocate an object of type '%s' with id '%s'.\n", type, id);
338 return NULL;
339 }
340
341 if (ast_sorcery_objectset_apply(sorcery, obj, vars)) {
342 ast_log(LOG_ERROR, "Unable to apply object type '%s' with id '%s'. Check preceeding errors.\n", type, id);
343 ao2_ref(obj, -1);
344 return NULL;
345 }
346
347 return obj;
348}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static const char type[]
Definition: chan_ooh323.c:109
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:1744
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:1632
Structure for internal sorcery object information.
Definition: sorcery.c:127

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 825 of file res_pjsip_config_wizard.c.

826{
827 struct object_type_wizard *otw = arg;
828
829 if (!strcmp(otw->object_type, "endpoint")) {
830 const char *context = ast_sorcery_object_get_extended(obj, "hint_context");
831 const char *exten = ast_sorcery_object_get_extended(obj, "hint_exten");
832 if (!ast_strlen_zero(context) && !ast_strlen_zero(exten)) {
833 delete_extens(context, exten);
834 }
835 }
836
837 otw->wizard->delete(otw->sorcery, otw->wizard_data, obj);
838
839 return CMP_MATCH;
840}
@ 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:2335
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, voicemailpwcheck::context, 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 405 of file res_pjsip_config_wizard.c.

406{
407 struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
408
409 if (pbx_find_extension(NULL, NULL, &find_info, context, exten, PRIORITY_HINT, NULL, NULL, E_MATCH)) {
411 }
412
413 if (pbx_find_extension(NULL, NULL, &find_info, context, exten, 1, NULL, NULL, E_MATCH)) {
415 }
416
417 return 0;
418}
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4948

References ast_context_remove_extension(), BASE_REGISTRAR, voicemailpwcheck::context, 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 313 of file res_pjsip_config_wizard.c.

314{
315 int idx;
316
317 AST_VECTOR_RW_RDLOCK(&object_type_wizards);
318 for(idx = 0; idx < AST_VECTOR_SIZE(&object_type_wizards); idx++) {
319 struct object_type_wizard *otw = AST_VECTOR_GET(&object_type_wizards, idx);
320 if (!strcmp(otw->object_type, object_type)) {
321 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
322 return otw;
323 }
324 }
325 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
326
327 return NULL;
328}
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:897
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:877
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

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 386 of file res_pjsip_config_wizard.c.

387{
388 struct ast_variable *return_vars = NULL;
389 struct ast_variable *v = vars;
390 int plen = strlen(prefix);
391
392 for(; v; v = v->next) {
393 if (ast_begins_with(v->name, prefix) && strlen(v->name) > plen) {
394 if (variable_list_append(&return_vars, v->name + plen, v->value)) {
395 ast_variables_destroy(return_vars);
396 return NULL;
397 }
398 }
399 }
400
401 return return_vars;
402}
static char prefix[MAX_PREFIX]
Definition: http.c:144
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
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
Structure for variables, used for configurations and for channel variables.
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 601 of file res_pjsip_config_wizard.c.

603{
604 struct ast_variable *wizvars = ast_category_first(wiz);
605 struct ast_sorcery_object *obj = NULL;
606 const char *id = ast_category_get_name(wiz);
607 const char *contact_pattern;
608 const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
609 int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
610 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "aor/"), ast_variables_destroy);
611
612 variable_list_append(&vars, "@pjsip_wizard", id);
613
614 if (!ast_strlen_zero(outbound_proxy)) {
615 variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
616 }
617
618 /* If the user explicitly specified an aor/contact, don't use remote hosts. */
619 if (!ast_variable_find_last_in_list(vars, "contact")) {
620 if (!(contact_pattern = ast_variable_find_last_in_list(wizvars, "contact_pattern"))) {
621 contact_pattern = "sip:${REMOTE_HOST}";
622 }
623
624 if (host_count > 0 && !ast_strlen_zero(contact_pattern)) {
625 int host_counter;
626
627 /* ast_str_substitute_variables operate on a varshead list so we have
628 * to create one to hold the REPORT_HOST substitution, do the substitution,
629 * then append the result to the ast_variable list.
630 */
631 for (host_counter = 0; host_counter < host_count; host_counter++) {
632 RAII_VAR(struct ast_str *, new_str, ast_str_create(64), ast_free);
634 struct ast_var_t *var = ast_var_assign("REMOTE_HOST",
635 AST_VECTOR_GET(remote_hosts_vector, host_counter));
636
637 AST_VAR_LIST_INSERT_TAIL(subst_vars, var);
638 ast_str_substitute_variables_varshead(&new_str, 0, subst_vars,
639 contact_pattern);
640
641 variable_list_append_return(&vars, "contact", ast_str_buffer(new_str));
642 }
643 }
644 }
645
646 obj = create_object(sorcery, id, "aor", vars);
647 if (!obj) {
648 return -1;
649 }
650
651 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
652 otw->wizard->create(sorcery, otw->wizard_data, obj);
653 }
654 ao2_ref(obj, -1);
655
656 return 0;
657}
#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.
Definition: main/config.c:1117
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.
Definition: main/config.c:931
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1246
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...
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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:941

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 531 of file res_pjsip_config_wizard.c.

533{
534 struct ast_variable *wizvars = ast_category_first(wiz);
535 struct ast_sorcery_object *obj = NULL;
536 const char *id = ast_category_get_name(wiz);
537 char new_id[strlen(id) + MAX_ID_SUFFIX];
538 char prefix[strlen(direction) + strlen("_auth/") + 1];
539 char *test_variable = NULL;
541
542 snprintf(prefix, sizeof(prefix), "%s_auth/", direction);
543 vars = get_object_variables(wizvars, prefix);
544
545 if (!strcmp(direction, "outbound")) {
546 snprintf(new_id, sizeof(new_id), "%s-oauth", id);
547 test_variable = "sends_auth";
548 } else {
549 snprintf(new_id, sizeof(new_id), "%s-iauth", id);
550 test_variable = "accepts_auth";
551 }
552
553 if (is_variable_true(wizvars, test_variable)) {
554 if (!ast_variable_find_last_in_list(vars, "username")) {
556 "Wizard '%s' must have '%s_auth/username' if it %s.\n", id, direction, test_variable);
557 return -1;
558 }
559 } else {
560 /* Delete auth if sends or accepts is now false. */
561 obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "auth", new_id);
562 if (obj) {
563 otw->wizard->delete(sorcery, otw->wizard_data, obj);
564 ao2_ref(obj, -1);
565 }
566 return 0;
567 }
568
569 variable_list_append_return(&vars, "@pjsip_wizard", id);
570
571 /* If the user set auth_type, don't override it. */
572 if (!ast_variable_find_last_in_list(vars, "auth_type")) {
573 variable_list_append_return(&vars, "auth_type", "userpass");
574 }
575
576 obj = create_object(sorcery, new_id, "auth", vars);
577 if (!obj) {
578 return -1;
579 }
580
581 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
582 otw->wizard->create(sorcery, otw->wizard_data, obj);
583 }
584 ao2_ref(obj, -1);
585
586 return 0;
587}
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 589 of file res_pjsip_config_wizard.c.

591{
592 int rc;
593
594 if ((rc = handle_auth(sorcery, otw, wiz, "outbound"))) {
595 return rc;
596 }
597
598 return handle_auth(sorcery, otw, wiz, "inbound");
599}
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 659 of file res_pjsip_config_wizard.c.

661{
662 struct ast_variable *wizvars = ast_category_first(wiz);
663 struct ast_sorcery_object *obj = NULL;
664 const char *id = ast_category_get_name(wiz);
665 const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
666 const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
667 const char *hint_context = hint_context = ast_variable_find_last_in_list(wizvars, "hint_context");
668 const char *hint_exten = ast_variable_find_last_in_list(wizvars, "hint_exten");
669 const char *hint_application= ast_variable_find_last_in_list(wizvars, "hint_application");
670 char new_id[strlen(id) + MAX_ID_SUFFIX];
671 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "endpoint/"), ast_variables_destroy);
672
673 variable_list_append_return(&vars, "@pjsip_wizard", id);
674 variable_list_append_return(&vars, "aors", id);
675
676 if (!ast_strlen_zero(outbound_proxy)) {
677 variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
678 }
679
680 if (ast_strlen_zero(hint_context)) {
681 hint_context = ast_variable_find_last_in_list(vars, "context");
682 }
683
684 if (ast_strlen_zero(hint_context)) {
685 hint_context = "default";
686 }
687
688 if (!ast_strlen_zero(hint_exten)) {
689 /* These are added so we can find and delete the hints when the endpoint gets deleted */
690 variable_list_append_return(&vars, "@hint_context", hint_context);
691 variable_list_append_return(&vars, "@hint_exten", hint_exten);
692 }
693
694 if (!ast_strlen_zero(transport)) {
695 variable_list_append_return(&vars, "transport", transport);
696 }
697
698 if (is_variable_true(wizvars, "sends_auth")) {
699 snprintf(new_id, sizeof(new_id), "%s-oauth", id);
700 variable_list_append_return(&vars, "outbound_auth", new_id);
701 }
702
703 if (is_variable_true(wizvars, "accepts_auth")) {
704 snprintf(new_id, sizeof(new_id), "%s-iauth", id);
705 variable_list_append_return(&vars, "auth", new_id);
706 }
707
708 obj = create_object(sorcery, id, "endpoint", vars);
709 if (!obj) {
710 return -1;
711 }
712
713 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
714 otw->wizard->create(sorcery, otw->wizard_data, obj);
715 }
716 ao2_ref(obj, -1);
717
718 if (!ast_strlen_zero(hint_exten)) {
719 if (is_variable_true(wizvars, "has_hint")) {
720 add_hints(hint_context, hint_exten, hint_application, id);
721 } else {
722 delete_extens(hint_context, hint_exten);
723 }
724 }
725
726 return 0;
727}
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 1218 of file res_pjsip_config_wizard.c.

1219{
1220 struct ast_sorcery *sorcery;
1221 int idx;
1222 FILE *f = NULL;
1223 const char *fn = NULL;
1224
1225 switch (cmd) {
1226 case CLI_INIT:
1227 e->command = "pjsip export config_wizard primitives [to]";
1228 e->usage =
1229 "Usage: pjsip export config_wizard primitives [ to <filename ]\n"
1230 " Export the config_wizard objects as pjsip primitives to\n"
1231 " the console or to <filename>\n";
1232 return NULL;
1233 case CLI_GENERATE:
1234 return NULL;
1235 }
1236
1237 if (a->argc > 5) {
1238 char date[256]="";
1239 time_t t;
1240 fn = a->argv[5];
1241
1242 time(&t);
1243 ast_copy_string(date, ctime(&t), sizeof(date));
1244 f = fopen(fn, "w");
1245 if (!f) {
1246 ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
1247 return CLI_FAILURE;
1248 }
1249
1250 fprintf(f, ";!\n");
1251 fprintf(f, ";! Automatically generated configuration file\n");
1252 fprintf(f, ";! Filename: %s\n", fn);
1253 fprintf(f, ";! Generator: %s\n", "'pjsip export config_wizard primitives'");
1254 fprintf(f, ";! Creation Date: %s", date);
1255 fprintf(f, ";!\n");
1256 }
1257
1259
1260 AST_VECTOR_RW_RDLOCK(&object_type_wizards);
1261 for(idx = 0; idx < AST_VECTOR_SIZE(&object_type_wizards); idx++) {
1262 struct object_type_wizard *otw = AST_VECTOR_GET(&object_type_wizards, idx);
1263 struct ao2_container *container;
1264 struct ao2_iterator i;
1265 void *o;
1266
1268 if (!container) {
1269 continue;
1270 }
1271
1273 while ((o = ao2_iterator_next(&i))) {
1274 struct ast_variable *vars;
1275 struct ast_variable *v;
1276
1278 if (vars && ast_variable_find_in_list(vars, "@pjsip_wizard")) {
1279 if (f) {
1280 fprintf(f, "\n[%s]\ntype = %s\n", ast_sorcery_object_get_id(o), otw->object_type);
1281 } else {
1282 ast_cli(a->fd, "\n[%s]\ntype = %s\n", ast_sorcery_object_get_id(o), otw->object_type);
1283 }
1284 for (v = vars; v; v = v->next) {
1285 if (!ast_strlen_zero(v->value)) {
1286 if (f) {
1287 fprintf(f, "%s = %s\n", v->name, v->value);
1288 } else {
1289 ast_cli(a->fd, "%s = %s\n", v->name, v->value);
1290 }
1291 }
1292 }
1293 }
1295 ao2_ref(o, -1);
1296 }
1299 }
1300 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
1301
1302 if (f) {
1303 fclose(f);
1304 ast_cli(a->fd, "Wrote configuration to %s\n", fn);
1305 }
1306
1307
1308 return CLI_SUCCESS;
1309}
#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.
Definition: main/config.c:919
int errno
struct ao2_container * container
Definition: res_fax.c:501
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
#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:1897
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:230
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 729 of file res_pjsip_config_wizard.c.

731{
732 struct ast_variable *wizvars = ast_category_first(wiz);
733 struct ast_sorcery_object *obj = NULL;
734 const char *id = ast_category_get_name(wiz);
735 char new_id[strlen(id) + MAX_ID_SUFFIX];
736 int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
737 int host_counter;
738 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "identify/"), ast_variables_destroy);
739
740 snprintf(new_id, sizeof(new_id), "%s-identify", id);
741
742 /* If accepting registrations or we're sending line, we don't need an identify. */
743 if (is_variable_true(wizvars, "accepts_registrations")
744 || is_variable_true(wizvars, "sends_line_with_registrations")) {
745 /* If one exists, delete it. */
746 obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "identify", new_id);
747 if (obj) {
748 otw->wizard->delete(sorcery, otw->wizard_data, obj);
749 ao2_ref(obj, -1);
750 }
751 return 0;
752 }
753
754 if (!host_count) {
756 "Wizard '%s' must have 'remote_hosts' if it doesn't accept registrations.\n", id);
757 return -1;
758 }
759
760 variable_list_append_return(&vars, "endpoint", id);
761 variable_list_append_return(&vars, "@pjsip_wizard", id);
762
763 if (!ast_variable_find_last_in_list(vars, "match")) {
764 for (host_counter = 0; host_counter < host_count; host_counter++) {
765 variable_list_append_return(&vars, "match",
766 AST_VECTOR_GET(remote_hosts_vector, host_counter));
767 }
768 }
769
770 obj = create_object(sorcery, new_id, "identify", vars);
771 if (!obj) {
772 return -1;
773 }
774
775 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
776 otw->wizard->create(sorcery, otw->wizard_data, obj);
777 }
778 ao2_ref(obj, -1);
779
780 return 0;
781}

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 783 of file res_pjsip_config_wizard.c.

785{
786 struct ast_variable *wizvars = ast_category_first(wiz);
787 struct ast_sorcery_object *obj = NULL;
788 const char *id = ast_category_get_name(wiz);
789 char new_id[strlen(id) + MAX_ID_SUFFIX];
790 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "phoneprov/"), ast_variables_destroy);
791
792 snprintf(new_id, sizeof(new_id), "%s-phoneprov", id);
793
794 if (!is_variable_true(wizvars, "has_phoneprov")) {
795 obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "phoneprov", new_id);
796 if (obj) {
797 otw->wizard->delete(sorcery, otw->wizard_data, obj);
798 ao2_ref(obj, -1);
799 }
800 return 0;
801 }
802
803 if (!ast_variable_find_last_in_list(wizvars, "phoneprov/MAC")) {
805 "Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n", id);
806 return -1;
807 }
808
809 variable_list_append_return(&vars, "endpoint", id);
810 variable_list_append_return(&vars, "@pjsip_wizard", id);
811
812 obj = create_object(sorcery, new_id, "phoneprov", vars);
813 if (!obj) {
814 return -1;
815 }
816
817 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
818 otw->wizard->create(sorcery, otw->wizard_data, obj);
819 }
820 ao2_ref(obj, -1);
821
822 return 0;
823}

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 842 of file res_pjsip_config_wizard.c.

844{
845 struct ast_variable *search;
846 struct ast_variable *wizvars = ast_category_first(wiz);
847 const char *id = ast_category_get_name(wiz);
848 const char *server_uri_pattern;
849 const char *client_uri_pattern;
850 const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
851 const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
852 const char *username;
853 char new_id[strlen(id) + MAX_ID_SUFFIX];
854 int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
855 int host_counter;
856 RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "registration/"), ast_variables_destroy);
857 RAII_VAR(struct ao2_container *, existing,
859
860 if (!existing) {
861 return -1;
862 }
863
864 /* Find any existing registrations. */
865 search = ast_variable_new("@pjsip_wizard", id, "");
866 if (!search) {
867 return -1;
868 }
869
870 if (!ast_strlen_zero(outbound_proxy)) {
871 variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
872 }
873
874 otw->wizard->retrieve_multiple(sorcery, otw->wizard_data, "registration", existing, search);
875 ast_variables_destroy(search);
876
877 /* If not sending registrations, delete ALL existing registrations for this wizard. */
878 if (!is_variable_true(wizvars, "sends_registrations")) {
879 if (ao2_container_count(existing) > 0) {
881 }
882 return 0;
883 }
884
885 if (!host_count) {
886 ast_log(LOG_ERROR, "Wizard '%s' must have 'remote_hosts' if it sends registrations.\n", id);
887 return -1;
888 }
889
890 variable_list_append_return(&vars, "@pjsip_wizard", id);
891
892 if (!(server_uri_pattern = ast_variable_find_last_in_list(wizvars, "server_uri_pattern"))) {
893 server_uri_pattern = "sip:${REMOTE_HOST}";
894 }
895
896 if (!(client_uri_pattern = ast_variable_find_last_in_list(wizvars, "client_uri_pattern"))) {
897 client_uri_pattern = "sip:${USERNAME}@${REMOTE_HOST}";
898 }
899
900 if (is_variable_true(wizvars, "sends_auth")) {
901 if (!(username = ast_variable_find_last_in_list(wizvars, "outbound_auth/username"))) {
902 ast_log(LOG_ERROR, "Wizard '%s' must have 'outbound_auth/username' if it sends"
903 " authentication.\n", id);
904 return -1;
905 }
906 } else {
907 username = id;
908 }
909
910
911 /* Unlike aor and identify, we need to create a separate registration object
912 * for each remote host.
913 */
914 for (host_counter = 0; host_counter < host_count; host_counter++) {
915 struct ast_var_t *rh = ast_var_assign("REMOTE_HOST",
916 AST_VECTOR_GET(remote_hosts_vector, host_counter));
917 struct ast_var_t *un = ast_var_assign("USERNAME", username);
918 struct ast_sorcery_object *obj;
919 RAII_VAR(struct ast_str *, uri, ast_str_create(64), ast_free);
921 RAII_VAR(struct ast_variable *, registration_vars, vars ? ast_variables_dup(vars) : NULL, ast_variables_destroy);
922
923 AST_VAR_LIST_INSERT_TAIL(subst_vars, rh);
924 AST_VAR_LIST_INSERT_TAIL(subst_vars, un);
925
926 if (!ast_strlen_zero(server_uri_pattern)) {
927 ast_str_substitute_variables_varshead(&uri, 0, subst_vars,
928 server_uri_pattern);
929 variable_list_append_return(&registration_vars, "server_uri", ast_str_buffer(uri));
930 }
931
932 if (!ast_strlen_zero(client_uri_pattern)) {
933 ast_str_reset(uri);
934 ast_str_substitute_variables_varshead(&uri, 0, subst_vars,
935 client_uri_pattern);
936 variable_list_append_return(&registration_vars, "client_uri", ast_str_buffer(uri));
937 }
938
939 if (is_variable_true(wizvars, "sends_auth")) {
940 snprintf(new_id, sizeof(new_id), "%s-oauth", id);
941 variable_list_append_return(&registration_vars, "outbound_auth", new_id);
942 }
943
944 if (!ast_strlen_zero(transport)) {
945 variable_list_append_return(&registration_vars, "transport", transport);
946 }
947
948 if (is_variable_true(wizvars, "sends_line_with_registrations")) {
949 variable_list_append_return(&registration_vars, "line", "yes");
950 variable_list_append_return(&registration_vars, "endpoint", id);
951 }
952
953 snprintf(new_id, sizeof(new_id), "%s-reg-%d", id, host_counter);
954
955 obj = create_object(sorcery, new_id, "registration", registration_vars);
956 if (!obj) {
957 return -1;
958 }
959
960 if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
961 otw->wizard->create(sorcery, otw->wizard_data, obj);
962 }
963 ao2_ref(obj, -1);
964
965 /* Unlink it from the 'existing' container. Any left will be deleted from
966 * sorcery. If it wasn't in the existing container, no harm.
967 */
969 }
970
971 /* If there are any excess registrations, delete them. */
972 if (ao2_container_count(existing) > 0) {
974 }
975
976 return 0;
977}
enum queue_result id
Definition: app_queue.c:1638
@ 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
#define ast_variable_new(name, value, filename)
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:543
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:2464
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 1196 of file res_pjsip_config_wizard.c.

1197{
1198 if (strcmp(name, "res_pjsip")) {
1199 return;
1200 }
1203}
static const char name[]
Definition: format_mp3.c:68
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443
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:520
struct ast_module * self
Definition: module.h:342

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 1208 of file res_pjsip_config_wizard.c.

1209{
1210 if (strcmp(name, "res_pjsip")) {
1211 return;
1212 }
1213
1216}
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
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:537

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 300 of file res_pjsip_config_wizard.c.

301{
302 int i;
303 for (i = 0; haystack[i]; i++) {
304 if (!strcmp(needle, haystack[i])) {
305 return 1;
306 }
307 }
308
309 return 0;
310}

Referenced by object_type_registered_observer(), and wizard_mapped_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 351 of file res_pjsip_config_wizard.c.

352{
354}
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:2199

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 1315 of file res_pjsip_config_wizard.c.

1316{
1317 AST_VECTOR_RW_INIT(&object_type_wizards, 12);
1320
1322}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
static const struct ast_sorcery_global_observer global_observer
static struct ast_cli_entry config_wizard_cli[]
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
Definition: sorcery.c:498
#define ARRAY_LEN(a)
Definition: utils.h:666
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition: vector.h:158

References ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_SUCCESS, ast_sorcery_global_observer_add(), AST_VECTOR_RW_INIT, config_wizard_cli, and global_observer.

◆ 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 1051 of file res_pjsip_config_wizard.c.

1053{
1054 struct ast_category *category = NULL;
1055 struct object_type_wizard *otw = NULL;
1056 char *filename = "pjsip_wizard.conf";
1057 struct ast_flags flags = { 0 };
1058 struct ast_config *cfg;
1059
1060 if (!strstr("auth aor endpoint identify registration phoneprov", object_type)) {
1061 /* Not interested. */
1062 return;
1063 }
1064
1065 otw = find_wizard(object_type);
1066 if (!otw) {
1067 ast_log(LOG_ERROR, "There was no wizard for object type '%s'\n", object_type);
1068 return;
1069 }
1070
1071 if (reloaded && otw->last_config) {
1073 }
1074
1075 cfg = ast_config_load2(filename, object_type, flags);
1076
1077 if (!cfg) {
1078 ast_log(LOG_ERROR, "Unable to load config file '%s'\n", filename);
1079 return;
1080 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
1081 ast_debug(2, "Config file '%s' was unchanged for '%s'.\n", filename, object_type);
1082 return;
1083 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
1084 ast_log(LOG_ERROR, "Contents of config file '%s' are invalid and cannot be parsed\n", filename);
1085 return;
1086 }
1087
1088 while ((category = ast_category_browse_filtered(cfg, NULL, category, "type=^wizard$"))) {
1089 const char *id = ast_category_get_name(category);
1090 struct ast_category *last_cat = NULL;
1091 int changes = 0;
1092
1093 if (otw->last_config) {
1094 last_cat = ast_category_get(otw->last_config, id, "type=^wizard$");
1095 changes = !ast_variable_lists_match(ast_category_first(category), ast_category_first(last_cat), 1);
1096 if (last_cat) {
1097 ast_category_delete(otw->last_config, last_cat);
1098 }
1099 }
1100
1101 if (!last_cat || changes) {
1102 ast_debug(3, "%s: %s(s) for wizard '%s'\n", reloaded ? "Reload" : "Load", object_type, id);
1103 if (wizard_apply_handler(sorcery, otw, category)) {
1104 ast_log(LOG_ERROR, "Unable to create objects for wizard '%s'\n", id);
1105 }
1106 }
1107 }
1108
1109 if (!otw->last_config) {
1110 otw->last_config = cfg;
1111 return;
1112 }
1113
1114 /* Only wizards that weren't in the new config are left in last_config now so we need to delete
1115 * all objects belonging to them.
1116 */
1117 category = NULL;
1118 while ((category = ast_category_browse_filtered(otw->last_config, NULL, category, "type=^wizard$"))) {
1119 const char *id = ast_category_get_name(category);
1120 struct ast_variable *search;
1121 RAII_VAR(struct ao2_container *, existing,
1123
1124 if (!existing) {
1125 ast_log(LOG_ERROR, "Unable to allocate temporary container.\n");
1126 break;
1127 }
1128
1129 search = ast_variable_new("@pjsip_wizard", id, "");
1130 if (!search) {
1131 ast_log(LOG_ERROR, "Unable to allocate memory for vaiable '@pjsip_wizard'.\n");
1132 break;
1133 }
1134 otw->wizard->retrieve_multiple(sorcery, otw->wizard_data, object_type, existing, search);
1135 ast_variables_destroy(search);
1136
1137 if (ao2_container_count(existing) > 0) {
1138 ast_debug(3, "Delete on %s: %d %s(s) for wizard: %s\n",
1139 reloaded ? "Reload" : "Load", ao2_container_count(existing), object_type, id);
1141 delete_existing_cb, otw);
1142 }
1143 }
1144
1146 otw->last_config = cfg;
1147}
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *cat)
Delete a category.
Definition: main/config.c:1567
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
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.
Definition: main/config.c:861
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
Definition: main/config.c:1111
@ CONFIG_FLAG_FILEUNCHANGED
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.
Definition: main/config.c:1424
#define ast_debug(level,...)
Log a DEBUG message.
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:199
unsigned int flags
Definition: utils.h:200
struct ast_config * last_config

References 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, 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 1184 of file res_pjsip_config_wizard.c.

1186{
1187 if (is_one_of(object_type, object_types)) {
1188 ast_sorcery_apply_wizard_mapping(sorcery, object_type, "memory", "pjsip_wizard", 0);
1189 }
1190}
static int is_one_of(const char *needle, const char *haystack[])
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching)
Apply additional object wizard mappings.
Definition: sorcery.h:510

References ast_sorcery_apply_wizard_mapping, is_one_of(), object_type_wizard::object_type, and sorcery.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1324 of file res_pjsip_config_wizard.c.

1325{
1329 AST_VECTOR_RW_FREE(&object_type_wizards);
1330
1331 return 0;
1332}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#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:514
#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:461
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
Definition: vector.h:202

References 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, and OTW_DELETE_CB.

◆ 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 357 of file res_pjsip_config_wizard.c.

358{
359 struct ast_variable *new = ast_variable_new(name, value, "");
360
361 if (!new) {
362 ast_log(LOG_ERROR, "Unable to allocate memory for new variable '%s'.\n", name);
363 return -1;
364 }
365
366 ast_variable_list_append(existing, new);
367
368 return 0;
369}
#define ast_variable_list_append(head, new_var)
int value
Definition: syslog.c:37

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 979 of file res_pjsip_config_wizard.c.

981{
982 struct ast_variable *wizvars = ast_category_first(wiz);
983 struct string_vector remote_hosts_vector;
984 const char *remote_hosts;
985 int rc = -1;
986
987 AST_VECTOR_INIT(&remote_hosts_vector, 16);
988 remote_hosts = ast_variable_find_last_in_list(wizvars, "remote_hosts");
989
990 if (!ast_strlen_zero(remote_hosts)) {
991 char *host;
992 char *hosts = ast_strdupa(remote_hosts);
993
994 while ((host = ast_strsep(&hosts, ',', AST_STRSEP_TRIM))) {
995 host = ast_strdup(host);
996 if (host && AST_VECTOR_APPEND(&remote_hosts_vector, host)) {
997 ast_free(host);
998 }
999 }
1000 }
1001
1002 ast_debug(4, "%s handler starting.\n", otw->object_type);
1003
1004 if (!strcmp(otw->object_type, "auth")) {
1005 rc = handle_auths(sorcery, otw, wiz);
1006 } else if (!strcmp(otw->object_type, "aor")) {
1007 rc = handle_aor(sorcery, otw, wiz, &remote_hosts_vector);
1008 } else if (!strcmp(otw->object_type, "endpoint")) {
1009 rc = handle_endpoint(sorcery, otw, wiz);
1010 } else if (!strcmp(otw->object_type, "identify")) {
1011 rc = handle_identify(sorcery, otw, wiz, &remote_hosts_vector);
1012 } else if (!strcmp(otw->object_type, "phoneprov")) {
1013 rc = handle_phoneprov(sorcery, otw, wiz);
1014 } else if (!strcmp(otw->object_type, "registration")) {
1015 rc = handle_registrations(sorcery, otw, wiz, &remote_hosts_vector);
1016 }
1017
1019 AST_VECTOR_FREE(&remote_hosts_vector);
1020
1021 ast_debug(4, "%s handler complete. rc: %d\n", otw->object_type, rc);
1022
1023 return rc;
1024}
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:1835
A generic char * vector definition.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256

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().

◆ wizard_mapped_observer()

static void wizard_mapped_observer ( const char *  name,
struct ast_sorcery sorcery,
const char *  object_type,
struct ast_sorcery_wizard wizard,
const char *  wizard_args,
void *  wizard_data 
)
static

When each wizard is mapped, save it off to the vector.

Definition at line 1150 of file res_pjsip_config_wizard.c.

1153{
1154 struct object_type_wizard *otw;
1155
1156 if (!is_one_of(object_type, object_types)) {
1157 /* Not interested. */
1158 return;
1159 }
1160
1161 /* We're only interested in memory wizards with the pjsip_wizard tag. */
1162 if (wizard_args && !strcmp(wizard_args, "pjsip_wizard")) {
1163 otw = ast_malloc(sizeof(*otw) + strlen(object_type) + 1);
1164 if (!otw) {
1165 return;
1166 }
1167
1168 otw->sorcery = sorcery;
1169 otw->wizard = wizard;
1170 otw->wizard_data = wizard_data;
1171 otw->last_config = NULL;
1172 strcpy(otw->object_type, object_type); /* Safe */
1173 AST_VECTOR_RW_WRLOCK(&object_type_wizards);
1174 if (AST_VECTOR_APPEND(&object_type_wizards, otw)) {
1175 ast_free(otw);
1176 } else {
1177 ast_debug(1, "Wizard mapped for object_type '%s'\n", object_type);
1178 }
1179 AST_VECTOR_RW_UNLOCK(&object_type_wizards);
1180 }
1181}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:887

References ast_debug, ast_free, ast_malloc, AST_VECTOR_APPEND, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, is_one_of(), object_type_wizard::last_config, NULL, object_type_wizard::object_type, object_type_wizard::sorcery, sorcery, object_type_wizard::wizard, and object_type_wizard::wizard_data.

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 = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
static

Definition at line 1339 of file res_pjsip_config_wizard.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1339 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 1311 of file res_pjsip_config_wizard.c.

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 1039 of file res_pjsip_config_wizard.c.

Referenced by load_module(), and unload_module().

◆ observer

Initial value:
= {
.wizard_mapped = wizard_mapped_observer,
.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.
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 void wizard_mapped_observer(const char *name, struct ast_sorcery *sorcery, const char *object_type, struct ast_sorcery_wizard *wizard, const char *wizard_args, void *wizard_data)
When each wizard is mapped, save it off to the vector.

Definition at line 1044 of file res_pjsip_config_wizard.c.

Referenced by ast_mwi_add_observer(), ast_mwi_remove_observer(), ast_sorcery_observer_add(), instance_created_observer(), instance_destroying_observer(), 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().