Asterisk - The Open Source Telephony Project  18.5.0
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...
 

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)
 
 AST_VECTOR (string_vector, char *)
 A generic char * vector definition. More...
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 278 of file res_pjsip_config_wizard.c.

Referenced by add_extension(), add_hints(), and delete_extens().

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

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

◆ 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); \
})

Referenced by unload_module().

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

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

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1351 of file res_pjsip_config_wizard.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

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, NULL, paren, pbx_find_extension(), and pbx_find_info::stacklen.

Referenced by add_hints().

424 {
425  struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
426  struct ast_exten *existing_exten;
427  char *data = NULL;
428  char *app = NULL;
429  void *free_ptr = NULL;
430  char *paren;
431  const char *context_name;
432 
433  if (!context || ast_strlen_zero(exten) || ast_strlen_zero(application)) {
434  return -1;
435  }
436 
437  /* The incoming application has to be split into the app name and the
438  * arguments (data). The app name can be any storage type as add_extension
439  * copies it into its own buffer. Data however, needs to be dynamically
440  * allocated and a free function provided.
441  */
442 
443  paren = strchr(application, '(');
444  if (!paren) {
445  app = (char *)application;
446  } else {
447  app = ast_strdupa(application);
448  app[paren - application] = '\0';
449  data = ast_strdup(paren + 1);
450  if (!data) {
451  return -1;
452  }
453  data[strlen(data) - 1] = '\0';
454  free_ptr = ast_free_ptr;
455  if (ast_strlen_zero(app) || ast_strlen_zero(data)) {
456  ast_free(data);
457  return -1;
458  }
459  }
460 
461  /* Don't disturb existing, exact-match, entries. */
462  context_name = ast_get_context_name(context);
463  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, context_name, exten,
464  priority, NULL, NULL, E_MATCH))) {
465  const char *existing_app = ast_get_extension_app(existing_exten);
466  const char *existing_data = ast_get_extension_app_data(existing_exten);
467  if (!strcmp(existing_app, app)
468  && !strcmp(existing_data ? existing_data : "", data ? data : "")) {
469  ast_free(data);
470  return 0;
471  }
472 
474  }
475 
476  if (ast_add_extension2_nolock(context, 0, exten, priority, NULL, NULL,
477  app, data, free_ptr, BASE_REGISTRAR, NULL, 0)) {
478  return -1;
479  }
480 
481  return 0;
482 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:237
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
#define BASE_REGISTRAR
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:8596
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:8601
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int priority
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
static const char context_name[]
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_free(a)
Definition: astmm.h:182
int stacklen
Definition: extconf.h:238
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:4982
void * data
Definition: pbx.c:248
static const char app[]
Definition: app_mysql.c:62
#define paren
Definition: ael_lex.c:973
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
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:7308

◆ add_hints()

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

Definition at line 484 of file res_pjsip_config_wizard.c.

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

485 {
486  struct ast_context *hint_context;
487  char *hint_device;
488 
489  hint_device = ast_alloca(strlen("PJSIP/") + strlen(id) + 1);
490  sprintf(hint_device, "PJSIP/%s", id);
491 
492  /* We need the contexts list locked to safely be able to both read and lock the specific context within */
493  if (ast_wrlock_contexts()) {
494  ast_log(LOG_ERROR, "Failed to lock the contexts list.\n");
495  return -1;
496  }
497 
498  if (!(hint_context = ast_context_find_or_create(NULL, NULL, context, BASE_REGISTRAR))) {
499  ast_log(LOG_ERROR, "Unable to find or create hint context '%s'\n", context);
500  if (ast_unlock_contexts()) {
501  ast_assert(0);
502  }
503  return -1;
504  }
505 
506  /* Transfer the all-contexts lock to the specific context */
507  if (ast_wrlock_context(hint_context)) {
509  ast_log(LOG_ERROR, "failed to obtain write lock on context\n");
510  return -1;
511  }
513 
514  if (add_extension(hint_context, exten, PRIORITY_HINT, hint_device)) {
515  ast_log(LOG_ERROR, "Failed to add hint '%s@%s' to the PBX.\n",
516  exten, context);
517  }
518 
519  if (!ast_strlen_zero(application)) {
520  if (add_extension(hint_context, exten, 1, application)) {
521  ast_log(LOG_ERROR, "Failed to add hint '%s@%s' to the PBX.\n",
522  exten, context);
523  }
524  } else {
525  ast_context_remove_extension2(hint_context, exten, 1, BASE_REGISTRAR, 1);
526  }
527 
528  ast_unlock_context(hint_context);
529 
530  return 0;
531 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define BASE_REGISTRAR
#define ast_assert(a)
Definition: utils.h:695
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8502
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define PRIORITY_HINT
Definition: pbx.h:54
static int add_extension(struct ast_context *context, const char *exten, int priority, const char *application)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8520
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:4982
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
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:6198
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1351 of file res_pjsip_config_wizard.c.

◆ AST_VECTOR()

AST_VECTOR ( string_vector  ,
char *   
)

A generic char * vector definition.

◆ AST_VECTOR_RW()

static AST_VECTOR_RW (   object_type_wizards,
struct object_type_wizard  
)
static

Definition at line 291 of file res_pjsip_config_wizard.c.

References NULL.

295  { \
296  ast_config_destroy(otw->last_config); \
297  ast_free(otw); \
298 })
299 
300 const static char *object_types[] = {"phoneprov", "registration", "identify", "endpoint", "aor", "auth", NULL};
#define NULL
Definition: resample.c:96

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

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

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

