summaryrefslogtreecommitdiff
path: root/res/res_pjsip/pjsip_configuration.c
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2015-10-20 15:02:30 -0600
committerGeorge Joseph <george.joseph@fairview5.com>2015-10-24 10:00:30 -0600
commit162acd45f744395c19ec5686af30d0abd61ef897 (patch)
tree66f8aea2d3c63ed344dc5f3bc7b72e038e501db7 /res/res_pjsip/pjsip_configuration.c
parentd818e6edceee45ffeeb1b536098d93d3c001aa9e (diff)
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
Diffstat (limited to 'res/res_pjsip/pjsip_configuration.c')
-rw-r--r--res/res_pjsip/pjsip_configuration.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index bcbb791e6..5d9097023 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1395,13 +1395,12 @@ static int ami_show_endpoints(struct mansession *s, const struct message *m)
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;
}
@@ -1515,12 +1514,26 @@ static int cli_endpoint_gather_channels(void *obj, void *arg, int flags)
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;
}
@@ -1532,6 +1545,15 @@ static struct ao2_container *cli_channel_get_container(void)
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;
}
@@ -1544,7 +1566,7 @@ static const char *cli_channel_get_id(const void *obj)
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);
}
@@ -1746,12 +1768,14 @@ static int cli_endpoint_print_body(void *obj, void *arg, int flags)
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"
@@ -1759,12 +1783,14 @@ static struct ast_cli_entry cli_commands[] = {
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"