274#define MAX_ID_SUFFIX 20
276#define BASE_REGISTRAR "res_pjsip_config_wizard"
292#define NOT_EQUALS(a, b) (a != b)
293#define OTW_DELETE_CB(otw) ({ \
294 ast_config_destroy(otw->last_config); \
298const static char *object_types[] = {
"phoneprov",
"registration",
"identify",
"endpoint",
"aor",
"auth",
NULL};
300static int is_one_of(
const char *needle,
const char *haystack[])
303 for (i = 0; haystack[i]; i++) {
304 if (!strcmp(needle, haystack[i])) {
342 ast_log(
LOG_ERROR,
"Unable to apply object type '%s' with id '%s'. Check preceeding errors.\n",
type,
id);
373#define variable_list_append_return(existing, name, value) ({ \
374 struct ast_variable *new = ast_variable_new(name, value, ""); \
376 ast_log(LOG_ERROR, "Unable to allocate memory for new variable '%s'.\n", name); \
379 ast_variable_list_append(existing, new); \
390 int plen = strlen(
prefix);
392 for(; v; v = v->
next) {
421 int priority,
const char *application)
427 void *free_ptr =
NULL;
441 paren = strchr(application,
'(');
443 app = (
char *)application;
465 if (!strcmp(existing_app,
app)
466 && !strcmp(existing_data ? existing_data :
"",
data ?
data :
"")) {
487 hint_device =
ast_alloca(strlen(
"PJSIP/") + strlen(
id) + 1);
488 sprintf(hint_device,
"PJSIP/%s",
id);
539 char *test_variable =
NULL;
546 snprintf(new_id,
sizeof(new_id),
"%s-oauth",
id);
547 test_variable =
"sends_auth";
549 snprintf(new_id,
sizeof(new_id),
"%s-iauth",
id);
550 test_variable =
"accepts_auth";
556 "Wizard '%s' must have '%s_auth/username' if it %s.\n",
id,
direction, test_variable);
607 const char *contact_pattern;
621 contact_pattern =
"sip:${REMOTE_HOST}";
631 for (host_counter = 0; host_counter < host_count; host_counter++) {
685 hint_context =
"default";
699 snprintf(new_id,
sizeof(new_id),
"%s-oauth",
id);
704 snprintf(new_id,
sizeof(new_id),
"%s-iauth",
id);
720 add_hints(hint_context, hint_exten, hint_application,
id);
740 snprintf(new_id,
sizeof(new_id),
"%s-identify",
id);
756 "Wizard '%s' must have 'remote_hosts' if it doesn't accept registrations.\n",
id);
764 for (host_counter = 0; host_counter < host_count; host_counter++) {
792 snprintf(new_id,
sizeof(new_id),
"%s-phoneprov",
id);
805 "Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n",
id);
848 const char *server_uri_pattern;
849 const char *client_uri_pattern;
852 const char *username;
886 ast_log(
LOG_ERROR,
"Wizard '%s' must have 'remote_hosts' if it sends registrations.\n",
id);
893 server_uri_pattern =
"sip:${REMOTE_HOST}";
897 client_uri_pattern =
"sip:${USERNAME}@${REMOTE_HOST}";
902 ast_log(
LOG_ERROR,
"Wizard '%s' must have 'outbound_auth/username' if it sends"
903 " authentication.\n",
id);
914 for (host_counter = 0; host_counter < host_count; host_counter++) {
940 snprintf(new_id,
sizeof(new_id),
"%s-oauth",
id);
953 snprintf(new_id,
sizeof(new_id),
"%s-reg-%d",
id, host_counter);
984 const char *remote_hosts;
1008 }
else if (!strcmp(otw->
object_type,
"endpoint")) {
1010 }
else if (!strcmp(otw->
object_type,
"identify")) {
1012 }
else if (!strcmp(otw->
object_type,
"phoneprov")) {
1014 }
else if (!strcmp(otw->
object_type,
"registration")) {
1052 char *filename =
"pjsip_wizard.conf";
1056 if (!strstr(
"auth aor endpoint identify registration phoneprov", object_type)) {
1063 ast_log(
LOG_ERROR,
"There was no wizard for object type '%s'\n", object_type);
1077 ast_debug(2,
"Config file '%s' was unchanged for '%s'.\n", filename, object_type);
1080 ast_log(
LOG_ERROR,
"Contents of config file '%s' are invalid and cannot be parsed\n", filename);
1097 if (!last_cat || changes) {
1098 ast_debug(3,
"%s: %s(s) for wizard '%s'\n", reloaded ?
"Reload" :
"Load", object_type,
id);
1127 ast_log(
LOG_ERROR,
"Unable to allocate memory for vaiable '@pjsip_wizard'.\n");
1134 ast_debug(3,
"Delete on %s: %d %s(s) for wizard: %s\n",
1188 if (strcmp(
name,
"res_pjsip")) {
1200 if (strcmp(
name,
"res_pjsip")) {
1213 const char *fn =
NULL;
1217 e->
command =
"pjsip export config_wizard primitives [to]";
1219 "Usage: pjsip export config_wizard primitives [ to <filename ]\n"
1220 " Export the config_wizard objects as pjsip primitives to\n"
1221 " the console or to <filename>\n";
1241 fprintf(f,
";! Automatically generated configuration file\n");
1242 fprintf(f,
";! Filename: %s\n", fn);
1243 fprintf(f,
";! Generator: %s\n",
"'pjsip export config_wizard primitives'");
1244 fprintf(f,
";! Creation Date: %s", date);
1274 for (v = vars; v; v = v->
next) {
1277 fprintf(f,
"%s = %s\n", v->
name, v->
value);
1294 ast_cli(
a->fd,
"Wrote configuration to %s\n", fn);
1331 for (i = 0; i <
ARRAY_LEN(object_types); ++i) {
1332 if (!object_types[i]) {
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_free_ptr(void *ptr)
free() wrapper
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_iterator_next(iter)
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
void ast_var_list_destroy(struct varshead *head)
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
#define ast_var_assign(name, value)
struct varshead * ast_var_list_create(void)
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static const char context_name[]
static char prefix[MAX_PREFIX]
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *cat)
Delete a category.
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.
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.
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
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.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
@ CONFIG_FLAG_FILEUNCHANGED
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_module_ref(mod)
Hold a reference to the module.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_REALTIME_DRIVER
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
Core PBX routines and definitions.
void * ast_get_extension_app_data(struct ast_exten *e)
int ast_wrlock_contexts(void)
Write locks the context list.
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...
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
const char * ast_get_extension_app(struct ast_exten *e)
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.
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
int ast_unlock_context(struct ast_context *con)
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
const char * ast_get_context_name(struct ast_context *con)
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.
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)
int ast_unlock_contexts(void)
Unlocks contexts.
struct ao2_container * container
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
static void instance_destroying_observer(const char *name, struct ast_sorcery *sorcery)
When the res_pjsip instance is destroyed, remove the observer and unref the module....
static 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 add_hints(const char *context, const char *exten, const char *application, const char *id)
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
static int delete_existing_cb(void *obj, void *arg, int flags)
#define OTW_DELETE_CB(otw)
static int add_extension(struct ast_context *context, const char *exten, int priority, const char *application)
static struct object_type_wizard * find_wizard(const char *object_type)
Finds the otw for the object type.
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 const struct ast_sorcery_global_observer global_observer
static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, char *direction)
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....
static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
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.
#define MAX_ID_SUFFIX
Defines the maximum number of characters that can be added to a wizard id.
static int handle_registrations(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
static int is_one_of(const char *needle, const char *haystack[])
static char * handle_export_primitives(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void object_type_registered_observer(const char *name, struct ast_sorcery *sorcery, const char *object_type)
When each object type is registered, map a memory wizard to it.
static int reload_module(void)
#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 AST_VECTOR_RW(object_type_wizards, struct object_type_wizard *)
static struct ast_cli_entry config_wizard_cli[]
static void * create_object(const struct ast_sorcery *sorcery, const char *id, const char *type, struct ast_variable *vars)
Creates a sorcery object and applies a variable list.
static struct ast_variable * get_object_variables(struct ast_variable *vars, char *prefix)
We need to strip off the prefix from the name of each variable so they're suitable for objectset_appl...
struct ast_sorcery_instance_observer observer
static int delete_extens(const char *context, const char *exten)
static int load_module(void)
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 unload_module(void)
static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
static int handle_auths(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
static int handle_phoneprov(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
static struct ast_sorcery * sorcery
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
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.
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
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.
@ AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
@ AST_SORCERY_WIZARD_APPLY_READONLY
@ AST_SORCERY_APPLY_SUCCESS
#define ast_sorcery_object_type_apply_wizard(sorcery, object_type_name, wizard_type_name, wizard_args, flags, wizard, wizard_data)
Apply additional object wizard mappings returning wizard information.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
descriptor for a cli entry.
ast_context: An extension context
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Structure used to handle boolean flags.
Interface for the global sorcery observer.
void(* instance_created)(const char *name, struct ast_sorcery *sorcery)
Callback after an instance is created.
Interface for the sorcery instance observer.
void(* object_type_registered)(const char *name, struct ast_sorcery *sorcery, const char *object_type)
Callback after any object_type is registered.
Structure for internal sorcery object information.
Interface for a sorcery wizard.
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.
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Full structure for sorcery.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Keeps track of the sorcery wizard and last config for each object type.
struct ast_config * last_config
struct ast_sorcery * sorcery
struct ast_sorcery_wizard * wizard
A generic char * vector definition.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Vector container support.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove all elements from a vector that matches the given comparison.
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR(name, type)
Define a vector structure.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.