335 {
336  struct ast_sorcery_object *obj = ast_sorcery_alloc(sorcery, type, id);
337 
338  if (!obj) {
339  ast_log(LOG_ERROR, "Unable to allocate an object of type '%s' with id '%s'.\n", type, id);
340  return NULL;
341  }
342 
343  if (ast_sorcery_objectset_apply(sorcery, obj, vars)) {
344  ast_log(LOG_ERROR, "Unable to apply object type '%s' with id '%s'. Check preceeding errors.\n", type, id);
345  ao2_ref(obj, -1);
346  return NULL;
347  }
348 
349  return obj;
350 }
static const char type[]
Definition: chan_ooh323.c:109
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
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure for internal sorcery object information.
Definition: sorcery.c:127
#define LOG_ERROR
Definition: logger.h:285
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744

◆ delete_existing_cb()

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

Definition at line 837 of file res_pjsip_config_wizard.c.

References ast_sorcery_object_get_extended(), ast_strlen_zero, CMP_MATCH, context, ast_sorcery_wizard::delete, delete_extens(), exten, 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().

838 {
839  struct object_type_wizard *otw = arg;
840 
841  if (!strcmp(otw->object_type, "endpoint")) {
842  const char *context = ast_sorcery_object_get_extended(obj, "hint_context");
843  const char *exten = ast_sorcery_object_get_extended(obj, "hint_exten");
844  if (!ast_strlen_zero(context) && !ast_strlen_zero(exten)) {
845  delete_extens(context, exten);
846  }
847  }
848 
849  otw->wizard->delete(otw->sorcery, otw->wizard_data, obj);
850 
851  return CMP_MATCH;
852 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
static int delete_extens(const char *context, const char *exten)
Keeps track of the sorcery wizard and last config for each object type.
#define ast_strlen_zero(foo)
Definition: strings.h:52
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
Definition: sorcery.h:319
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:2330
struct ast_sorcery_wizard * wizard
struct ast_sorcery * sorcery
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ delete_extens()

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

Definition at line 407 of file res_pjsip_config_wizard.c.

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

408 {
409  struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
410 
413  }
414 
415  if (pbx_find_extension(NULL, NULL, &find_info, context, exten, 1, NULL, NULL, E_MATCH)) {
417  }
418 
419  return 0;
420 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define BASE_REGISTRAR
#define NULL
Definition: resample.c:96
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4952
#define PRIORITY_HINT
Definition: pbx.h:54
int stacklen
Definition: extconf.h:238
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
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

◆ find_wizard()

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

Finds the otw for the object type.

Definition at line 315 of file res_pjsip_config_wizard.c.

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

316 {
317  int idx;
318 
319  AST_VECTOR_RW_RDLOCK(&object_type_wizards);
320  for(idx = 0; idx < AST_VECTOR_SIZE(&object_type_wizards); idx++) {
321  struct object_type_wizard *otw = AST_VECTOR_GET(&object_type_wizards, idx);
322  if (!strcmp(otw->object_type, object_type)) {
323  AST_VECTOR_RW_UNLOCK(&object_type_wizards);
324  return otw;
325  }
326  }
327  AST_VECTOR_RW_UNLOCK(&object_type_wizards);
328 
329  return NULL;
330 }
Keeps track of the sorcery wizard and last config for each object type.
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

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

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

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

389 {
390  struct ast_variable *return_vars = NULL;
391  struct ast_variable *v = vars;
392  int plen = strlen(prefix);
393 
394  for(; v; v = v->next) {
395  if (ast_begins_with(v->name, prefix) && strlen(v->name) > plen) {
396  if (variable_list_append(&return_vars, v->name + plen, v->value)) {
397  ast_variables_destroy(return_vars);
398  return NULL;
399  }
400  }
401  }
402 
403  return return_vars;
404 }
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94
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 char prefix[MAX_PREFIX]
Definition: http.c:141

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

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

605 {
606  struct ast_variable *wizvars = ast_category_first(wiz);
607  struct ast_sorcery_object *obj = NULL;
608  const char *id = ast_category_get_name(wiz);
609  const char *contact_pattern;
610  const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
611  int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
612  RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "aor/"), ast_variables_destroy);
613 
614  variable_list_append(&vars, "@pjsip_wizard", id);
615 
616  if (!ast_strlen_zero(outbound_proxy)) {
617  variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
618  }
619 
620  /* If the user explicitly specified an aor/contact, don't use remote hosts. */
621  if (!ast_variable_find_last_in_list(vars, "contact")) {
622  if (!(contact_pattern = ast_variable_find_last_in_list(wizvars, "contact_pattern"))) {
623  contact_pattern = "sip:${REMOTE_HOST}";
624  }
625 
626  if (host_count > 0 && !ast_strlen_zero(contact_pattern)) {
627  int host_counter;
628 
629  /* ast_str_substitute_variables operate on a varshead list so we have
630  * to create one to hold the REPORT_HOST substitution, do the substitution,
631  * then append the result to the ast_variable list.
632  */
633  for (host_counter = 0; host_counter < host_count; host_counter++) {
634  RAII_VAR(struct ast_str *, new_str, ast_str_create(64), ast_free);
635  RAII_VAR(struct varshead *, subst_vars, ast_var_list_create(), ast_var_list_destroy);
636  struct ast_var_t *var = ast_var_assign("REMOTE_HOST",
637  AST_VECTOR_GET(remote_hosts_vector, host_counter));
638 
639  AST_VAR_LIST_INSERT_TAIL(subst_vars, var);
640  ast_str_substitute_variables_varshead(&new_str, 0, subst_vars,
641  contact_pattern);
642 
643  variable_list_append_return(&vars, "contact", ast_str_buffer(new_str));
644  }
645  }
646  }
647 
648  obj = create_object(sorcery, id, "aor", vars);
649  if (!obj) {
650  return -1;
651  }
652 
653  if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
654  otw->wizard->create(sorcery, otw->wizard_data, obj);
655  }
656  ao2_ref(obj, -1);
657 
658  return 0;
659 }
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#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.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
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:842
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
Structure for internal sorcery object information.
Definition: sorcery.c:127
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
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&#39;re suitable for objectset_appl...
#define ast_free(a)
Definition: astmm.h:182
#define ast_var_assign(name, value)
Definition: chanvars.h:40
struct ast_sorcery_wizard * wizard
struct varshead * ast_var_list_create(void)
Definition: chanvars.c:97
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
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.
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_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

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, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by handle_auths().

