[Asterisk-code-review] res pjsip: Add "like" processing to pjsip list and show com... (asterisk[master])

George Joseph asteriskteam at digium.com
Wed Oct 21 12:49:50 CDT 2015


George Joseph has uploaded a new change for review.

  https://gerrit.asterisk.org/1476

Change subject: res_pjsip:  Add "like" processing to pjsip list and show commands
......................................................................

res_pjsip:  Add "like" processing to pjsip list and show commands

Add the ability to filter output from pjsip list and show commands
using the "like" predicate like chan_sip.

For endpoints, aors, auths, registrations, identifyies and transports,
the modification was a simple change of an ast_sorcery_retrieve_by_fields
call to ast_sorcery_retrieve_by_regex.  For channels and contacts a
little more work had to be done because neither of those objects are
true sorcery objects.  That was just removing the non-matching object
from the final container.  Of course, a little extra plumbing in the
common pjsip_cli code was needed to parse the "like" and pass the regex
to the get_container callbacks.

Some of the get_container code in res_pjsip_endpoint_identifier was also
refactored for simplicity.

ASTERISK-25477 #close
Reported by: Bryant Zimmerman
Tested by: George Joseph

Change-Id: I646d9326b778aac26bb3e2bcd7fa1346d24434f1
---
M CHANGES
M include/asterisk/res_pjsip_cli.h
M res/res_pjsip/config_auth.c
M res/res_pjsip/config_transport.c
M res/res_pjsip/location.c
M res/res_pjsip/pjsip_cli.c
M res/res_pjsip/pjsip_configuration.c
M res/res_pjsip_endpoint_identifier_ip.c
M res/res_pjsip_outbound_registration.c
9 files changed, 145 insertions(+), 90 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/76/1476/1

diff --git a/CHANGES b/CHANGES
index 88743cc..c2247a4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -184,6 +184,14 @@
    names. This setting is configurable for cdr_adaptive_odbc via the
    quoted_identifiers in configuration file cdr_adaptive_odbc.conf.
 
+------------------------------------------------------------------------------
+--- Functionality changes from Asterisk 13.6.0 to Asterisk 13.7.0 ------------
+------------------------------------------------------------------------------
+
+res_pjsip
+------------------
+ * The ability to use "like" has been added to the pjsip list and show
+   CLI commands.  For instance: CLI> pjsip list endpoints like abc
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.5.0 to Asterisk 13.6.0 ------------
diff --git a/include/asterisk/res_pjsip_cli.h b/include/asterisk/res_pjsip_cli.h
index 44979b7..c253521 100644
--- a/include/asterisk/res_pjsip_cli.h
+++ b/include/asterisk/res_pjsip_cli.h
@@ -61,7 +61,7 @@
 	/*! The callback used to print the details of the object. */
 	ao2_callback_fn *print_body;
 	/*! The function used to retrieve a container of all objects of this type. */
-	struct ao2_container *(* get_container)(void);
+	struct ao2_container *(* get_container)(const char *regex);
 	/*! The function used to iterate over a container of objects. */
 	int (* iterate)(void *container, ao2_callback_fn callback, void *args);
 	/*! The function used to retrieve a specific object from it's container. */
diff --git a/res/res_pjsip/config_auth.c b/res/res_pjsip/config_auth.c
index 773889c..9160e67 100644
--- a/res/res_pjsip/config_auth.c
+++ b/res/res_pjsip/config_auth.c
@@ -195,13 +195,12 @@
 	.format_ami = format_ami_endpoint_auth
 };
 
-static struct ao2_container *cli_get_container(void)
+static struct ao2_container *cli_get_container(const char *regex)
 {
 	RAII_VAR(struct ao2_container *, 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);
+	container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "auth", regex);
 	if (!container) {
 		return NULL;
 	}
@@ -272,12 +271,14 @@
 static struct ast_cli_entry cli_commands[] = {
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Auths",
 		.command = "pjsip list auths",
-		.usage = "Usage: pjsip list auths\n"
-				 "       List the configured PJSIP Auths\n"),
+		.usage = "Usage: pjsip list auths [ like <pattern> ]\n"
+				"       List the configured PJSIP Auths\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Auths",
 		.command = "pjsip show auths",
-		.usage = "Usage: pjsip show auths\n"
-				 "       Show the configured PJSIP Auths\n"),
+		.usage = "Usage: pjsip show auths [ like <pattern> ]\n"
+				"       Show the configured PJSIP Auths\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Auth",
 		.command = "pjsip show auth",
 		.usage = "Usage: pjsip show auth <id>\n"
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index 73030b1..e998661 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -633,13 +633,13 @@
 	return 0;
 }
 
-static struct ao2_container *cli_get_container(void)
+static struct ao2_container *cli_get_container(const char *regex)
 {
 	RAII_VAR(struct ao2_container *, 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);
+	container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "transport",
+		regex);
 	if (!container) {
 		return NULL;
 	}
