276 #define MAX_ID_SUFFIX 20 278 #define BASE_REGISTRAR "res_pjsip_config_wizard" 294 #define NOT_EQUALS(a, b) (a != b) 295 #define OTW_DELETE_CB(otw) ({ \ 296 ast_config_destroy(otw->last_config); \ 300 const static char *object_types[] = {
"phoneprov",
"registration",
"identify",
"endpoint",
"aor",
"auth",
NULL};
302 static int is_one_of(
const char *needle,
const char *haystack[])
305 for (i = 0; haystack[i]; i++) {
306 if (!strcmp(needle, haystack[i])) {
339 ast_log(
LOG_ERROR,
"Unable to allocate an object of type '%s' with id '%s'.\n", type,
id);
344 ast_log(
LOG_ERROR,
"Unable to apply object type '%s' with id '%s'. Check preceeding errors.\n", type,
id);
364 ast_log(
LOG_ERROR,
"Unable to allocate memory for new variable '%s'.\n", name);
375 #define variable_list_append_return(existing, name, value) ({ \ 376 struct ast_variable *new = ast_variable_new(name, value, ""); \ 378 ast_log(LOG_ERROR, "Unable to allocate memory for new variable '%s'.\n", name); \ 381 ast_variable_list_append(existing, new); \ 392 int plen = strlen(prefix);
394 for(; v; v = v->
next) {
423 int priority,
const char *application)
429 void *free_ptr =
NULL;
443 paren = strchr(application,
'(');
445 app = (
char *)application;
448 app[paren - application] =
'\0';
453 data[strlen(data) - 1] =
'\0';
467 if (!strcmp(existing_app, app)
468 && !strcmp(existing_data ? existing_data :
"", data ? data :
"")) {
489 hint_device =
ast_alloca(strlen(
"PJSIP/") + strlen(
id) + 1);
490 sprintf(hint_device,
"PJSIP/%s",
id);
499 ast_log(
LOG_ERROR,
"Unable to find or create hint context '%s'\n", context);
540 char prefix[strlen(direction) + strlen(
"_auth/") + 1];
541 char *test_variable =
NULL;
544 snprintf(prefix,
sizeof(prefix),
"%s_auth/", direction);
547 if (!strcmp(direction,
"outbound")) {
548 snprintf(new_id,
sizeof(new_id),
"%s-oauth",
id);
549 test_variable =
"sends_auth";
551 snprintf(new_id,
sizeof(new_id),
"%s-iauth",
id);
552 test_variable =
"accepts_auth";
558 "Wizard '%s' must have '%s_auth/username' if it %s.\n",
id, direction, test_variable);
596 if ((rc =
handle_auth(sorcery, otw, wiz,
"outbound"))) {
604 struct ast_category *wiz,
struct string_vector *remote_hosts_vector)
609 const char *contact_pattern;
623 contact_pattern =
"sip:${REMOTE_HOST}";
633 for (host_counter = 0; host_counter < host_count; host_counter++) {
687 hint_context =
"default";
701 snprintf(new_id,
sizeof(new_id),
"%s-oauth",
id);
706 snprintf(new_id,
sizeof(new_id),
"%s-iauth",
id);
722 add_hints(hint_context, hint_exten, hint_application,
id);
732 struct ast_category *wiz,
struct string_vector *remote_hosts_vector)
742 snprintf(new_id,
sizeof(new_id),
"%s-identify",
id);
758 "Wizard '%s' must have 'remote_hosts' if it doesn't accept registrations.\n",
id);
766 for (host_counter = 0; host_counter < host_count; host_counter++) {
768 char host[strlen(rhost) + 1];
773 colon = strchr(host,
':');
804 snprintf(new_id,
sizeof(new_id),
"%s-phoneprov",
id);
817 "Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n",
id);
855 struct ast_category *wiz,
struct string_vector *remote_hosts_vector)
860 const char *server_uri_pattern;
861 const char *client_uri_pattern;
864 const char *username;
898 ast_log(
LOG_ERROR,
"Wizard '%s' must have 'remote_hosts' if it sends registrations.\n",
id);
905 server_uri_pattern =
"sip:${REMOTE_HOST}";
909 client_uri_pattern =
"sip:${USERNAME}@${REMOTE_HOST}";
914 ast_log(
LOG_ERROR,
"Wizard '%s' must have 'outbound_auth/username' if it sends" 915 " authentication.\n",
id);
926 for (host_counter = 0; host_counter < host_count; host_counter++) {
952 snprintf(new_id,
sizeof(new_id),
"%s-oauth",
id);
965 snprintf(new_id,
sizeof(new_id),
"%s-reg-%d",
id, host_counter);
967 obj =
create_object(sorcery, new_id,
"registration", registration_vars);
995 struct string_vector remote_hosts_vector;
996 const char *remote_hosts;
1019 rc =
handle_aor(sorcery, otw, wiz, &remote_hosts_vector);
1020 }
else if (!strcmp(otw->
object_type,
"endpoint")) {
1022 }
else if (!strcmp(otw->
object_type,
"identify")) {
1024 }
else if (!strcmp(otw->
object_type,
"phoneprov")) {
1026 }
else if (!strcmp(otw->
object_type,
"registration")) {
1068 char *filename =
"pjsip_wizard.conf";
1072 if (!strstr(
"auth aor endpoint identify registration phoneprov", object_type)) {
1079 ast_log(
LOG_ERROR,
"There was no wizard for object type '%s'\n", object_type);
1093 ast_debug(2,
"Config file '%s' was unchanged for '%s'.\n", filename, object_type);
1096 ast_log(
LOG_ERROR,
"Contents of config file '%s' are invalid and cannot be parsed\n", filename);
1113 if (!last_cat || changes) {
1114 ast_debug(3,
"%s: %s(s) for wizard '%s'\n", reloaded ?
"Reload" :
"Load", object_type,
id);
1143 ast_log(
LOG_ERROR,
"Unable to allocate memory for vaiable '@pjsip_wizard'.\n");
1150 ast_debug(3,
"Delete on %s: %d %s(s) for wizard: %s\n",
1168 if (!
is_one_of(object_type, object_types)) {
1174 if (wizard_args && !strcmp(wizard_args,
"pjsip_wizard")) {
1175 otw =
ast_malloc(
sizeof(*otw) + strlen(object_type) + 1);
1189 ast_debug(1,
"Wizard mapped for object_type '%s'\n", object_type);
1199 if (
is_one_of(object_type, object_types)) {
1210 if (strcmp(name,
"res_pjsip")) {
1222 if (strcmp(name,
"res_pjsip")) {
1235 const char *fn =
NULL;
1239 e->
command =
"pjsip export config_wizard primitives [to]";
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";
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);
1296 for (v = vars; v; v = v->
next) {
1299 fprintf(f,
"%s = %s\n", v->
name, v->
value);
1316 ast_cli(a->
fd,
"Wrote configuration to %s\n", fn);
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
struct ast_variable * next
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
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.
int ast_unlock_context(struct ast_context *con)
static char exten[AST_MAX_EXTENSION]
#define AST_CLI_DEFINE(fn, txt,...)
static int load_module(void)
Asterisk main include file. File version handling, generic pbx functions.
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
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.
const char * ast_get_context_name(struct ast_context *con)
Keeps track of the sorcery wizard and last config for each object type.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching)
Apply additional object wizard mappings.
#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 -...
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
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.
The arg parameter is a search key, but is not an object.
void(* instance_created)(const char *name, struct ast_sorcery *sorcery)
Callback after an instance is created.
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.
Interface for the global sorcery observer.
static int add_hints(const char *context, const char *exten, const char *application, const char *id)
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.
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *category)
Delete a category.
static AST_VECTOR_RW(object_type_wizards, struct object_type_wizard *)
descriptor for a cli entry.
static char * handle_export_primitives(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
const char * ast_get_extension_app(struct ast_exten *e)
#define ao2_callback(c, flags, cb_fn, arg)
static int handle_auths(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
#define CONFIG_STATUS_FILEINVALID
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
static int handle_registrations(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
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.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Full structure for sorcery.
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on 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...
void * ast_get_extension_app_data(struct ast_exten *e)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
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.
Return all matching objects.
int ast_wrlock_contexts(void)
Write locks the context list.
#define ast_strdup(str)
A wrapper for strdup()
void ast_cli(int fd, const char *fmt,...)
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
static struct ast_cli_entry config_wizard_cli[]
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.
void ast_free_ptr(void *ptr)
free() wrapper
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, char *direction)
#define OTW_DELETE_CB(otw)
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
static const char context_name[]
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_strlen_zero(foo)
void(* wizard_mapped)(const char *name, struct ast_sorcery *sorcery, const char *object_type, struct ast_sorcery_wizard *wizard, const char *wizard_args, void *wizard_data)
Callback after a wizard is mapped to an object_type.
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
#define ast_debug(level,...)
Log a DEBUG message.
static const struct ast_sorcery_global_observer global_observer
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
Interface for the sorcery instance observer.
#define ao2_ref(o, delta)
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
#define ast_strdupa(s)
duplicate a string in memory from the stack
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
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.
Structure for internal sorcery object information.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
#define ast_malloc(len)
A wrapper for malloc()
struct ao2_container * container
#define ast_variable_new(name, value, filename)
static int add_extension(struct ast_context *context, const char *exten, int priority, const char *application)
Core PBX routines and definitions.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
#define CONFIG_STATUS_FILEUNCHANGED
static int delete_existing_cb(void *obj, void *arg, int flags)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static struct object_type_wizard * find_wizard(const char *object_type)
Finds the otw for the object type.
static int handle_phoneprov(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz)
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.
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".
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
static int handle_identify(const struct ast_sorcery *sorcery, struct object_type_wizard *otw, struct ast_category *wiz, struct string_vector *remote_hosts_vector)
int ast_unlock_contexts(void)
Unlocks contexts.
static int unload_module(void)
#define ao2_iterator_next(iter)
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
static struct ast_variable * get_object_variables(struct ast_variable *vars, char *prefix)
We need to strip off the prefix from the name of each variable so they're suitable for objectset_appl...
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
#define ast_var_assign(name, value)
struct ast_sorcery_wizard * wizard
Vector container support.
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 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.
Structure used to handle boolean flags.
AST_VECTOR(string_vector, char *)
A generic char * vector definition.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
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.
static int is_one_of(const char *needle, const char *haystack[])
Interface for a sorcery wizard.
struct varshead * ast_var_list_create(void)
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_VECTOR_GET(vec, idx)
Get an element from a vector.
int ast_variable_lists_match(const struct ast_variable *left, const struct ast_variable *right, int exact_match)
Tests 2 variable lists to see if they match.
struct ast_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...
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct ast_sorcery_instance_observer observer
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...
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
#define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove all elements from a vector that matches the given comparison.
static char context[AST_MAX_CONTEXT]
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.
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
struct ast_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.
static int is_variable_true(struct ast_variable *vars, const char *name)
Finds the last variable in a list and tests it.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
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)
void ast_var_list_destroy(struct varshead *head)
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
ast_context: An extension context - must remain in sync with fake_context
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
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.
#define ast_variable_list_append(head, new_var)
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.
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
struct ast_config * last_config
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Sorcery Data Access Layer API.
static char prefix[MAX_PREFIX]
#define ast_module_ref(mod)
Hold a reference to the module.