535 {
536  struct ast_variable *wizvars = ast_category_first(wiz);
537  struct ast_sorcery_object *obj = NULL;
538  const char *id = ast_category_get_name(wiz);
539  char new_id[strlen(id) + MAX_ID_SUFFIX];
540  char prefix[strlen(direction) + strlen("_auth/") + 1];
541  char *test_variable = NULL;
543 
544  snprintf(prefix, sizeof(prefix), "%s_auth/", direction);
545  vars = get_object_variables(wizvars, prefix);
546 
547  if (!strcmp(direction, "outbound")) {
548  snprintf(new_id, sizeof(new_id), "%s-oauth", id);
549  test_variable = "sends_auth";
550  } else {
551  snprintf(new_id, sizeof(new_id), "%s-iauth", id);
552  test_variable = "accepts_auth";
553  }
554 
555  if (is_variable_true(wizvars, test_variable)) {
556  if (!ast_variable_find_last_in_list(vars, "username")) {
558  "Wizard '%s' must have '%s_auth/username' if it %s.\n", id, direction, test_variable);
559  return -1;
560  }
561  } else {
562  /* Delete auth if sends or accepts is now false. */
563  obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "auth", new_id);
564  if (obj) {
565  otw->wizard->delete(sorcery, otw->wizard_data, obj);
566  ao2_ref(obj, -1);
567  }
568  return 0;
569  }
570 
571  variable_list_append_return(&vars, "@pjsip_wizard", id);
572 
573  /* If the user set auth_type, don't override it. */
574  if (!ast_variable_find_last_in_list(vars, "auth_type")) {
575  variable_list_append_return(&vars, "auth_type", "userpass");
576  }
577 
578  obj = create_object(sorcery, new_id, "auth", vars);
579  if (!obj) {
580  return -1;
581  }
582 
583  if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
584  otw->wizard->create(sorcery, otw->wizard_data, obj);
585  }
586  ao2_ref(obj, -1);
587 
588  return 0;
589 }
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#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.
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
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:842
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
Definition: sorcery.h:319
#define ast_log
Definition: astobj2.c:42
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
Structure for internal sorcery object information.
Definition: sorcery.c:127
#define LOG_ERROR
Definition: logger.h:285
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&#39;re suitable for objectset_appl...
struct ast_sorcery_wizard * wizard
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
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
direction
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ handle_auths()

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

Definition at line 591 of file res_pjsip_config_wizard.c.

References handle_auth().

Referenced by wizard_apply_handler().

593 {
594  int rc;
595 
596  if ((rc = handle_auth(sorcery, otw, wiz, "outbound"))) {
597  return rc;
598  }
599 
600  return handle_auth(sorcery, otw, wiz, "inbound");
601 }
static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, char *direction)

◆ handle_endpoint()

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

Definition at line 661 of file res_pjsip_config_wizard.c.

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, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

663 {
664  struct ast_variable *wizvars = ast_category_first(wiz);
665  struct ast_sorcery_object *obj = NULL;
666  const char *id = ast_category_get_name(wiz);
667  const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
668  const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
669  const char *hint_context = hint_context = ast_variable_find_last_in_list(wizvars, "hint_context");
670  const char *hint_exten = ast_variable_find_last_in_list(wizvars, "hint_exten");
671  const char *hint_application= ast_variable_find_last_in_list(wizvars, "hint_application");
672  char new_id[strlen(id) + MAX_ID_SUFFIX];
673  RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "endpoint/"), ast_variables_destroy);
674 
675  variable_list_append_return(&vars, "@pjsip_wizard", id);
676  variable_list_append_return(&vars, "aors", id);
677 
678  if (!ast_strlen_zero(outbound_proxy)) {
679  variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
680  }
681 
682  if (ast_strlen_zero(hint_context)) {
683  hint_context = ast_variable_find_last_in_list(vars, "context");
684  }
685 
686  if (ast_strlen_zero(hint_context)) {
687  hint_context = "default";
688  }
689 
690  if (!ast_strlen_zero(hint_exten)) {
691  /* These are added so we can find and delete the hints when the endpoint gets deleted */
692  variable_list_append_return(&vars, "@hint_context", hint_context);
693  variable_list_append_return(&vars, "@hint_exten", hint_exten);
694  }
695 
696  if (!ast_strlen_zero(transport)) {
697  variable_list_append_return(&vars, "transport", transport);
698  }
699 
700  if (is_variable_true(wizvars, "sends_auth")) {
701  snprintf(new_id, sizeof(new_id), "%s-oauth", id);
702  variable_list_append_return(&vars, "outbound_auth", new_id);
703  }
704 
705  if (is_variable_true(wizvars, "accepts_auth")) {
706  snprintf(new_id, sizeof(new_id), "%s-iauth", id);
707  variable_list_append_return(&vars, "auth", new_id);
708  }
709 
710  obj = create_object(sorcery, id, "endpoint", vars);
711  if (!obj) {
712  return -1;
713  }
714 
715  if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
716  otw->wizard->create(sorcery, otw->wizard_data, obj);
717  }
718  ao2_ref(obj, -1);
719 
720  if (!ast_strlen_zero(hint_exten)) {
721  if (is_variable_true(wizvars, "has_hint")) {
722  add_hints(hint_context, hint_exten, hint_application, id);
723  } else {
724  delete_extens(hint_context, hint_exten);
725  }
726  }
727 
728  return 0;
729 }
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316
static int delete_extens(const char *context, const char *exten)
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#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 int add_hints(const char *context, const char *exten, const char *application, const char *id)
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
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:842
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
Structure for internal sorcery object information.
Definition: sorcery.c:127
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&#39;re suitable for objectset_appl...
struct ast_sorcery_wizard * wizard
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028