@@ -720,12 +720,14 @@
 	AST_CLI_DEFINE(handle_pjsip_list_ciphers, "List available OpenSSL cipher names"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Transports",
 		.command = "pjsip list transports",
-		.usage = "Usage: pjsip list transports\n"
-				 "       List the configured PJSIP Transports\n"),
+		.usage = "Usage: pjsip list transports [ like <pattern> ]\n"
+				"       List the configured PJSIP Transports\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Transports",
 		.command = "pjsip show transports",
-		.usage = "Usage: pjsip show transports\n"
-				 "       Show the configured PJSIP Transport\n"),
+		.usage = "Usage: pjsip show transports [ like <pattern> ]\n"
+				"       Show the configured PJSIP Transport\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Transport",
 		.command = "pjsip show transport",
 		.usage = "Usage: pjsip show transport <id>\n"
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index 9625f04..36e2cee 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -626,13 +626,12 @@
 	.format_ami = format_ami_endpoint_aor
 };
 
-static struct ao2_container *cli_aor_get_container(void)
+static struct ao2_container *cli_aor_get_container(const char *regex)
 {
 	RAII_VAR(struct ao2_container *, 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);
+	container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "aor", regex);
 	if (!container) {
 		return NULL;
 	}
@@ -730,12 +729,25 @@
 	return ast_sip_for_each_contact(container, callback, args);
 }
 
-static struct ao2_container *cli_contact_get_container(void)
+static int cli_filter_contacts(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact_wrapper *wrapper = obj;
+	regex_t *regexbuf = arg;
+
+	if (!regexec(regexbuf, wrapper->contact_id, 0, NULL, 0)) {
+		return 0;
+	}
+
+	return CMP_MATCH;
+}
+
+static struct ao2_container *cli_contact_get_container(const char *regex)
 {
 	RAII_VAR(struct ao2_container *, parent_container, NULL, ao2_cleanup);
 	struct ao2_container *child_container;
+	regex_t regexbuf;
 
-	parent_container =  cli_aor_get_container();
+	parent_container =  cli_aor_get_container("");
 	if (!parent_container) {
 		return NULL;
 	}
@@ -748,12 +760,23 @@
 
 	ao2_callback(parent_container, OBJ_NODATA, cli_aor_gather_contacts, child_container);
 
+	if (!ast_strlen_zero(regex)) {
+		if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
+			ao2_ref(child_container, -1);
+			return NULL;
+		}
+		ao2_callback(child_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_contacts, &regexbuf);
+		regfree(&regexbuf);
+	}
+
 	return child_container;
 }
 
 static void *cli_contact_retrieve_by_id(const char *id)
 {
-	return ao2_find(cli_contact_get_container(), id, OBJ_KEY | OBJ_NOLOCK);
+	RAII_VAR(struct ao2_container *, container, cli_contact_get_container(""), ao2_cleanup);
+
+	return ao2_find(container, id, OBJ_KEY | OBJ_NOLOCK);
 }
 
 static int cli_contact_print_header(void *obj, void *arg, int flags)
@@ -890,12 +913,14 @@
 static struct ast_cli_entry cli_commands[] = {
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Aors",
 		.command = "pjsip list aors",
-		.usage = "Usage: pjsip list aors\n"
-				 "       List the configured PJSIP Aors\n"),
+		.usage = "Usage: pjsip list aors [ like <pattern> ]\n"
+				"       List the configured PJSIP Aors\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Aors",
 		.command = "pjsip show aors",
-		.usage = "Usage: pjsip show aors\n"
-				 "       Show the configured PJSIP Aors\n"),
+		.usage = "Usage: pjsip show aors [ like <pattern> ]\n"
+				"       Show the configured PJSIP Aors\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Aor",
 		.command = "pjsip show aor",
 		.usage = "Usage: pjsip show aor <id>\n"
@@ -903,12 +928,14 @@
 
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Contacts",
 		.command = "pjsip list contacts",
-		.usage = "Usage: pjsip list contacts\n"
-				 "       List the configured PJSIP contacts\n"),
+		.usage = "Usage: pjsip list contacts [ like <pattern> ]\n"
+				"       List the configured PJSIP contacts\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Contacts",
 		.command = "pjsip show contacts",
-		.usage = "Usage: pjsip show contacts\n"
-				 "       Show the configured PJSIP contacts\n"),
+		.usage = "Usage: pjsip show contacts [ like <pattern> ]\n"
+				"       Show the configured PJSIP contacts\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Contact",
 		.command = "pjsip show contact",
 		.usage = "Usage: pjsip show contact\n"
