summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2014-03-08 16:50:36 +0000
committerGeorge Joseph <george.joseph@fairview5.com>2014-03-08 16:50:36 +0000
commit3ff60b75b144d70034a768fc7d7da4537bf7cd7a (patch)
tree41509c60312f10e14a72c4f3a6bf37bb85c06cb9 /res
parent5ca081e05369e2611048ac942f6c48e4814e4fe2 (diff)
pjsip_cli: Create pjsip show channel and contact, and general cli code cleanup.
Created the 'pjsip show channel' and 'pjsip show contact' commands. Refactored out the hated ast_hashtab. Replaced with ao2_container. Cleaned up function naming. Internal only, no public name changes. Cleaned up whitespace and brace formatting in cli code. Changed some NULL checking from "if"s to ast_asserts. Fixed some register/unregister ordering to reduce deadlock potential. Fixed ast_sip_location_add_contact where the 'name' buffer was too short. Fixed some self-assignment issues in res_pjsip_outbound_registration. (closes issue ASTERISK-23276) Review: http://reviewboard.asterisk.org/r/3283/ ........ Merged revisions 410287 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410288 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip/config_auth.c62
-rw-r--r--res/res_pjsip/config_transport.c53
-rw-r--r--res/res_pjsip/location.c310
-rw-r--r--res/res_pjsip/pjsip_cli.c136
-rw-r--r--res/res_pjsip/pjsip_configuration.c323
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c68
-rw-r--r--res/res_pjsip_outbound_registration.c57
7 files changed, 645 insertions, 364 deletions
diff --git a/res/res_pjsip/config_auth.c b/res/res_pjsip/config_auth.c
index bfba26253..05ec4c9ae 100644
--- a/res/res_pjsip/config_auth.c
+++ b/res/res_pjsip/config_auth.c
@@ -199,10 +199,10 @@ static struct ast_sip_endpoint_formatter endpoint_auth_formatter = {
.format_ami = format_ami_endpoint_auth
};
-static struct ao2_container *cli_get_auth_container(void)
+static struct ao2_container *cli_get_container(void)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, s_container, NULL, ao2_cleanup);
+ struct ao2_container *s_container;
container = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "auth",
AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
@@ -211,34 +211,36 @@ static struct ao2_container *cli_get_auth_container(void)
}
s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
if (!s_container) {
return NULL;
}
if (ao2_container_dup(s_container, container, 0)) {
+ ao2_ref(s_container, -1);
return NULL;
}
- ao2_ref(s_container, +1);
+
return s_container;
}
-static int cli_iterator(const void *container, ao2_callback_fn callback, void *args)
+static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
{
- const struct ast_sip_auth_vector *vector = container;
+ return ast_sip_for_each_auth(container, callback, args);
+}
- return ast_sip_for_each_auth(vector, callback, args);
+static void *cli_retrieve_by_id(const char *id)
+{
+ return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE, id);
}
-static int cli_print_auth_header(void *obj, void *arg, int flags)
+static int cli_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
int indent = CLI_INDENT_TO_SPACES(context->indent_level);
int filler = CLI_MAX_WIDTH - indent - 20;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
ast_str_append(&context->output_buffer, 0,
"%*s: <AuthId/UserName%*.*s>\n", indent, "I/OAuth", filler, filler,
@@ -247,17 +249,13 @@ static int cli_print_auth_header(void *obj, void *arg, int flags)
return 0;
}
-static int cli_print_auth_body(void *obj, void *arg, int flags)
+static int cli_print_body(void *obj, void *arg, int flags)
{
struct ast_sip_auth *auth = obj;
struct ast_sip_cli_context *context = arg;
char title[32];
- context->current_auth = auth;
-
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
snprintf(title, sizeof(title), "%sAuth",
context->auth_direction ? context->auth_direction : "");
@@ -275,15 +273,6 @@ static int cli_print_auth_body(void *obj, void *arg, int flags)
return 0;
}
-static struct ast_sip_cli_formatter_entry cli_auth_formatter = {
- .name = SIP_SORCERY_AUTH_TYPE,
- .print_header = cli_print_auth_header,
- .print_body = cli_print_auth_body,
- .get_container = cli_get_auth_container,
- .iterator = cli_iterator,
- .comparator = ast_sorcery_object_id_compare,
-};
-
static struct ast_cli_entry cli_commands[] = {
AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Auths",
.command = "pjsip list auths",
@@ -299,6 +288,8 @@ static struct ast_cli_entry cli_commands[] = {
" Show the configured PJSIP Auth\n"),
};
+static struct ast_sip_cli_formatter_entry *cli_formatter;
+
/*! \brief Initialize sorcery with auth support */
int ast_sip_initialize_sorcery_auth(void)
{
@@ -326,7 +317,21 @@ int ast_sip_initialize_sorcery_auth(void)
"userpass", auth_type_handler, auth_type_to_str, NULL, 0, 0);
ast_sip_register_endpoint_formatter(&endpoint_auth_formatter);
- ast_sip_register_cli_formatter(&cli_auth_formatter);
+
+ cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!cli_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
+ return -1;
+ }
+ cli_formatter->name = SIP_SORCERY_AUTH_TYPE;
+ cli_formatter->print_header = cli_print_header;
+ cli_formatter->print_body = cli_print_body;
+ cli_formatter->get_container = cli_get_container;
+ cli_formatter->iterate = cli_iterator;
+ cli_formatter->get_id = ast_sorcery_object_get_id;
+ cli_formatter->retrieve_by_id = cli_retrieve_by_id;
+
+ ast_sip_register_cli_formatter(cli_formatter);
ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
return 0;
@@ -335,6 +340,7 @@ int ast_sip_initialize_sorcery_auth(void)
int ast_sip_destroy_sorcery_auth(void)
{
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
- ast_sip_unregister_cli_formatter(&cli_auth_formatter);
+ ast_sip_unregister_cli_formatter(cli_formatter);
+
return 0;
}
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index 797427b4a..1559ab77c 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -509,7 +509,7 @@ static int tos_to_str(const void *obj, const intptr_t *args, char **buf)
static struct ao2_container *cli_get_container(void)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, s_container, NULL, ao2_cleanup);
+ struct ao2_container *s_container;
container = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport",
AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
@@ -518,19 +518,20 @@ static struct ao2_container *cli_get_container(void)
}
s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
if (!s_container) {
return NULL;
}
if (ao2_container_dup(s_container, container, 0)) {
+ ao2_ref(s_container, -1);
return NULL;
}
- ao2_ref(s_container, +1);
+
return s_container;
}
-static int cli_iterator(const void *container, ao2_callback_fn callback, void *args)
+static int cli_iterate(void *container, ao2_callback_fn callback, void *args)
{
const struct ast_sip_endpoint *endpoint = container;
struct ast_sip_transport *transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(),
@@ -539,18 +540,22 @@ static int cli_iterator(const void *container, ao2_callback_fn callback, void *a
if (!transport) {
return -1;
}
+
return callback(transport, args, 0);
}
+static void *cli_retrieve_by_id(const char *id)
+{
+ return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", id);
+}
+
static int cli_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
int indent = CLI_INDENT_TO_SPACES(context->indent_level);
int filler = CLI_MAX_WIDTH - indent - 61;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
ast_str_append(&context->output_buffer, 0,
"%*s: <TransportId........> <Type> <cos> <tos> <BindAddress%*.*s>\n",
@@ -565,9 +570,7 @@ static int cli_print_body(void *obj, void *arg, int flags)
struct ast_sip_cli_context *context = arg;
char hoststr[PJ_INET6_ADDRSTRLEN];
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
pj_sockaddr_print(&transport->host, hoststr, sizeof(hoststr), 3);
@@ -586,15 +589,6 @@ static int cli_print_body(void *obj, void *arg, int flags)
return 0;
}
-static struct ast_sip_cli_formatter_entry cli_formatter = {
- .name = "transport",
- .print_header = cli_print_header,
- .print_body = cli_print_body,
- .get_container = cli_get_container,
- .iterator = cli_iterator,
- .comparator = ast_sorcery_object_id_compare,
-};
-
static struct ast_cli_entry cli_commands[] = {
AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Transports",
.command = "pjsip list transports",
@@ -610,6 +604,8 @@ static struct ast_cli_entry cli_commands[] = {
" Show the configured PJSIP Transport\n"),
};
+static struct ast_sip_cli_formatter_entry *cli_formatter;
+
/*! \brief Initialize sorcery with transport support */
int ast_sip_initialize_sorcery_transport(void)
{
@@ -643,7 +639,21 @@ int ast_sip_initialize_sorcery_transport(void)
ast_sorcery_object_field_register(sorcery, "transport", "cos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, cos));
ast_sip_register_endpoint_formatter(&endpoint_transport_formatter);
- ast_sip_register_cli_formatter(&cli_formatter);
+
+ cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!cli_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
+ return -1;
+ }
+ cli_formatter->name = "transport";
+ cli_formatter->print_header = cli_print_header;
+ cli_formatter->print_body = cli_print_body;
+ cli_formatter->get_container = cli_get_container;
+ cli_formatter->iterate = cli_iterate;
+ cli_formatter->get_id = ast_sorcery_object_get_id;
+ cli_formatter->retrieve_by_id = cli_retrieve_by_id;
+
+ ast_sip_register_cli_formatter(cli_formatter);
ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
return 0;
@@ -652,6 +662,7 @@ int ast_sip_initialize_sorcery_transport(void)
int ast_sip_destroy_sorcery_transport(void)
{
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
- ast_sip_unregister_cli_formatter(&cli_formatter);
+ ast_sip_unregister_cli_formatter(cli_formatter);
+
return 0;
}
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index eb12d8e74..e526c4665 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -181,7 +181,7 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na
int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
struct timeval expiration_time, const char *path_info, const char *user_agent)
{
- char name[AST_UUID_STR_LEN];
+ char name[MAX_OBJECT_FIELD * 2 + 3];
RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), uri);
@@ -279,21 +279,21 @@ static int permanent_uri_handler(const struct aco_option *opt, struct ast_variab
return 0;
}
-static int contact_to_vl(void *object, void *arg, int flags)
+static int contact_to_var_list(void *object, void *arg, int flags)
{
- struct ast_sip_contact *contact = object;
+ struct ast_sip_contact_wrapper *wrapper = object;
struct ast_variable **var = arg;
- ast_variable_list_append(&*var, ast_variable_new("contact", contact->uri, ""));
+ ast_variable_list_append(&*var, ast_variable_new("contact", wrapper->contact->uri, ""));
return 0;
}
-static int contacts_to_vl(const void *obj, struct ast_variable **fields)
+static int contacts_to_var_list(const void *obj, struct ast_variable **fields)
{
const struct ast_sip_aor *aor = obj;
- ast_sip_for_each_contact(aor, contact_to_vl, fields);
+ ast_sip_for_each_contact(aor, contact_to_var_list, fields);
return 0;
}
@@ -323,12 +323,21 @@ int ast_sip_for_each_aor(const char *aors, ao2_callback_fn on_aor, void *arg)
return 0;
}
+static void contact_wrapper_destroy(void *obj)
+{
+ struct ast_sip_contact_wrapper *wrapper = obj;
+ ast_free(wrapper->aor_id);
+ ast_free(wrapper->contact_id);
+ ao2_ref(wrapper->contact, -1);
+}
+
int ast_sip_for_each_contact(const struct ast_sip_aor *aor,
ao2_callback_fn on_contact, void *arg)
{
RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
- struct ast_sip_contact *contact;
struct ao2_iterator i;
+ int res = 0;
+ void *object = NULL;
if (!on_contact ||
!(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
@@ -336,26 +345,44 @@ int ast_sip_for_each_contact(const struct ast_sip_aor *aor,
}
i = ao2_iterator_init(contacts, 0);
- while ((contact = ao2_iterator_next(&i))) {
- int res;
+ while ((object = ao2_iterator_next(&i))) {
+ RAII_VAR(struct ast_sip_contact *, contact, object, ao2_cleanup);
+ RAII_VAR(struct ast_sip_contact_wrapper *, wrapper, NULL, ao2_cleanup);
+ const char *aor_id = ast_sorcery_object_get_id(aor);
+
+ wrapper = ao2_alloc(sizeof(struct ast_sip_contact_wrapper), contact_wrapper_destroy);
+ if (!wrapper) {
+ res = -1;
+ break;
+ }
+ wrapper->contact_id = ast_malloc(strlen(aor_id) + strlen(contact->uri) + 2);
+ if (!wrapper->contact_id) {
+ res = -1;
+ break;
+ }
+ sprintf(wrapper->contact_id, "%s/%s", aor_id, contact->uri);
+ wrapper->aor_id = ast_strdup(aor_id);
+ if (!wrapper->aor_id) {
+ res = -1;
+ break;
+ }
+ wrapper->contact = contact;
+ ao2_bump(wrapper->contact);
- ast_sorcery_object_set_extended(contact, "@aor_id", ast_sorcery_object_get_id(aor));
- if ((res = on_contact(contact, arg, 0))) {
- ao2_iterator_destroy(&i);
- return -1;
+ if ((res = on_contact(wrapper, arg, 0))) {
+ break;
}
}
ao2_iterator_destroy(&i);
- return 0;
+ return res;
}
int ast_sip_contact_to_str(void *object, void *arg, int flags)
{
- struct ast_sip_contact *contact = object;
+ struct ast_sip_contact_wrapper *wrapper = object;
struct ast_str **buf = arg;
- ast_str_append(buf, 0, "%s/%s,",
- ast_sorcery_object_get_extended(contact, "aor_id"), contact->uri);
+ ast_str_append(buf, 0, "%s,", wrapper->contact_id);
return 0;
}
@@ -448,10 +475,10 @@ struct ast_sip_endpoint_formatter endpoint_aor_formatter = {
.format_ami = format_ami_endpoint_aor
};
-static struct ao2_container *cli_get_aor_container(void)
+static struct ao2_container *cli_aor_get_container(void)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, s_container, NULL, ao2_cleanup);
+ struct ao2_container *s_container;
container = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "aor",
AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
@@ -460,90 +487,144 @@ static struct ao2_container *cli_get_aor_container(void)
}
s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
if (!s_container) {
return NULL;
}
if (ao2_container_dup(s_container, container, 0)) {
+ ao2_ref(s_container, -1);
return NULL;
}
- ao2_ref(s_container, +1);
+
return s_container;
}
-static int populate_contact_container(void *obj, void *arg, int flags)
+static int cli_contact_populate_container(void *obj, void *arg, int flags)
{
- struct ast_sip_contact *contact = obj;
- struct ao2_container *container = arg;
+ ao2_link(arg, obj);
- ao2_link(container, contact);
return 0;
}
-static int gather_aor_contacts(void *obj, void *arg, int flags)
+static int cli_aor_gather_contacts(void *obj, void *arg, int flags)
{
struct ast_sip_aor *aor = obj;
- struct ao2_container *container = arg;
- ast_sip_for_each_contact(aor, populate_contact_container, container);
- return 0;
+
+ return ast_sip_for_each_contact(aor, cli_contact_populate_container, arg);
}
-static int cli_contact_compare(const void *left, const void *right, int flags)
+static const char *cli_contact_get_id(const void *obj)
{
- const struct ast_sip_contact *left_contact = left;
- const struct ast_sip_contact *right_contact = right;
- int rc;
+ const struct ast_sip_contact_wrapper *wrapper = obj;
+ return wrapper->contact_id;
+}
- if (!left_contact || !right_contact) {
- return 0;
+static int cli_contact_sort(const void *obj, const void *arg, int flags)
+{
+ const struct ast_sip_contact_wrapper *left_wrapper = obj;
+ const struct ast_sip_contact_wrapper *right_wrapper = arg;
+ const char *right_key = arg;
+ int cmp = 0;
+
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = right_wrapper->contact_id;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ cmp = strcmp(left_wrapper->contact_id, right_key);
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ cmp = strncmp(left_wrapper->contact_id, right_key, strlen(right_key));
+ break;
+ default:
+ cmp = 0;
+ break;
}
- rc = strcmp(ast_sorcery_object_get_extended(left_contact, "aor_id"),
- ast_sorcery_object_get_extended(right_contact, "aor_id"));
- if (rc) {
- return rc;
+
+ return cmp;
+}
+
+static int cli_contact_compare(void *obj, void *arg, int flags)
+{
+ const struct ast_sip_contact_wrapper *left_wrapper = obj;
+ const struct ast_sip_contact_wrapper *right_wrapper = arg;
+ const char *right_key = arg;
+ int cmp = 0;
+
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = right_wrapper->contact_id;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ if (strcmp(left_wrapper->contact_id, right_key) == 0) {;
+ cmp = CMP_MATCH | CMP_STOP;
+ }
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ if (strncmp(left_wrapper->contact_id, right_key, strlen(right_key)) == 0) {
+ cmp = CMP_MATCH;
+ }
+ break;
+ default:
+ cmp = 0;
+ break;
+ }
+
+ return cmp;
+}
+
+static int cli_contact_hash(const void *obj, int flags)
+{
+ const struct ast_sip_contact_wrapper *wrapper = obj;
+ if (flags & OBJ_SEARCH_OBJECT) {
+ return ast_str_hash(wrapper->contact_id);
+ } else if (flags & OBJ_SEARCH_KEY) {
+ return ast_str_hash(obj);
}
- return strcmp(left_contact->uri, right_contact->uri);
+
+ return -1;
+}
+
+static int cli_contact_iterate(void *container, ao2_callback_fn callback, void *args)
+{
+ return ast_sip_for_each_contact(container, callback, args);
}
-static struct ao2_container *cli_get_contact_container(void)
+static struct ao2_container *cli_contact_get_container(void)
{
RAII_VAR(struct ao2_container *, parent_container, NULL, ao2_cleanup);
struct ao2_container *child_container;
- parent_container = cli_get_aor_container();
+ parent_container = cli_aor_get_container();
if (!parent_container) {
return NULL;
}
- child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- cli_contact_compare, NULL);
+ child_container = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, 17,
+ cli_contact_hash, cli_contact_sort, cli_contact_compare);
if (!child_container) {
return NULL;
}
- ao2_ref(child_container, +1);
- ao2_callback(parent_container, OBJ_NODATA, gather_aor_contacts, child_container);
+ ao2_callback(parent_container, OBJ_NODATA, cli_aor_gather_contacts, child_container);
return child_container;
}
-static int cli_contact_iterator(const void *container, ao2_callback_fn callback, void *args)
+static void *cli_contact_retrieve_by_id(const char *id)
{
- const struct ast_sip_aor *array = container;
-
- return ast_sip_for_each_contact(array, callback, args);
+ return ao2_find(cli_contact_get_container(), id, OBJ_KEY | OBJ_NOLOCK);
}
-static int cli_print_contact_header(void *obj, void *arg, int flags)
+static int cli_contact_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
int indent = CLI_INDENT_TO_SPACES(context->indent_level);
int filler = CLI_LAST_TABSTOP - indent - 18;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
+
ast_str_append(&context->output_buffer, 0,
"%*s: <Aor/ContactUri%*.*s> <Status....> <RTT(ms)..>\n",
indent, "Contact", filler, filler, CLI_HEADER_FILLER);
@@ -551,27 +632,20 @@ static int cli_print_contact_header(void *obj, void *arg, int flags)
return 0;
}
-static int cli_print_contact_body(void *obj, void *arg, int flags)
+static int cli_contact_print_body(void *obj, void *arg, int flags)
{
- struct ast_sip_contact *contact = obj;
+ struct ast_sip_contact_wrapper *wrapper = obj;
+ struct ast_sip_contact *contact = wrapper->contact;
struct ast_sip_cli_context *context = arg;
- char *print_name = NULL;
- int print_name_len;
int indent;
int flexwidth;
- const char *aor_id = ast_sorcery_object_get_extended(contact, "aor_id");
RAII_VAR(struct ast_sip_contact_status *, status,
ast_sorcery_retrieve_by_id( ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact)),
ao2_cleanup);
- if (!context->output_buffer) {
- return -1;
- }
-
- print_name_len = strlen(aor_id) + strlen(contact->uri) + 2;
- print_name = ast_alloca(print_name_len);
- snprintf(print_name, print_name_len, "%s/%s", aor_id, contact->uri);
+ ast_assert(contact->uri != NULL);
+ ast_assert(context->output_buffer != NULL);
indent = CLI_INDENT_TO_SPACES(context->indent_level);
flexwidth = CLI_LAST_TABSTOP - indent - 2;
@@ -580,31 +654,40 @@ static int cli_print_contact_body(void *obj, void *arg, int flags)
indent,
"Contact",
flexwidth, flexwidth,
- print_name,
+ wrapper->contact_id,
(status ? (status->status == AVAILABLE ? "Avail" : "Unavail") : "Unknown"),
(status ? ((long long) status->rtt) / 1000.0 : NAN));
return 0;
}
-static int cli_aor_iterator(const void *container, ao2_callback_fn callback, void *args)
+static int cli_aor_iterate(void *container, ao2_callback_fn callback, void *args)
{
const char *aor_list = container;
return ast_sip_for_each_aor(aor_list, callback, args);
}
-static int cli_print_aor_header(void *obj, void *arg, int flags)
+static void *cli_aor_retrieve_by_id(const char *id)
+{
+ return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", id);
+}
+
+static const char *cli_aor_get_id(const void *obj)
+{
+ return ast_sorcery_object_get_id(obj);
+}
+
+static int cli_aor_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
- struct ast_sip_cli_formatter_entry *formatter_entry;
+ RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);
int indent = CLI_INDENT_TO_SPACES(context->indent_level);
int filler = CLI_LAST_TABSTOP - indent - 7;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
+
ast_str_append(&context->output_buffer, 0,
"%*s: <Aor%*.*s> <MaxContact>\n",
indent, "Aor", filler, filler, CLI_HEADER_FILLER);
@@ -612,27 +695,26 @@ static int cli_print_aor_header(void *obj, void *arg, int flags)
if (context->recurse) {
context->indent_level++;
formatter_entry = ast_sip_lookup_cli_formatter("contact");
- if (formatter_entry && formatter_entry->print_header) {
+ if (formatter_entry) {
formatter_entry->print_header(NULL, context, 0);
}
context->indent_level--;
}
+
return 0;
}
-static int cli_print_aor_body(void *obj, void *arg, int flags)
+static int cli_aor_print_body(void *obj, void *arg, int flags)
{
struct ast_sip_aor *aor = obj;
struct ast_sip_cli_context *context = arg;
- struct ast_sip_cli_formatter_entry *formatter_entry;
+ RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);
int indent;
int flexwidth;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
- context->current_aor = aor;
+// context->current_aor = aor;
indent = CLI_INDENT_TO_SPACES(context->indent_level);
flexwidth = CLI_LAST_TABSTOP - indent - 12;
@@ -647,8 +729,8 @@ static int cli_print_aor_body(void *obj, void *arg, int flags)
context->indent_level++;
formatter_entry = ast_sip_lookup_cli_formatter("contact");
- if (formatter_entry && formatter_entry->print_body && formatter_entry->iterator) {
- formatter_entry->iterator(aor, formatter_entry->print_body, context);
+ if (formatter_entry) {
+ formatter_entry->iterate(aor, formatter_entry->print_body, context);
}
context->indent_level--;
@@ -666,24 +748,6 @@ static int cli_print_aor_body(void *obj, void *arg, int flags)
return 0;
}
-static struct ast_sip_cli_formatter_entry cli_contact_formatter = {
- .name = "contact",
- .print_header = cli_print_contact_header,
- .print_body = cli_print_contact_body,
- .get_container = cli_get_contact_container,
- .iterator = cli_contact_iterator,
- .comparator = cli_contact_compare,
-};
-
-static struct ast_sip_cli_formatter_entry cli_aor_formatter = {
- .name = "aor",
- .print_header = cli_print_aor_header,
- .print_body = cli_print_aor_body,
- .get_container = cli_get_aor_container,
- .iterator = cli_aor_iterator,
- .comparator = ast_sorcery_object_id_compare,
-};
-
static struct ast_cli_entry cli_commands[] = {
AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Aors",
.command = "pjsip list aors",
@@ -706,8 +770,15 @@ static struct ast_cli_entry cli_commands[] = {
.command = "pjsip show contacts",
.usage = "Usage: pjsip show contacts\n"
" Show the configured PJSIP contacts\n"),
+ AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Contact",
+ .command = "pjsip show contact",
+ .usage = "Usage: pjsip show contact\n"
+ " Show the configured PJSIP contact\n"),
};
+struct ast_sip_cli_formatter_entry *contact_formatter;
+struct ast_sip_cli_formatter_entry *aor_formatter;
+
/*! \brief Initialize sorcery with location support */
int ast_sip_initialize_sorcery_location(void)
{
@@ -737,23 +808,52 @@ int ast_sip_initialize_sorcery_location(void)
ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
- ast_sorcery_object_field_register_custom(sorcery, "aor", "contact", "", permanent_uri_handler, contacts_to_str, contacts_to_vl, 0, 0);
+ ast_sorcery_object_field_register_custom(sorcery, "aor", "contact", "", permanent_uri_handler, contacts_to_str, contacts_to_var_list, 0, 0);
ast_sorcery_object_field_register(sorcery, "aor", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, mailboxes));
ast_sorcery_object_field_register(sorcery, "aor", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, outbound_proxy));
ast_sorcery_object_field_register(sorcery, "aor", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, support_path));
ast_sip_register_endpoint_formatter(&endpoint_aor_formatter);
- ast_sip_register_cli_formatter(&cli_contact_formatter);
- ast_sip_register_cli_formatter(&cli_aor_formatter);
+
+ contact_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!contact_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for contact_formatter\n");
+ return -1;
+ }
+ contact_formatter->name = "contact";
+ contact_formatter->print_header = cli_contact_print_header;
+ contact_formatter->print_body = cli_contact_print_body;
+ contact_formatter->get_container = cli_contact_get_container;
+ contact_formatter->iterate = cli_contact_iterate;
+ contact_formatter->get_id = cli_contact_get_id;
+ contact_formatter->retrieve_by_id = cli_contact_retrieve_by_id;
+
+ aor_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!aor_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for aor_formatter\n");
+ return -1;
+ }
+ aor_formatter->name = "aor";
+ aor_formatter->print_header = cli_aor_print_header;
+ aor_formatter->print_body = cli_aor_print_body;
+ aor_formatter->get_container = cli_aor_get_container;
+ aor_formatter->iterate = cli_aor_iterate;
+ aor_formatter->get_id = cli_aor_get_id;
+ aor_formatter->retrieve_by_id = cli_aor_retrieve_by_id;
+
+ ast_sip_register_cli_formatter(contact_formatter);
+ ast_sip_register_cli_formatter(aor_formatter);
ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
+
return 0;
}
int ast_sip_destroy_sorcery_location(void)
{
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
- ast_sip_unregister_cli_formatter(&cli_contact_formatter);
- ast_sip_unregister_cli_formatter(&cli_aor_formatter);
+ ast_sip_unregister_cli_formatter(contact_formatter);
+ ast_sip_unregister_cli_formatter(aor_formatter);
+
return 0;
}
diff --git a/res/res_pjsip/pjsip_cli.c b/res/res_pjsip/pjsip_cli.c
index 6ad820a0c..17876024d 100644
--- a/res/res_pjsip/pjsip_cli.c
+++ b/res/res_pjsip/pjsip_cli.c
@@ -31,15 +31,7 @@
#include "asterisk/utils.h"
#include "asterisk/sorcery.h"
-static struct ast_hashtab *formatter_registry;
-
-struct ast_sip_cli_formatter_entry *ast_sip_lookup_cli_formatter(const char *name)
-{
- struct ast_sip_cli_formatter_entry fake_entry = {
- .name = name,
- };
- return ast_hashtab_lookup(formatter_registry, &fake_entry);
-}
+static struct ao2_container *formatter_registry;
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
{
@@ -91,6 +83,7 @@ int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
}
static char *complete_show_sorcery_object(struct ao2_container *container,
+ struct ast_sip_cli_formatter_entry *formatter_entry,
const char *word, int state)
{
char *result = NULL;
@@ -101,9 +94,10 @@ static char *complete_show_sorcery_object(struct ao2_container *container,
void *object;
while ((object = ao2_t_iterator_next(&i, "iterate thru endpoints table"))) {
- if (!strncasecmp(word, ast_sorcery_object_get_id(object), wordlen)
+ const char *id = formatter_entry->get_id(object);
+ if (!strncasecmp(word, id, wordlen)
&& ++which > state) {
- result = ast_strdup(ast_sorcery_object_get_id(object));
+ result = ast_strdup(id);
}
ao2_t_ref(object, -1, "toss iterator endpoint ptr before break");
if (result) {
@@ -111,6 +105,7 @@ static char *complete_show_sorcery_object(struct ao2_container *container,
}
}
ao2_iterator_destroy(&i);
+
return result;
}
@@ -123,20 +118,15 @@ static void dump_str_and_free(int fd, struct ast_str *buf)
char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);
RAII_VAR(void *, object, NULL, ao2_cleanup);
int is_container = 0;
const char *cmd1;
const char *cmd2;
const char *object_id;
char formatter_type[64];
- struct ast_sip_cli_formatter_entry *formatter_entry;
struct ast_sip_cli_context context = {
- .peers_mon_online = 0,
- .peers_mon_offline = 0,
- .peers_unmon_online = 0,
- .peers_unmon_offline = 0,
- .a = a,
.indent_level = 0,
.show_details = 0,
.show_details_only_level_0 = 0,
@@ -203,7 +193,7 @@ char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_
if (cmd == CLI_GENERATE) {
ast_free(context.output_buffer);
- return complete_show_sorcery_object(container, a->word, a->n);
+ return complete_show_sorcery_object(container, formatter_entry, a->word, a->n);
}
if (is_container) {
@@ -219,8 +209,8 @@ char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_
ast_cli(a->fd, "No object specified.\n");
return CLI_FAILURE;
}
- object = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), formatter_type,
- object_id);
+
+ object = formatter_entry->retrieve_by_id(object_id);
if (!object) {
dump_str_and_free(a->fd, context.output_buffer);
ast_cli(a->fd, "Unable to find object %s.\n\n", object_id);
@@ -234,44 +224,110 @@ char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_
return CLI_SUCCESS;
}
-static int compare_formatters(const void *a, const void *b)
+static int formatter_sort(const void *obj, const void *arg, int flags)
{
- const struct ast_sip_cli_formatter_entry *afe = a;
- const struct ast_sip_cli_formatter_entry *bfe = b;
- if (!afe || !bfe) {
- ast_log(LOG_ERROR, "One of the arguments to compare_formatters was NULL\n");
- return -1;
+ const struct ast_sip_cli_formatter_entry *left_obj = obj;
+ const struct ast_sip_cli_formatter_entry *right_obj = arg;
+ const char *right_key = arg;
+ int cmp = 0;
+
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = right_obj->name;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ cmp = strcmp(left_obj->name, right_key);
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ cmp = strncmp(left_obj->name, right_key, strlen(right_key));
+ break;
+ default:
+ cmp = 0;
+ break;
}
- return strcmp(afe->name, bfe->name);
+
+ return cmp;
}
-static unsigned int hash_formatters(const void *a)
+static int formatter_compare(void *obj, void *arg, int flags)
{
- const struct ast_sip_cli_formatter_entry *afe = a;
- return ast_hashtab_hash_string(afe->name);
+ const struct ast_sip_cli_formatter_entry *left_obj = obj;
+ const struct ast_sip_cli_formatter_entry *right_obj = arg;
+ const char *right_key = arg;
+ int cmp = 0;
+
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = right_obj->name;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ if (strcmp(left_obj->name, right_key) == 0) {;
+ cmp = CMP_MATCH | CMP_STOP;
+ }
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ if (strncmp(left_obj->name, right_key, strlen(right_key)) == 0) {
+ cmp = CMP_MATCH;
+ }
+ break;
+ default:
+ cmp = 0;
+ break;
+ }
+
+ return cmp;
+}
+
+static int formatter_hash(const void *obj, int flags)
+{
+ const struct ast_sip_cli_formatter_entry *left_obj = obj;
+ if (flags & OBJ_SEARCH_OBJECT) {
+ return ast_str_hash(left_obj->name);
+ } else if (flags & OBJ_SEARCH_KEY) {
+ return ast_str_hash(obj);
+ }
+
+ return -1;
+}
+
+struct ast_sip_cli_formatter_entry *ast_sip_lookup_cli_formatter(const char *name)
+{
+ return ao2_find(formatter_registry, name, OBJ_SEARCH_KEY | OBJ_NOLOCK);
}
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
{
- ast_hashtab_insert_safe(formatter_registry, formatter);
+ ast_assert(formatter != NULL);
+ ast_assert(formatter->name != NULL);
+ ast_assert(formatter->print_body != NULL);
+ ast_assert(formatter->print_header != NULL);
+ ast_assert(formatter->get_container != NULL);
+ ast_assert(formatter->iterate != NULL);
+ ast_assert(formatter->get_id != NULL);
+ ast_assert(formatter->retrieve_by_id != NULL);
+
+ ao2_link(formatter_registry, formatter);
+
return 0;
}
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
{
- struct ast_sip_cli_formatter_entry *entry = ast_hashtab_lookup(formatter_registry, formatter);
-
- if (!entry) {
- return -1;
+ if (formatter) {
+ ao2_wrlock(formatter_registry);
+ if (ao2_ref(formatter, -1) == 2) {
+ ao2_unlink_flags(formatter_registry, formatter, OBJ_NOLOCK);
+ }
+ ao2_unlock(formatter_registry);
}
- ast_hashtab_remove_this_object(formatter_registry, entry);
return 0;
}
int ast_sip_initialize_cli(void)
{
- formatter_registry = ast_hashtab_create(17, compare_formatters,
- ast_hashtab_resize_java, ast_hashtab_newsize_java, hash_formatters, 0);
+ formatter_registry = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, 17,
+ formatter_hash, formatter_sort, formatter_compare);
+
if (!formatter_registry) {
ast_log(LOG_ERROR, "Unable to create formatter_registry.\n");
return -1;
@@ -282,7 +338,5 @@ int ast_sip_initialize_cli(void)
void ast_sip_destroy_cli(void)
{
- if (formatter_registry) {
- ast_hashtab_destroy(formatter_registry, ast_free_ptr);
- }
+ ao2_ref(formatter_registry, -1);
}
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 0aa63004b..b2a86c3c8 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1217,10 +1217,10 @@ static int ami_show_endpoints(struct mansession *s, const struct message *m)
return 0;
}
-static struct ao2_container *cli_get_endpoint_container(void)
+static struct ao2_container *cli_endpoint_get_container(void)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, s_container, NULL, ao2_cleanup);
+ struct ao2_container *s_container;
container = ast_sorcery_retrieve_by_fields(sip_sorcery, "endpoint",
AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
@@ -1229,100 +1229,175 @@ static struct ao2_container *cli_get_endpoint_container(void)
}
s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ (void *)ast_sorcery_object_id_sort, (void *)ast_sorcery_object_id_compare);
if (!s_container) {
return NULL;
}
if (ao2_container_dup(s_container, container, 0)) {
+ ao2_ref(s_container, -1);
return NULL;
}
- ao2_ref(s_container, +1);
+
return s_container;
}
-static int populate_channel_container(void *obj, void *arg, int flags)
+static int cli_channel_populate_container(void *obj, void *arg, int flags)
{
struct ast_channel_snapshot *snapshot = obj;
- struct ao2_container *container = arg;
- ao2_link(container, snapshot);
+ ao2_link(arg, snapshot);
+
return 0;
}
-static int cli_channel_iterator(const void *container, ao2_callback_fn callback, void *args)
+static int cli_channel_iterate(void *container, ao2_callback_fn callback, void *args)
{
- const struct ast_sip_endpoint *array = container;
+ const struct ast_sip_endpoint *endpoint = container;
+
+ ast_sip_for_each_channel(endpoint, callback, args);
- return ast_sip_for_each_channel(array, callback, args);
+ return 0;
}
-static int gather_endpoint_channels(void *obj, void *arg, int flags)
+static int cli_channel_sort(const void *obj, const void *arg, int flags)
{
- struct ast_sip_endpoint *endpoint = obj;
- struct ao2_container *channels = arg;
+ const struct ast_channel_snapshot *left_obj = obj;
+ const struct ast_channel_snapshot *right_obj = arg;
+ const char *right_key = arg;
+ int cmp;
- ast_sip_for_each_channel(endpoint, populate_channel_container, channels);
- return 0;
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = right_obj->name;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ cmp = strcmp(left_obj->name, right_key);
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ cmp = strncmp(left_obj->name, right_key, strlen(right_key));
+ break;
+ default:
+ cmp = 0;
+ break;
+ }
+
+ return cmp;
}
-static int cli_channel_compare(const void *left, const void *right, int flags)
+static int cli_channel_compare(void *obj, void *arg, int flags)
{
- const struct ast_channel_snapshot *left_snap = left;
- const struct ast_channel_snapshot *right_snap = right;
+ const struct ast_channel_snapshot *left_obj = obj;
+ const struct ast_channel_snapshot *right_obj = arg;
+ const char *right_key = arg;
+ int cmp = 0;
- if (!left_snap || !right_snap) {
- return 0;
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = right_obj->name;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ if (strcmp(left_obj->name, right_key) == 0) {
+ cmp = CMP_MATCH | CMP_STOP;
+ }
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ if (strncmp(left_obj->name, right_key, strlen(right_key)) == 0) {
+ cmp = CMP_MATCH;
+ }
+ break;
+ default:
+ cmp = 0;
+ break;
}
- return strcmp(left_snap->name, right_snap->name);
+
+ return cmp;
}
-static struct ao2_container *cli_get_channel_container(void)
+static int cli_channel_hash(const void *obj, int flags)
+{
+ const struct ast_channel_snapshot *snapshot = obj;
+
+ if (flags & OBJ_SEARCH_OBJECT) {
+ return ast_str_hash(snapshot->name);
+ } else if (flags & OBJ_SEARCH_KEY) {
+ return ast_str_hash(obj);
+ }
+
+ return -1;
+}
+
+static int cli_endpoint_gather_channels(void *obj, void *arg, int flags)
+{
+ struct ast_sip_endpoint *endpoint = obj;
+ struct ao2_container *channels = arg;
+
+ ast_sip_for_each_channel(endpoint, cli_channel_populate_container, channels);
+
+ return 0;
+}
+
+static struct ao2_container *cli_channel_get_container(void)
{
RAII_VAR(struct ao2_container *, parent_container, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, child_container, NULL, ao2_cleanup);
+ struct ao2_container *child_container;
- parent_container = cli_get_endpoint_container();
+ parent_container = cli_endpoint_get_container();
if (!parent_container) {
return NULL;
}
- child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- cli_channel_compare, NULL);
+ child_container = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, 17,
+ cli_channel_hash, cli_channel_sort, cli_channel_compare);
if (!child_container) {
return NULL;
}
- ao2_callback(parent_container, OBJ_NODATA, gather_endpoint_channels, child_container);
- ao2_ref(child_container, +1);
+ ao2_callback(parent_container, OBJ_NODATA, cli_endpoint_gather_channels, child_container);
+
return child_container;
}
-static int cli_print_channel_header(void *obj, void *arg, int flags)
+static const char *cli_channel_get_id(const void *obj)
+{
+ const struct ast_channel_snapshot *snapshot = obj;
+
+ return snapshot->name;
+}
+
+static void *cli_channel_retrieve_by_id(const char *id)
+{
+ RAII_VAR(struct ao2_container *, container, cli_channel_get_container(), ao2_cleanup);
+
+ return ao2_find(container, id, OBJ_KEY | OBJ_NOLOCK);
+}
+
+static int cli_channel_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
int indent = CLI_INDENT_TO_SPACES(context->indent_level);
int filler = CLI_LAST_TABSTOP - indent - 13;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
+
ast_str_append(&context->output_buffer, 0,
"%*s: <ChannelId%*.*s> <State.....> <Time(sec)>\n",
indent, "Channel", filler, filler, CLI_HEADER_FILLER);
+ if (context->recurse) {
+ context->indent_level++;
+ indent = CLI_INDENT_TO_SPACES(context->indent_level);
+ filler = CLI_LAST_TABSTOP - indent - 38;
+ ast_str_append(&context->output_buffer, 0,
+ "%*s: <Codec> Exten: <DialedExten%*.*s> CLCID: <ConnectedLineCID.......>\n",
+ indent, "Codec", filler, filler, CLI_HEADER_FILLER);
+ context->indent_level--;
+ }
- context->indent_level++;
- indent = CLI_INDENT_TO_SPACES(context->indent_level);
- filler = CLI_LAST_TABSTOP - indent - 38;
- ast_str_append(&context->output_buffer, 0,
- "%*s: <Codec> Exten: <DialedExten%*.*s> CLCID: <ConnectedLineCID.......>\n",
- indent, "Codec", filler, filler, CLI_HEADER_FILLER);
- context->indent_level--;
return 0;
}
-static int cli_print_channel_body(void *obj, void *arg, int flags)
+static int cli_channel_print_body(void *obj, void *arg, int flags)
{
- struct ast_channel_snapshot *snapshot = obj;
+ const struct ast_channel_snapshot *snapshot = obj;
struct ast_sip_cli_context *context = arg;
struct timeval current_time;
char *print_name = NULL;
@@ -1330,9 +1405,7 @@ static int cli_print_channel_body(void *obj, void *arg, int flags)
int indent;
int flexwidth;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
gettimeofday(&current_time, NULL);
@@ -1353,79 +1426,84 @@ static int cli_print_channel_body(void *obj, void *arg, int flags)
ast_state2str(snapshot->state),
current_time.tv_sec - snapshot->creationtime.tv_sec);
- context->indent_level++;
- indent = CLI_INDENT_TO_SPACES(context->indent_level);
- flexwidth = CLI_LAST_TABSTOP - indent - 25;
-
- ast_str_append(&context->output_buffer, 0,
- "%*s: %-7s Exten: %-*.*s CLCID: \"%s\" <%s>\n",
- indent, "Codec",
- snapshot->nativeformats,
- flexwidth, flexwidth,
- snapshot->exten,
- snapshot->connected_name,
- snapshot->connected_number
- );
- context->indent_level--;
- if (context->indent_level == 0) {
- ast_str_append(&context->output_buffer, 0, "\n");
+ if (context->recurse) {
+ context->indent_level++;
+ indent = CLI_INDENT_TO_SPACES(context->indent_level);
+ flexwidth = CLI_LAST_TABSTOP - indent - 25;
+
+ ast_str_append(&context->output_buffer, 0,
+ "%*s: %-7s Exten: %-*.*s CLCID: \"%s\" <%s>\n",
+ indent, "Codec",
+ snapshot->nativeformats,
+ flexwidth, flexwidth,
+ snapshot->exten,
+ snapshot->connected_name,
+ snapshot->connected_number
+ );
+ context->indent_level--;
+ if (context->indent_level == 0) {
+ ast_str_append(&context->output_buffer, 0, "\n");
+ }
}
return 0;
}
-static int cli_endpoint_iterator(const void *container, ao2_callback_fn callback,
- void *args)
+static int cli_endpoint_iterate(void *obj, ao2_callback_fn callback, void *args)
{
- struct ao2_container *ao2container = (struct ao2_container *) container;
+ ao2_callback(obj, OBJ_NODATA, callback, args);
- ao2_callback(ao2container, OBJ_NODATA, callback, args);
return 0;
}
-static void print_child_header(char *type, struct ast_sip_cli_context *context)
+static void *cli_endpoint_retrieve_by_id(const char *id)
{
- struct ast_sip_cli_formatter_entry *formatter_entry;
+ return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
+}
+
+static void cli_endpoint_print_child_header(char *type, struct ast_sip_cli_context *context)
+{
+ RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);
formatter_entry = ast_sip_lookup_cli_formatter(type);
- if (formatter_entry && formatter_entry->print_header) {
+ if (formatter_entry) {
formatter_entry->print_header(NULL, context, 0);
}
}
-static int cli_print_endpoint_header(void *obj, void *arg, int flags)
+static int cli_endpoint_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
+
ast_str_append(&context->output_buffer, 0,
" Endpoint: <Endpoint/CID.....................................> <State.....> <Channels.>\n");
if (context->recurse) {
context->indent_level++;
- print_child_header("auth", context);
- print_child_header("aor", context);
- print_child_header("transport", context);
- print_child_header("identify", context);
- print_child_header("channel", context);
+ cli_endpoint_print_child_header("auth", context);
+ cli_endpoint_print_child_header("aor", context);
+ cli_endpoint_print_child_header("transport", context);
+ cli_endpoint_print_child_header("identify", context);
+ cli_endpoint_print_child_header("channel", context);
context->indent_level--;
}
+
return 0;
}
-static void print_child_body(char *type, const void *obj, struct ast_sip_cli_context *context)
+static void cli_endpoint_print_child_body(char *type, const void *obj, struct ast_sip_cli_context *context)
{
- struct ast_sip_cli_formatter_entry *formatter_entry;
+ RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);
formatter_entry = ast_sip_lookup_cli_formatter(type);
- if (formatter_entry && formatter_entry->print_body && formatter_entry->iterator) {
- formatter_entry->iterator(obj, formatter_entry->print_body, context);
+ if (formatter_entry) {
+ formatter_entry->iterate((void *)obj, formatter_entry->print_body, context);
}
}
-static int cli_print_endpoint_body(void *obj, void *arg, int flags)
+static int cli_endpoint_print_body(void *obj, void *arg, int flags)
{
struct ast_sip_endpoint *endpoint = obj;
RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, ast_sip_get_endpoint_snapshot(endpoint), ao2_cleanup);
@@ -1438,11 +1516,7 @@ static int cli_print_endpoint_body(void *obj, void *arg, int flags)
int indent;
int flexwidth;
- if (!context->output_buffer) {
- return -1;
- }
-
- context->current_endpoint = endpoint;
+ ast_assert(context->output_buffer != NULL);
if (number) {
print_name_len = strlen(id) + strlen(number) + 2;
@@ -1468,14 +1542,14 @@ static int cli_print_endpoint_body(void *obj, void *arg, int flags)
context->indent_level++;
context->auth_direction = "Out";
- print_child_body("auth", &endpoint->outbound_auths, context);
+ cli_endpoint_print_child_body("auth", &endpoint->outbound_auths, context);
context->auth_direction = "In";
- print_child_body("auth", &endpoint->inbound_auths, context);
+ cli_endpoint_print_child_body("auth", &endpoint->inbound_auths, context);
- print_child_body("aor", endpoint->aors, context);
- print_child_body("transport", endpoint, context);
- print_child_body("identify", endpoint, context);
- print_child_body("channel", endpoint, context);
+ cli_endpoint_print_child_body("aor", endpoint->aors, context);
+ cli_endpoint_print_child_body("transport", endpoint, context);
+ cli_endpoint_print_child_body("identify", endpoint, context);
+ cli_endpoint_print_child_body("channel", endpoint, context);
context->indent_level--;
@@ -1492,24 +1566,6 @@ static int cli_print_endpoint_body(void *obj, void *arg, int flags)
return 0;
}
-static struct ast_sip_cli_formatter_entry cli_channel_formatter = {
- .name = "channel",
- .print_header = cli_print_channel_header,
- .print_body = cli_print_channel_body,
- .get_container = cli_get_channel_container,
- .iterator = cli_channel_iterator,
- .comparator = cli_channel_compare,
-};
-
-static struct ast_sip_cli_formatter_entry cli_endpoint_formatter = {
- .name = "endpoint",
- .print_header = cli_print_endpoint_header,
- .print_body = cli_print_endpoint_body,
- .get_container = cli_get_endpoint_container,
- .iterator = cli_endpoint_iterator,
- .comparator = ast_sorcery_object_id_compare,
-};
-
static struct ast_cli_entry cli_commands[] = {
AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Channels",
.command = "pjsip list channels",
@@ -1519,6 +1575,10 @@ static struct ast_cli_entry cli_commands[] = {
.command = "pjsip show channels",
.usage = "Usage: pjsip show channels\n"
" List(detailed) the active PJSIP channels\n"),
+ AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Channel",
+ .command = "pjsip show channel",
+ .usage = "Usage: pjsip show channel\n"
+ " List(detailed) the active PJSIP channel\n"),
AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Endpoints",
.command = "pjsip list endpoints",
@@ -1534,9 +1594,11 @@ static struct ast_cli_entry cli_commands[] = {
" Show the configured PJSIP endpoint\n"),
};
+struct ast_sip_cli_formatter_entry *channel_formatter;
+struct ast_sip_cli_formatter_entry *endpoint_formatter;
+
int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_module_info)
{
-
if (ast_manager_register_xml(AMI_SHOW_ENDPOINTS, EVENT_FLAG_SYSTEM, ami_show_endpoints) ||
ast_manager_register_xml(AMI_SHOW_ENDPOINT, EVENT_FLAG_SYSTEM, ami_show_endpoint)) {
return -1;
@@ -1563,7 +1625,6 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
}
ast_sorcery_apply_default(sip_sorcery, "endpoint", "config", "pjsip.conf,criteria=type=endpoint");
-
ast_sorcery_apply_default(sip_sorcery, "nat_hook", "memory", NULL);
if (ast_sorcery_object_register(sip_sorcery, "endpoint", ast_sip_endpoint_alloc, NULL, sip_endpoint_apply_handler)) {
@@ -1694,8 +1755,38 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
return -1;
}
- ast_sip_register_cli_formatter(&cli_channel_formatter);
- ast_sip_register_cli_formatter(&cli_endpoint_formatter);
+ channel_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!channel_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for channel_formatter\n");
+ ast_sorcery_unref(sip_sorcery);
+ sip_sorcery = NULL;
+ return -1;
+ }
+ channel_formatter->name = "channel";
+ channel_formatter->print_header = cli_channel_print_header;
+ channel_formatter->print_body = cli_channel_print_body;
+ channel_formatter->get_container = cli_channel_get_container;
+ channel_formatter->iterate = cli_channel_iterate;
+ channel_formatter->retrieve_by_id = cli_channel_retrieve_by_id;
+ channel_formatter->get_id = cli_channel_get_id;
+
+ endpoint_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!endpoint_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for endpoint_formatter\n");
+ ast_sorcery_unref(sip_sorcery);
+ sip_sorcery = NULL;
+ return -1;
+ }
+ endpoint_formatter->name = "endpoint";
+ endpoint_formatter->print_header = cli_endpoint_print_header;
+ endpoint_formatter->print_body = cli_endpoint_print_body;
+ endpoint_formatter->get_container = cli_endpoint_get_container;
+ endpoint_formatter->iterate = cli_endpoint_iterate;
+ endpoint_formatter->retrieve_by_id = cli_endpoint_retrieve_by_id;
+ endpoint_formatter->get_id = ast_sorcery_object_get_id;
+
+ ast_sip_register_cli_formatter(channel_formatter);
+ ast_sip_register_cli_formatter(endpoint_formatter);
ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
ast_sorcery_load(sip_sorcery);
@@ -1705,12 +1796,14 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
void ast_res_pjsip_destroy_configuration(void)
{
- ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
ast_sip_destroy_sorcery_location();
ast_sip_destroy_sorcery_auth();
ast_sip_destroy_sorcery_transport();
ast_manager_unregister(AMI_SHOW_ENDPOINT);
ast_manager_unregister(AMI_SHOW_ENDPOINTS);
+ ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
+ ast_sip_unregister_cli_formatter(endpoint_formatter);
+ ast_sip_unregister_cli_formatter(channel_formatter);
ast_sorcery_unref(sip_sorcery);
}
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index 414f430a2..cc9bc3534 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -270,16 +270,14 @@ struct ast_sip_endpoint_formatter endpoint_identify_formatter = {
.format_ami = format_ami_endpoint_identify
};
-static int populate_identify_container(void *obj, void *arg, int flags)
+static int cli_populate_container(void *obj, void *arg, int flags)
{
- struct ast_sip_ip_identify_match *ident = obj;
- struct ao2_container *container = arg;
+ ao2_link(arg, obj);
- ao2_link(container, ident);
return 0;
}
-static int cli_iterator(const void *container, ao2_callback_fn callback, void *args)
+static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
{
const struct ast_sip_endpoint *endpoint = container;
struct ao2_container *identifies;
@@ -301,16 +299,17 @@ static int cli_iterator(const void *container, ao2_callback_fn callback, void *a
return 0;
}
-static int gather_endpoint_identifies(void *obj, void *arg, int flags)
+static int cli_endpoint_gather_identifies(void *obj, void *arg, int flags)
{
struct ast_sip_endpoint *endpoint = obj;
struct ao2_container *container = arg;
- cli_iterator(endpoint, populate_identify_container, container);
+ cli_iterator(endpoint, cli_populate_container, container);
+
return 0;
}
-static struct ao2_container *cli_get_identify_container(void)
+static struct ao2_container *cli_get_container(void)
{
RAII_VAR(struct ao2_container *, parent_container, NULL, ao2_cleanup);
RAII_VAR(struct ao2_container *, s_parent_container, NULL, ao2_cleanup);
@@ -323,7 +322,7 @@ static struct ao2_container *cli_get_identify_container(void)
}
s_parent_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
if (!s_parent_container) {
return NULL;
}
@@ -333,26 +332,28 @@ static struct ao2_container *cli_get_identify_container(void)
}
child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
if (!child_container) {
return NULL;
}
- ao2_callback(s_parent_container, OBJ_NODATA, gather_endpoint_identifies, child_container);
- ao2_ref(child_container, +1);
+ ao2_callback(s_parent_container, OBJ_NODATA, cli_endpoint_gather_identifies, child_container);
+
return child_container;
}
+static void *cli_retrieve_by_id(const char *id)
+{
+ return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "identify", id);
+}
-static int cli_print_identify_header(void *obj, void *arg, int flags)
+static int cli_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
int indent = CLI_INDENT_TO_SPACES(context->indent_level);
int filler = CLI_MAX_WIDTH - indent - 14;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
ast_str_append(&context->output_buffer, 0,
"%*s: <MatchList%*.*s>\n",
@@ -361,15 +362,13 @@ static int cli_print_identify_header(void *obj, void *arg, int flags)
return 0;
}
-static int cli_print_identify_body(void *obj, void *arg, int flags)
+static int cli_print_body(void *obj, void *arg, int flags)
{
RAII_VAR(struct ast_str *, str, ast_str_create(MAX_OBJECT_FIELD), ast_free);
struct ip_identify_match *ident = obj;
struct ast_sip_cli_context *context = arg;
- if (!context->output_buffer || !str) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
ast_str_append(&context->output_buffer, 0, "%*s: ",
CLI_INDENT_TO_SPACES(context->indent_level), "Identify");
@@ -379,14 +378,7 @@ static int cli_print_identify_body(void *obj, void *arg, int flags)
return 0;
}
-static struct ast_sip_cli_formatter_entry cli_identify_formatter = {
- .name = "identify",
- .print_header = cli_print_identify_header,
- .print_body = cli_print_identify_body,
- .get_container = cli_get_identify_container,
- .comparator = ast_sorcery_object_id_compare,
- .iterator = cli_iterator,
-};
+static struct ast_sip_cli_formatter_entry *cli_formatter;
static int load_module(void)
{
@@ -403,7 +395,21 @@ static int load_module(void)
ast_sip_register_endpoint_identifier(&ip_identifier);
ast_sip_register_endpoint_formatter(&endpoint_identify_formatter);
- ast_sip_register_cli_formatter(&cli_identify_formatter);
+
+ cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!cli_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
+ return -1;
+ }
+ cli_formatter->name = "identify";
+ cli_formatter->print_header = cli_print_header;
+ cli_formatter->print_body = cli_print_body;
+ cli_formatter->get_container = cli_get_container;
+ cli_formatter->iterate = cli_iterator;
+ cli_formatter->get_id = ast_sorcery_object_get_id;
+ cli_formatter->retrieve_by_id = cli_retrieve_by_id;
+
+ ast_sip_register_cli_formatter(cli_formatter);
return AST_MODULE_LOAD_SUCCESS;
}
@@ -411,14 +417,16 @@ static int load_module(void)
static int reload_module(void)
{
ast_sorcery_reload_object(ast_sip_get_sorcery(), "identify");
+
return 0;
}
static int unload_module(void)
{
- ast_sip_unregister_cli_formatter(&cli_identify_formatter);
+ ast_sip_unregister_cli_formatter(cli_formatter);
ast_sip_unregister_endpoint_formatter(&endpoint_identify_formatter);
ast_sip_unregister_endpoint_identifier(&ip_identifier);
+
return 0;
}
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 019ac51cd..b35e27eb8 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -1132,7 +1132,7 @@ static int ami_show_outbound_registrations(struct mansession *s,
static struct ao2_container *cli_get_container(void)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, s_container, NULL, ao2_cleanup);
+ struct ao2_container *s_container;
container = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration",
AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
@@ -1141,33 +1141,36 @@ static struct ao2_container *cli_get_container(void)
}
s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
- ast_sorcery_object_id_compare, NULL);
+ ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
if (!s_container) {
return NULL;
}
if (ao2_container_dup(s_container, container, 0)) {
+ ao2_ref(s_container, -1);
return NULL;
}
- ao2_ref(s_container, +1);
+
return s_container;
}
-static int cli_iterator(const void *container, ao2_callback_fn callback, void *args)
+static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
{
- struct ao2_container *ao2container = (struct ao2_container *) container;
+ ao2_callback(container, OBJ_NODATA, callback, args);
- ao2_callback(ao2container, OBJ_NODATA, callback, args);
return 0;
}
+static void *cli_retrieve_by_id(const char *id)
+{
+ return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration", id);
+}
+
static int cli_print_header(void *obj, void *arg, int flags)
{
struct ast_sip_cli_context *context = arg;
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
ast_str_append(&context->output_buffer, 0,
" <Registration/ServerURI..............................> <Auth..........> <Status.......>\n");
@@ -1182,9 +1185,7 @@ static int cli_print_body(void *obj, void *arg, int flags)
const char *id = ast_sorcery_object_get_id(registration);
#define REGISTRATION_URI_FIELD_LEN 53
- if (!context->output_buffer) {
- return -1;
- }
+ ast_assert(context->output_buffer != NULL);
ast_str_append(&context->output_buffer, 0, " %-s/%-*.*s %-16s %-16s\n",
id,
@@ -1205,15 +1206,6 @@ static int cli_print_body(void *obj, void *arg, int flags)
return 0;
}
-static struct ast_sip_cli_formatter_entry cli_formatter = {
- .name = "registration",
- .print_header = cli_print_header,
- .print_body = cli_print_body,
- .get_container = cli_get_container,
- .iterator = cli_iterator,
- .comparator = ast_sorcery_object_id_compare,
-};
-
/*
* A function pointer to callback needs to be within the
* module in order to avoid problems with an undefined
@@ -1240,6 +1232,8 @@ static struct ast_cli_entry cli_outbound_registration[] = {
" Show the configured PJSIP Registration\n"),
};
+static struct ast_sip_cli_formatter_entry *cli_formatter;
+
static int load_module(void)
{
ast_sorcery_apply_default(ast_sip_get_sorcery(), "registration", "config", "pjsip.conf,criteria=type=registration");
@@ -1264,10 +1258,24 @@ static int load_module(void)
ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
sip_outbound_registration_perform_all();
- ast_cli_register_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING,ami_show_outbound_registrations);
- ast_sip_register_cli_formatter(&cli_formatter);
+
+ cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
+ if (!cli_formatter) {
+ ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
+ return -1;
+ }
+ cli_formatter->name = "registration";
+ cli_formatter->print_header = cli_print_header;
+ cli_formatter->print_body = cli_print_body;
+ cli_formatter->get_container = cli_get_container;
+ cli_formatter->iterate = cli_iterator;
+ cli_formatter->get_id = ast_sorcery_object_get_id;
+ cli_formatter->retrieve_by_id = cli_retrieve_by_id;
+
+ ast_sip_register_cli_formatter(cli_formatter);
+ ast_cli_register_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
return AST_MODULE_LOAD_SUCCESS;
}
@@ -1281,10 +1289,11 @@ static int reload_module(void)
static int unload_module(void)
{
- ast_sip_unregister_cli_formatter(&cli_formatter);
ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
+ ast_sip_unregister_cli_formatter(cli_formatter);
ast_manager_unregister("PJSIPShowRegistrationsOutbound");
ast_manager_unregister("PJSIPUnregister");
+
return 0;
}