◆ handle_export_primitives()

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

Definition at line 1230 of file res_pjsip_config_wizard.c.

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, 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, ast_cli_args::fd, LOG_ERROR, ast_variable::name, ast_variable::next, NULL, object_type_wizard::object_type, object_type_wizard::sorcery, ast_cli_entry::usage, and ast_variable::value.

1231 {
1232  struct ast_sorcery *sorcery;
1233  int idx;
1234  FILE *f = NULL;
1235  const char *fn = NULL;
1236 
1237  switch (cmd) {
1238  case CLI_INIT:
1239  e->command = "pjsip export config_wizard primitives [to]";
1240  e->usage =
1241  "Usage: pjsip export config_wizard primitives [ to <filename ]\n"
1242  " Export the config_wizard objects as pjsip primitives to\n"
1243  " the console or to <filename>\n";
1244  return NULL;
1245  case CLI_GENERATE:
1246  return NULL;
1247  }
1248 
1249  if (a->argc > 5) {
1250  char date[256]="";
1251  time_t t;
1252  fn = a->argv[5];
1253 
1254  time(&t);
1255  ast_copy_string(date, ctime(&t), sizeof(date));
1256  f = fopen(fn, "w");
1257  if (!f) {
1258  ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
1259  return CLI_FAILURE;
1260  }
1261 
1262  fprintf(f, ";!\n");
1263  fprintf(f, ";! Automatically generated configuration file\n");
1264  fprintf(f, ";! Filename: %s\n", fn);
1265  fprintf(f, ";! Generator: %s\n", "'pjsip export config_wizard primitives'");
1266  fprintf(f, ";! Creation Date: %s", date);
1267  fprintf(f, ";!\n");
1268  }
1269 
1270  sorcery = ast_sip_get_sorcery();
1271 
1272  AST_VECTOR_RW_RDLOCK(&object_type_wizards);
1273  for(idx = 0; idx < AST_VECTOR_SIZE(&object_type_wizards); idx++) {
1274  struct object_type_wizard *otw = AST_VECTOR_GET(&object_type_wizards, idx);
1275  struct ao2_container *container;
1276  struct ao2_iterator i;
1277  void *o;
1278 
1280  if (!container) {
1281  continue;
1282  }
1283 
1284  i = ao2_iterator_init(container, 0);
1285  while ((o = ao2_iterator_next(&i))) {
1286  struct ast_variable *vars;
1287  struct ast_variable *v;
1288 
1289  vars = ast_sorcery_objectset_create(sorcery, o);
1290  if (vars && ast_variable_find_in_list(vars, "@pjsip_wizard")) {
1291  if (f) {
1292  fprintf(f, "\n[%s]\ntype = %s\n", ast_sorcery_object_get_id(o), otw->object_type);
1293  } else {
1294  ast_cli(a->fd, "\n[%s]\ntype = %s\n", ast_sorcery_object_get_id(o), otw->object_type);
1295  }
1296  for (v = vars; v; v = v->next) {
1297  if (!ast_strlen_zero(v->value)) {
1298  if (f) {
1299  fprintf(f, "%s = %s\n", v->name, v->value);
1300  } else {
1301  ast_cli(a->fd, "%s = %s\n", v->name, v->value);
1302  }
1303  }
1304  }
1305  }
1306  ast_variables_destroy(vars);
1307  ao2_ref(o, -1);
1308  }
1310  ao2_cleanup(container);
1311  }
1312  AST_VECTOR_RW_UNLOCK(&object_type_wizards);
1313 
1314  if (f) {
1315  fclose(f);
1316  ast_cli(a->fd, "Wrote configuration to %s\n", fn);
1317  }
1318 
1319 
1320  return CLI_SUCCESS;
1321 }
struct ast_variable * next
Keeps track of the sorcery wizard and last config for each object type.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
const int argc
Definition: cli.h:160
Structure for variables, used for configurations and for channel variables.
Definition: cli.h:152
Full structure for sorcery.
Definition: sorcery.c:230
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
Return all matching objects.
Definition: sorcery.h:120
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
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:830
struct ao2_container * container
Definition: res_fax.c:502
const char *const * argv
Definition: cli.h:161
#define LOG_ERROR
Definition: logger.h:285
int errno
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1136
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
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
#define CLI_SUCCESS
Definition: cli.h:44
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static struct ast_sorcery * sorcery
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

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

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(), host, is_variable_true(), LOG_ERROR, MAX_ID_SUFFIX, NULL, RAII_VAR, ast_sorcery_wizard::retrieve_id, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