diff --git a/res/res_pjsip/pjsip_cli.c b/res/res_pjsip/pjsip_cli.c
index 16df3f5..bbd0ac4 100644
--- a/res/res_pjsip/pjsip_cli.c
+++ b/res/res_pjsip/pjsip_cli.c
@@ -125,6 +125,7 @@
 	const char *cmd2;
 	const char *object_id;
 	char formatter_type[64];
+	const char *regex;
 
 	struct ast_sip_cli_context context = {
 		.indent_level = 0,
@@ -162,6 +163,18 @@
 		is_container = 1;
 	}
 
+	if (cmd != CLI_GENERATE
+		&& is_container
+		&& a->argc >= 4
+		&& strcmp(object_id, "like") == 0) {
+		if (ast_strlen_zero(a->argv[4])) {
+			return CLI_SHOWUSAGE;
+		}
+		regex = a->argv[4];
+	} else {
+		regex = "";
+	}
+
 	if (cmd == CLI_GENERATE
 		&& (is_container
 			|| a->argc > 4
@@ -187,7 +200,7 @@
 		" =========================================================================================\n\n");
 
 	if (is_container || cmd == CLI_GENERATE) {
-		container = formatter_entry->get_container();
+		container = formatter_entry->get_container(regex);
 		if (!container) {
 			ast_cli(a->fd, "No container returned for object type %s.\n",
 				formatter_type);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index cfb17cd..ff72fc2 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1423,13 +1423,12 @@
 	return 0;
 }
 
-static struct ao2_container *cli_endpoint_get_container(void)
+static struct ao2_container *cli_endpoint_get_container(const char *regex)
 {
 	RAII_VAR(struct ao2_container *, 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);
+	container = ast_sorcery_retrieve_by_regex(sip_sorcery, "endpoint", regex);
 	if (!container) {
 		return NULL;
 	}
@@ -1543,12 +1542,26 @@
 	return 0;
 }
 
-static struct ao2_container *cli_channel_get_container(void)
+static int cli_filter_channels(void *obj, void *arg, int flags)
+{
+	struct ast_channel_snapshot *channel = obj;
+	regex_t *regexbuf = arg;
+
+	if (!regexec(regexbuf, channel->name, 0, NULL, 0)
+		|| !regexec(regexbuf, channel->appl, 0, NULL, 0)) {
+		return 0;
+	}
+
+	return CMP_MATCH;
+}
+
+static struct ao2_container *cli_channel_get_container(const char *regex)
 {
 	RAII_VAR(struct ao2_container *, parent_container, NULL, ao2_cleanup);
 	struct ao2_container *child_container;
+	regex_t regexbuf;
 
-	parent_container = cli_endpoint_get_container();
+	parent_container = cli_endpoint_get_container("");
 	if (!parent_container) {
 		return NULL;
 	}
@@ -1559,6 +1572,15 @@
 	}
 
 	ao2_callback(parent_container, OBJ_NODATA, cli_endpoint_gather_channels, child_container);
+
+	if (!ast_strlen_zero(regex)) {
+		if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
+			ao2_ref(child_container, -1);
+			return NULL;
+		}
+		ao2_callback(child_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_channels, &regexbuf);
+		regfree(&regexbuf);
+	}
 
 	return child_container;
 }
@@ -1572,7 +1594,7 @@
 
 static void *cli_channel_retrieve_by_id(const char *id)
 {
-	RAII_VAR(struct ao2_container *, container, cli_channel_get_container(), ao2_cleanup);
+	RAII_VAR(struct ao2_container *, container, cli_channel_get_container(""), ao2_cleanup);
 
 	return ao2_find(container, id, OBJ_KEY | OBJ_NOLOCK);
 }
@@ -1774,12 +1796,14 @@
 static struct ast_cli_entry cli_commands[] = {
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Channels",
 		.command = "pjsip list channels",
-		.usage = "Usage: pjsip list channels\n"
-				 "       List the active PJSIP channels\n"),
+		.usage = "Usage: pjsip list channels [ like <pattern> ]\n"
+				"       List the active PJSIP channels\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Channels",
 		.command = "pjsip show channels",
-		.usage = "Usage: pjsip show channels\n"
-				 "       List(detailed) the active PJSIP channels\n"),
+		.usage = "Usage: pjsip show channels [ like <pattern> ]\n"
+				"       List(detailed) the active PJSIP channels\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Channel",
 		.command = "pjsip show channel",
 		.usage = "Usage: pjsip show channel\n"
@@ -1787,12 +1811,14 @@
 
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Endpoints",
 		.command = "pjsip list endpoints",
-		.usage = "Usage: pjsip list endpoints\n"
-				 "       List the configured PJSIP endpoints\n"),
+		.usage = "Usage: pjsip list endpoints [ like <pattern> ]\n"
+				"       List the configured PJSIP endpoints\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Endpoints",
 		.command = "pjsip show endpoints",