733 {
734  struct ast_variable *wizvars = ast_category_first(wiz);
735  struct ast_sorcery_object *obj = NULL;
736  const char *id = ast_category_get_name(wiz);
737  char new_id[strlen(id) + MAX_ID_SUFFIX];
738  int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
739  int host_counter;
740  RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "identify/"), ast_variables_destroy);
741 
742  snprintf(new_id, sizeof(new_id), "%s-identify", id);
743 
744  /* If accepting registrations or we're sending line, we don't need an identify. */
745  if (is_variable_true(wizvars, "accepts_registrations")
746  || is_variable_true(wizvars, "sends_line_with_registrations")) {
747  /* If one exists, delete it. */
748  obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "identify", new_id);
749  if (obj) {
750  otw->wizard->delete(sorcery, otw->wizard_data, obj);
751  ao2_ref(obj, -1);
752  }
753  return 0;
754  }
755 
756  if (!host_count) {
758  "Wizard '%s' must have 'remote_hosts' if it doesn't accept registrations.\n", id);
759  return -1;
760  }
761 
762  variable_list_append_return(&vars, "endpoint", id);
763  variable_list_append_return(&vars, "@pjsip_wizard", id);
764 
765  if (!ast_variable_find_last_in_list(vars, "match")) {
766  for (host_counter = 0; host_counter < host_count; host_counter++) {
767  char *rhost = AST_VECTOR_GET(remote_hosts_vector, host_counter);
768  char host[strlen(rhost) + 1];
769  char *colon;
770 
771  /* If there's a :port specified, we have to remove it. */
772  strcpy(host, rhost); /* Safe */
773  colon = strchr(host, ':');
774  if (colon) {
775  *colon = '\0';
776  }
777 
778  variable_list_append_return(&vars, "match", host);
779  }
780  }
781 
782  obj = create_object(sorcery, new_id, "identify", vars);
783  if (!obj) {
784  return -1;
785  }
786 
787  if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
788  otw->wizard->create(sorcery, otw->wizard_data, obj);
789  }
790  ao2_ref(obj, -1);
791 
792  return 0;
793 }
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#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.
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
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:842
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
Definition: sorcery.h:319
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
Structure for internal sorcery object information.
Definition: sorcery.c:127
#define LOG_ERROR
Definition: logger.h:285
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&#39;re suitable for objectset_appl...
struct ast_sorcery_wizard * wizard
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
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
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028

◆ handle_phoneprov()

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

Definition at line 795 of file res_pjsip_config_wizard.c.

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, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

797 {
798  struct ast_variable *wizvars = ast_category_first(wiz);
799  struct ast_sorcery_object *obj = NULL;
800  const char *id = ast_category_get_name(wiz);
801  char new_id[strlen(id) + MAX_ID_SUFFIX];
802  RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "phoneprov/"), ast_variables_destroy);
803 
804  snprintf(new_id, sizeof(new_id), "%s-phoneprov", id);
805 
806  if (!is_variable_true(wizvars, "has_phoneprov")) {
807  obj = otw->wizard->retrieve_id(sorcery, otw->wizard_data, "phoneprov", new_id);
808  if (obj) {
809  otw->wizard->delete(sorcery, otw->wizard_data, obj);
810  ao2_ref(obj, -1);
811  }
812  return 0;
813  }
814 
815  if (!ast_variable_find_last_in_list(wizvars, "phoneprov/MAC")) {
817  "Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n", id);
818  return -1;
819  }
820 
821  variable_list_append_return(&vars, "endpoint", id);
822  variable_list_append_return(&vars, "@pjsip_wizard", id);
823 
824  obj = create_object(sorcery, new_id, "phoneprov", vars);
825  if (!obj) {
826  return -1;
827  }
828 
829  if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
830  otw->wizard->create(sorcery, otw->wizard_data, obj);
831  }
832  ao2_ref(obj, -1);
833 
834  return 0;
835 }
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#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.
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
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:842
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
Definition: sorcery.h:319
#define ast_log
Definition: astobj2.c:42
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
Structure for internal sorcery object information.
Definition: sorcery.c:127
#define LOG_ERROR
Definition: logger.h:285
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&#39;re suitable for objectset_appl...
struct ast_sorcery_wizard * wizard
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
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028

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

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, ast_sorcery_wizard::update, variable_list_append_return, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

856 {
857  struct ast_variable *search;
858  struct ast_variable *wizvars = ast_category_first(wiz);
859  const char *id = ast_category_get_name(wiz);
860  const char *server_uri_pattern;
861  const char *client_uri_pattern;
862  const char *outbound_proxy = ast_variable_find_last_in_list(wizvars, "outbound_proxy");
863  const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
864  const char *username;
865  char new_id[strlen(id) + MAX_ID_SUFFIX];
866  int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
867  int host_counter;
868  RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "registration/"), ast_variables_destroy);
869  RAII_VAR(struct ao2_container *, existing,
871 
872  if (!existing) {
873  return -1;
874  }
875 
876  /* Find any existing registrations. */
877  search = ast_variable_new("@pjsip_wizard", id, "");
878  if (!search) {
879  return -1;
880  }
881 
882  if (!ast_strlen_zero(outbound_proxy)) {
883  variable_list_append_return(&vars, "outbound_proxy", outbound_proxy);
884  }
885 
886  otw->wizard->retrieve_multiple(sorcery, otw->wizard_data, "registration", existing, search);
887  ast_variables_destroy(search);
888 
889  /* If not sending registrations, delete ALL existing registrations for this wizard. */
890  if (!is_variable_true(wizvars, "sends_registrations")) {
891  if (ao2_container_count(existing) > 0) {
893  }
894  return 0;
895  }
896 
897  if (!host_count) {
898  ast_log(LOG_ERROR, "Wizard '%s' must have 'remote_hosts' if it sends registrations.\n", id);
899  return -1;
900  }
901 
902  variable_list_append_return(&vars, "@pjsip_wizard", id);
903 
904  if (!(server_uri_pattern = ast_variable_find_last_in_list(wizvars, "server_uri_pattern"))) {
905  server_uri_pattern = "sip:${REMOTE_HOST}";
906  }
907 
908  if (!(client_uri_pattern = ast_variable_find_last_in_list(wizvars, "client_uri_pattern"))) {
909  client_uri_pattern = "sip:${USERNAME}@${REMOTE_HOST}";
910  }
911 
912  if (is_variable_true(wizvars, "sends_auth")) {
913  if (!(username = ast_variable_find_last_in_list(wizvars, "outbound_auth/username"))) {
914  ast_log(LOG_ERROR, "Wizard '%s' must have 'outbound_auth/username' if it sends"
915  " authentication.\n", id);
916  return -1;
917  }
918  } else {
919  username = id;
920  }
921 
922 
923  /* Unlike aor and identify, we need to create a separate registration object
924  * for each remote host.
925  */
926  for (host_counter = 0; host_counter < host_count; host_counter++) {
927  struct ast_var_t *rh = ast_var_assign("REMOTE_HOST",
928  AST_VECTOR_GET(remote_hosts_vector, host_counter));
929  struct ast_var_t *un = ast_var_assign("USERNAME", username);
930  struct ast_sorcery_object *obj;
931  RAII_VAR(struct ast_str *, uri, ast_str_create(64), ast_free);
932  RAII_VAR(struct varshead *, subst_vars, ast_var_list_create(), ast_var_list_destroy);
933  RAII_VAR(struct ast_variable *, registration_vars, vars ? ast_variables_dup(vars) : NULL, ast_variables_destroy);
934 
935  AST_VAR_LIST_INSERT_TAIL(subst_vars, rh);
936  AST_VAR_LIST_INSERT_TAIL(subst_vars, un);
937 
938  if (!ast_strlen_zero(server_uri_pattern)) {
939  ast_str_substitute_variables_varshead(&uri, 0, subst_vars,
940  server_uri_pattern);
941  variable_list_append_return(&registration_vars, "server_uri", ast_str_buffer(uri));
942  }
943 
944  if (!ast_strlen_zero(client_uri_pattern)) {
945  ast_str_reset(uri);
946  ast_str_substitute_variables_varshead(&uri, 0, subst_vars,
947  client_uri_pattern);
948  variable_list_append_return(&registration_vars, "client_uri", ast_str_buffer(uri));
949  }
950 
951  if (is_variable_true(wizvars, "sends_auth")) {
952  snprintf(new_id, sizeof(new_id), "%s-oauth", id);
953  variable_list_append_return(&registration_vars, "outbound_auth", new_id);
954  }
955 
956  if (!ast_strlen_zero(transport)) {
957  variable_list_append_return(&registration_vars, "transport", transport);
958  }
959 
960  if (is_variable_true(wizvars, "sends_line_with_registrations")) {
961  variable_list_append_return(&registration_vars, "line", "yes");
962  variable_list_append_return(&registration_vars, "endpoint", id);
963  }
964 
965  snprintf(new_id, sizeof(new_id), "%s-reg-%d", id, host_counter);
966 
967  obj = create_object(sorcery, new_id, "registration", registration_vars);
968  if (!obj) {
969  return -1;
970  }
971 
972  if (otw->wizard->update(sorcery, otw->wizard_data, obj)) {
973  otw->wizard->create(sorcery, otw->wizard_data, obj);
974  }
975  ao2_ref(obj, -1);
976 
977  /* Unlink it from the 'existing' container. Any left will be deleted from
978  * sorcery. If it wasn't in the existing container, no harm.
979  */
981  }
982 
983  /* If there are any excess registrations, delete them. */
984  if (ao2_container_count(existing) > 0) {
986  }
987 
988  return 0;
989 }
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#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 -...
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
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.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
Structure for variables, used for configurations and for channel variables.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2459
#define NULL
Definition: resample.c:96
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
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:842
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
static rc_handle * rh
Definition: cdr_radius.c:96
Structure for internal sorcery object information.
Definition: sorcery.c:127
#define ast_variable_new(name, value, filename)
static int delete_existing_cb(void *obj, void *arg, int flags)
#define LOG_ERROR
Definition: logger.h:285
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
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
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&#39;re suitable for objectset_appl...
#define ast_free(a)
Definition: astmm.h:182
#define ast_var_assign(name, value)
Definition: chanvars.h:40
struct ast_sorcery_wizard * wizard
struct varshead * ast_var_list_create(void)
Definition: chanvars.c:97
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:653
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
enum queue_result id
Definition: app_queue.c:1507
Generic container type.
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
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
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:545
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

References ast_module_ref, ast_sorcery_instance_observer_add(), and ast_module_info::self.

Referenced by wizard_apply_handler().

1209 {
1210  if (strcmp(name, "res_pjsip")) {
1211  return;
1212  }
1215 }
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
static const char name[]
Definition: cdr_mysql.c:74
struct ast_sorcery_instance_observer observer
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

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

References ast_module_unref, ast_sorcery_instance_observer_remove(), and ast_module_info::self.

Referenced by wizard_apply_handler().

1221 {
1222  if (strcmp(name, "res_pjsip")) {
1223  return;
1224  }
1225 
1228 }
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct ast_module * self
Definition: module.h:342
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
static const char name[]
Definition: cdr_mysql.c:74
struct ast_sorcery_instance_observer observer

◆ is_one_of()

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

Definition at line 302 of file res_pjsip_config_wizard.c.

Referenced by object_type_registered_observer(), and wizard_mapped_observer().

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

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

References ast_true(), and ast_variable_find_last_in_list().

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

354 {
356 }
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:842
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static const char name[]
Definition: cdr_mysql.c:74

◆ load_module()

static int load_module ( void  )
static

Definition at line 1327 of file res_pjsip_config_wizard.c.

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

Referenced by unload_module().

1328 {
1329  AST_VECTOR_RW_INIT(&object_type_wizards, 12);
1332 
1333  return AST_MODULE_LOAD_SUCCESS;
1334 }
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition: vector.h:158
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
Definition: sorcery.c:498
static struct ast_cli_entry config_wizard_cli[]
static const struct ast_sorcery_global_observer 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 1063 of file res_pjsip_config_wizard.c.

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, object_type_wizard::wizard, wizard_apply_handler(), and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