-		.usage = "Usage: pjsip show endpoints\n"
-				 "       List(detailed) the configured PJSIP endpoints\n"),
+		.usage = "Usage: pjsip show endpoints [ like <pattern> ]\n"
+				"       List(detailed) the configured PJSIP endpoints\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Endpoint",
 		.command = "pjsip show endpoint",
 		.usage = "Usage: pjsip show endpoint <id>\n"
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index bbf3407..154d7ea 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -298,13 +298,6 @@
 	.format_ami = format_ami_endpoint_identify
 };
 
-static int cli_populate_container(void *obj, void *arg, int flags)
-{
-	ao2_link(arg, obj);
-
-	return 0;
-}
-
 static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
 {
 	const struct ast_sip_endpoint *endpoint = container;
@@ -328,47 +321,27 @@
 	return 0;
 }
 
-static int cli_endpoint_gather_identifies(void *obj, void *arg, int flags)
+static struct ao2_container *cli_get_container(const char *regex)
 {
-	struct ast_sip_endpoint *endpoint = obj;
-	struct ao2_container *container = arg;
+	RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
+	struct ao2_container *s_container;
 
-	cli_iterator(endpoint, cli_populate_container, container);
-
-	return 0;
-}
-
-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);
-	struct ao2_container *child_container;
-
-	parent_container =  ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "endpoint",
-		AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
-	if (!parent_container) {
+	container =  ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "identify", regex);
+	if (!container) {
 		return NULL;
 	}
 
-	s_parent_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
+	s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
 		ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
-	if (!s_parent_container) {
+	if (!s_container) {
 		return NULL;
 	}
 
-	if (ao2_container_dup(s_parent_container, parent_container, 0)) {
+	if (ao2_container_dup(s_container, container, 0)) {
 		return NULL;
 	}
 
-	child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
-		ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
-	if (!child_container) {
-		return NULL;
-	}
-
-	ao2_callback(s_parent_container, OBJ_NODATA, cli_endpoint_gather_identifies, child_container);
-
-	return child_container;
+	return s_container;
 }
 
 static void *cli_retrieve_by_id(const char *id)
@@ -461,12 +434,14 @@
 static struct ast_cli_entry cli_identify[] = {
 AST_CLI_DEFINE(my_cli_traverse_objects, "List PJSIP Identifies",
 	.command = "pjsip list identifies",
-	.usage = "Usage: pjsip list identifies\n"
-	"       List the configured PJSIP Identifies\n"),
+	.usage = "Usage: pjsip list identifies [ like <pattern> ]\n"
+	"       List the configured PJSIP Identifies\n"
+	"       Optional regular expression pattern is used to filter the list.\n"),
 AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Identifies",
 	.command = "pjsip show identifies",
-	.usage = "Usage: pjsip show identifies\n"
-	"       Show the configured PJSIP Identifies\n"),
+	.usage = "Usage: pjsip show identifies [ like <pattern> ]\n"
+	"       Show the configured PJSIP Identifies\n"
+	"       Optional regular expression pattern is used to filter the list.\n"),
 AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Identify",
 	.command = "pjsip show identify",
 	.usage = "Usage: pjsip show identify <id>\n"
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 6bdba56..b0ff558 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -1611,11 +1611,12 @@
 	return 0;
 }
 
-static struct ao2_container *cli_get_container(void)
+static struct ao2_container *cli_get_container(const char *regex)
 {
-	RAII_VAR(struct ao2_container *, container, get_registrations(), ao2_cleanup);
+	RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
 	struct ao2_container *s_container;
 
+	container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "registration", regex);
 	if (!container) {
 		return NULL;
 	}
@@ -1719,12 +1720,14 @@
 	AST_CLI_DEFINE(cli_register, "Registers an outbound registration target"),
 	AST_CLI_DEFINE(my_cli_traverse_objects, "List PJSIP Registrations",
 		.command = "pjsip list registrations",
-		.usage = "Usage: pjsip list registrations\n"
-				 "       List the configured PJSIP Registrations\n"),
+		.usage = "Usage: pjsip list registrations [ like <pattern> ]\n"
+				"       List the configured PJSIP Registrations\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Registrations",
 		.command = "pjsip show registrations",
-		.usage = "Usage: pjsip show registrations\n"
-				 "       Show the configured PJSIP Registrations\n"),
+		.usage = "Usage: pjsip show registrations [ like <pattern> ]\n"
+				"       Show the configured PJSIP Registrations\n"
+				"       Optional regular expression pattern is used to filter the list.\n"),
 	AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Registration",
 		.command = "pjsip show registration",
 		.usage = "Usage: pjsip show registration <id>\n"

-- 
To view, visit https://gerrit.asterisk.org/1476
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I646d9326b778aac26bb3e2bcd7fa1346d24434f1
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <george.joseph at fairview5.com>



More information about the asterisk-code-review mailing list