1065 {
1066  struct ast_category *category = NULL;
1067  struct object_type_wizard *otw = NULL;
1068  char *filename = "pjsip_wizard.conf";
1069  struct ast_flags flags = { 0 };
1070  struct ast_config *cfg;
1071 
1072  if (!strstr("auth aor endpoint identify registration phoneprov", object_type)) {
1073  /* Not interested. */
1074  return;
1075  }
1076 
1077  otw = find_wizard(object_type);
1078  if (!otw) {
1079  ast_log(LOG_ERROR, "There was no wizard for object type '%s'\n", object_type);
1080  return;
1081  }
1082 
1083  if (reloaded && otw->last_config) {
1085  }
1086 
1087  cfg = ast_config_load2(filename, object_type, flags);
1088 
1089  if (!cfg) {
1090  ast_log(LOG_ERROR, "Unable to load config file '%s'\n", filename);
1091  return;
1092  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
1093  ast_debug(2, "Config file '%s' was unchanged for '%s'.\n", filename, object_type);
1094  return;
1095  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
1096  ast_log(LOG_ERROR, "Contents of config file '%s' are invalid and cannot be parsed\n", filename);
1097  return;
1098  }
1099 
1100  while ((category = ast_category_browse_filtered(cfg, NULL, category, "type=^wizard$"))) {
1101  const char *id = ast_category_get_name(category);
1102  struct ast_category *last_cat = NULL;
1103  int changes = 0;
1104 
1105  if (otw->last_config) {
1106  last_cat = ast_category_get(otw->last_config, id, "type=^wizard$");
1107  changes = !ast_variable_lists_match(ast_category_first(category), ast_category_first(last_cat), 1);
1108  if (last_cat) {
1109  ast_category_delete(otw->last_config, last_cat);
1110  }
1111  }
1112 
1113  if (!last_cat || changes) {
1114  ast_debug(3, "%s: %s(s) for wizard '%s'\n", reloaded ? "Reload" : "Load", object_type, id);
1115  if (wizard_apply_handler(sorcery, otw, category)) {
1116  ast_log(LOG_ERROR, "Unable to create objects for wizard '%s'\n", id);
1117  }
1118  }
1119  }
1120 
1121  if (!otw->last_config) {
1122  otw->last_config = cfg;
1123  return;
1124  }
1125 
1126  /* Only wizards that weren't in the new config are left in last_config now so we need to delete
1127  * all objects belonging to them.
1128  */
1129  category = NULL;
1130  while ((category = ast_category_browse_filtered(otw->last_config, NULL, category, "type=^wizard$"))) {
1131  const char *id = ast_category_get_name(category);
1132  struct ast_variable *search;
1133  RAII_VAR(struct ao2_container *, existing,
1135 
1136  if (!existing) {
1137  ast_log(LOG_ERROR, "Unable to allocate temporary container.\n");
1138  break;
1139  }
1140 
1141  search = ast_variable_new("@pjsip_wizard", id, "");
1142  if (!search) {
1143  ast_log(LOG_ERROR, "Unable to allocate memory for vaiable '@pjsip_wizard'.\n");
1144  break;
1145  }
1146  otw->wizard->retrieve_multiple(sorcery, otw->wizard_data, object_type, existing, search);
1147  ast_variables_destroy(search);
1148 
1149  if (ao2_container_count(existing) > 0) {
1150  ast_debug(3, "Delete on %s: %d %s(s) for wizard: %s\n",
1151  reloaded ? "Reload" : "Load", ao2_container_count(existing), object_type, id);
1153  delete_existing_cb, otw);
1154  }
1155  }
1156 
1158  otw->last_config = cfg;
1159 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Keeps track of the sorcery wizard and last config for each object type.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *category)
Delete a category.
Definition: main/config.c:1478
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define CONFIG_STATUS_FILEINVALID
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
unsigned int flags
Definition: utils.h:200
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:3154
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
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:1335
static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#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:911
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define ast_variable_new(name, value, filename)
#define CONFIG_STATUS_FILEUNCHANGED
static int delete_existing_cb(void *obj, void *arg, int flags)
static struct object_type_wizard * find_wizard(const char *object_type)
Finds the otw for the object type.
#define LOG_ERROR
Definition: logger.h:285
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
struct ast_sorcery_wizard * wizard
Structure used to handle boolean flags.
Definition: utils.h:199
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:772
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
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:1022
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1028
struct ast_config * last_config

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

References ast_sorcery_apply_wizard_mapping, and is_one_of().

Referenced by wizard_apply_handler().

1198 {
1199  if (is_one_of(object_type, object_types)) {
1200  ast_sorcery_apply_wizard_mapping(sorcery, object_type, "memory", "pjsip_wizard", 0);
1201  }
1202 }
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching)
Apply additional object wizard mappings.
Definition: sorcery.h:511
static int is_one_of(const char *needle, const char *haystack[])

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1336 of file res_pjsip_config_wizard.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_REALTIME_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_sorcery_global_observer_remove(), AST_VECTOR_REMOVE_ALL_CMP_UNORDERED, AST_VECTOR_RW_FREE, ASTERISK_GPL_KEY, load_module(), NOT_EQUALS, NULL, and OTW_DELETE_CB.

1337 {
1341  AST_VECTOR_RW_FREE(&object_type_wizards);
1342 
1343  return 0;
1344 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define NULL
Definition: resample.c:96
static struct ast_cli_entry config_wizard_cli[]
#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
static const struct ast_sorcery_global_observer global_observer
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
Definition: vector.h:202
#define NOT_EQUALS(a, b)
#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

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

References ast_log, ast_variable_list_append, ast_variable_new, and LOG_ERROR.

Referenced by get_object_variables(), and handle_aor().

360 {
361  struct ast_variable *new = ast_variable_new(name, value, "");
362 
363  if (!new) {
364  ast_log(LOG_ERROR, "Unable to allocate memory for new variable '%s'.\n", name);
365  return -1;
366  }
367 
368  ast_variable_list_append(existing, new);
369 
370  return 0;
371 }
Structure for variables, used for configurations and for channel variables.
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
#define ast_variable_new(name, value, filename)
#define LOG_ERROR
Definition: logger.h:285
static const char name[]
Definition: cdr_mysql.c:74
#define ast_variable_list_append(head, new_var)

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

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(), host, instance_created_observer(), instance_destroying_observer(), name, NOT_EQUALS, NULL, object_type_wizard::object_type, object_type_loaded_observer(), object_type_registered_observer(), object_type_wizard::sorcery, object_type_wizard::wizard, object_type_wizard::wizard_data, and wizard_mapped_observer().

Referenced by object_type_loaded_observer().

993 {
994  struct ast_variable *wizvars = ast_category_first(wiz);
995  struct string_vector remote_hosts_vector;
996  const char *remote_hosts;
997  int rc = -1;
998 
999  AST_VECTOR_INIT(&remote_hosts_vector, 16);
1000  remote_hosts = ast_variable_find_last_in_list(wizvars, "remote_hosts");
1001 
1002  if (!ast_strlen_zero(remote_hosts)) {
1003  char *host;
1004  char *hosts = ast_strdupa(remote_hosts);
1005 
1006  while ((host = ast_strsep(&hosts, ',', AST_STRSEP_TRIM))) {
1007  host = ast_strdup(host);
1008  if (host && AST_VECTOR_APPEND(&remote_hosts_vector, host)) {
1009  ast_free(host);
1010  }
1011  }
1012  }
1013 
1014  ast_debug(4, "%s handler starting.\n", otw->object_type);
1015 
1016  if (!strcmp(otw->object_type, "auth")) {
1017  rc = handle_auths(sorcery, otw, wiz);
1018  } else if (!strcmp(otw->object_type, "aor")) {
1019  rc = handle_aor(sorcery, otw, wiz, &remote_hosts_vector);
1020  } else if (!strcmp(otw->object_type, "endpoint")) {
1021  rc = handle_endpoint(sorcery, otw, wiz);
1022  } else if (!strcmp(otw->object_type, "identify")) {
1023  rc = handle_identify(sorcery, otw, wiz, &remote_hosts_vector);
1024  } else if (!strcmp(otw->object_type, "phoneprov")) {
1025  rc = handle_phoneprov(sorcery, otw, wiz);
1026  } else if (!strcmp(otw->object_type, "registration")) {
1027  rc = handle_registrations(sorcery, otw, wiz, &remote_hosts_vector);
1028  }
1029 
1031  AST_VECTOR_FREE(&remote_hosts_vector);
1032 
1033  ast_debug(4, "%s handler complete. rc: %d\n", otw->object_type, rc);
1034 
1035  return rc;
1036 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
static int handle_auths(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)
Structure for variables, used for configurations and for channel variables.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
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:842
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
static char host[256]
Definition: muted.c:77
static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: main/utils.c:1656
#define NOT_EQUALS(a, b)
static int handle_phoneprov(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
static int handle_identify(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
#define ast_free(a)
Definition: astmm.h:182
static int handle_aor(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
#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

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

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, object_type_wizard::wizard, and object_type_wizard::wizard_data.

Referenced by wizard_apply_handler().

1165 {
1166  struct object_type_wizard *otw;
1167 
1168  if (!is_one_of(object_type, object_types)) {
1169  /* Not interested. */
1170  return;
1171  }
1172 
1173  /* We're only interested in memory wizards with the pjsip_wizard tag. */
1174  if (wizard_args && !strcmp(wizard_args, "pjsip_wizard")) {
1175  otw = ast_malloc(sizeof(*otw) + strlen(object_type) + 1);
1176  if (!otw) {
1177  return;
1178  }
1179 
1180  otw->sorcery = sorcery;
1181  otw->wizard = wizard;
1182  otw->wizard_data = wizard_data;
1183  otw->last_config = NULL;
1184  strcpy(otw->object_type, object_type); /* Safe */
1185  AST_VECTOR_RW_WRLOCK(&object_type_wizards);
1186  if (AST_VECTOR_APPEND(&object_type_wizards, otw)) {
1187  ast_free(otw);
1188  } else {
1189  ast_debug(1, "Wizard mapped for object_type '%s'\n", object_type);
1190  }
1191  AST_VECTOR_RW_UNLOCK(&object_type_wizards);
1192  }
1193 }
Keeps track of the sorcery wizard and last config for each object type.
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:890
struct ast_sorcery_wizard * wizard
static int is_one_of(const char *needle, const char *haystack[])
static struct ast_sorcery * sorcery
struct ast_sorcery * sorcery
struct ast_config * last_config

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
static

Definition at line 1351 of file res_pjsip_config_wizard.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

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

◆ 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. This should then allow this module to unload cleanly.
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 1051 of file res_pjsip_config_wizard.c.

◆ observer

Initial value:
= {
.wizard_mapped = wizard_mapped_observer,
.object_type_registered = object_type_registered_observer,
.object_type_loaded = object_type_loaded_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)
When each wizard is mapped, save it off to the vector.
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.

Definition at line 1056 of file res_pjsip_config_wizard.c.

Referenced by ast_sorcery_observer_add(), sorcery_generic_observer_remove(), sorcery_observer_notify_create(), sorcery_observer_notify_delete(), sorcery_observer_notify_loaded(), sorcery_observer_notify_update(), and sorcery_observer_remove().