summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2015-01-06 17:43:16 +0000
committerGeorge Joseph <george.joseph@fairview5.com>2015-01-06 17:43:16 +0000
commitfb3c8e342463afc645c87d5ca2b98adafea2b31e (patch)
treefb66dac48726f7687f151cec028c21f9278c3e89
parent7dc0c88fc62ca0e1791b68363f6221af66de43e5 (diff)
outbound_registration: Add 'pjsip send register' and update 'send unregister'
The current behavior of 'pjsip send unregister' is to send the unregister (REGISTER with 0 exp) but let the next scheduled register proceed normally. I don't think that's a good idea. If you unregister, it should stay unregistered until you decide to start registrations again. So this patch just adds a cancel_registration call to the current unregister_task to cancel the timer. Of course, now you need a way to start registration again so I've added a 'pjsip send register' command that unregisters and cancels any existing registration (the same as send unregister), then sends an immediate registration and starts the timer back up again. Both changes also ripple to AMI. There's a new PJSIPRegister command. There's no harm in calling either command repeatedly. They don't care about the actual state. Tested-by: George Joseph Review: https://reviewboard.asterisk.org/r/4301/ ........ Merged revisions 430223 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430224 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--CHANGES10
-rw-r--r--res/res_pjsip_outbound_registration.c127
2 files changed, 125 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index f4940045c..05c2f6053 100644
--- a/CHANGES
+++ b/CHANGES
@@ -102,10 +102,18 @@ res_musiconhold
* New 'PJSIP_AOR' and 'PJSIP_CONTACT' dialplan functions have been added which
allow examining PJSIP AORs or contacts from the dialplan.
+res_pjsip_outbound_registration
+------------------
+ * The 'pjsip send unregister' command now stops further registrations.
+
+ * A new command 'pjsip send register' has been added which allows you to
+ start or restart periodic registration. It can be used after a
+ 'send unregister' or after a 401 permanent error.
+
res_pjsip_config_wizard
------------------
* This is a new module that adds streamlined configuration capability for
- chan_pjsip. It's targetted at users who have lots of basic configuration
+ chan_pjsip. It's targeted at users who have lots of basic configuration
scenarios like 'phone' or 'agent' or 'trunk'. Additional information
can be found in the sample configuration file at
config/samples/pjsip_wizard.conf.sample.
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index bb9904a39..1faa93e5a 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -156,11 +156,27 @@
</syntax>
<description>
<para>
- Send a SIP REGISTER request to the specified outbound registration with an expiration of 0.
- This will cause the contact added by this registration to be removed on the remote system.
- Note: The specified outbound registration will attempt to re-register according to it's last
- registration expiration.
- </para>
+ Unregisters the specified outbound registration and stops future registration attempts.
+ Call PJSIPRegister to start registration and schedule re-registrations according to configuration.
+ </para>
+ </description>
+ </manager>
+ <manager name="PJSIPRegister" language="en_US">
+ <synopsis>
+ Register an outbound registration.
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Registration" required="true">
+ <para>The outbound registration to register.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>
+ Unregisters the specified outbound registration then starts registration and schedules re-registrations
+ according to configuration.
+ future registrations.
+ </para>
</description>
</manager>
<manager name="PJSIPShowRegistrationsOutbound" language="en_US">
@@ -1124,6 +1140,8 @@ static int unregister_task(void *obj)
struct pjsip_regc *client = state->client_state->client;
pjsip_tx_data *tdata;
+ cancel_registration(state->client_state);
+
if (pjsip_regc_unregister(client, &tdata) != PJ_SUCCESS) {
return 0;
}
@@ -1143,6 +1161,18 @@ static int queue_unregister(struct sip_outbound_registration_state *state)
ao2_ref(state, -1);
return -1;
}
+
+ return 0;
+}
+
+static int queue_register(struct sip_outbound_registration_state *state)
+{
+ ao2_ref(state, +1);
+ if (ast_sip_push_task(state->client_state->serializer, sip_outbound_registration_perform, state)) {
+ ao2_ref(state, -1);
+ return -1;
+ }
+
return 0;
}
@@ -1193,11 +1223,7 @@ static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
e->command = "pjsip send unregister";
e->usage =
"Usage: pjsip send unregister <registration>\n"
- " Send a SIP REGISTER request to the specified outbound "
- "registration with an expiration of 0. This will cause the contact "
- "added by this registration to be removed on the remote system. Note: "
- "The specified outbound registration will attempt to re-register "
- "according to its last registration expiration.\n";
+ " Unregisters the specified outbound registration and stops future registration attempts.\n";
return NULL;
case CLI_GENERATE:
return cli_complete_registration(a->line, a->word, a->pos, a->n);
@@ -1223,6 +1249,50 @@ static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
return CLI_SUCCESS;
}
+static char *cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ RAII_VAR(struct sip_outbound_registration_state *, state, NULL, ao2_cleanup);
+ const char *registration_name;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "pjsip send register";
+ e->usage =
+ "Usage: pjsip send register <registration>\n"
+ " Unregisters the specified outbound "
+ "registration then re-registers and re-schedules it.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return cli_complete_registration(a->line, a->word, a->pos, a->n);
+ }
+
+ if (a->argc != 4) {
+ return CLI_SHOWUSAGE;
+ }
+
+ registration_name = a->argv[3];
+
+ state = get_state(registration_name);
+ if (!state) {
+ ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name);
+ return CLI_FAILURE;
+ }
+
+ /* We need to serialize the unregister and register so they need
+ * to be queued as separate tasks.
+ */
+ if (queue_unregister(state)) {
+ ast_cli(a->fd, "Failed to queue unregistration");
+ return 0;
+ }
+ if (queue_register(state)) {
+ ast_cli(a->fd, "Failed to queue registration");
+ return 0;
+ }
+
+ return CLI_SUCCESS;
+}
+
static int ami_unregister(struct mansession *s, const struct message *m)
{
const char *registration_name = astman_get_header(m, "Registration");
@@ -1248,6 +1318,38 @@ static int ami_unregister(struct mansession *s, const struct message *m)
return 0;
}
+static int ami_register(struct mansession *s, const struct message *m)
+{
+ const char *registration_name = astman_get_header(m, "Registration");
+ RAII_VAR(struct sip_outbound_registration_state *, state, NULL, ao2_cleanup);
+
+ if (ast_strlen_zero(registration_name)) {
+ astman_send_error(s, m, "Registration parameter missing.");
+ return 0;
+ }
+
+ state = get_state(registration_name);
+ if (!state) {
+ astman_send_error(s, m, "Unable to retrieve registration entry\n");
+ return 0;
+ }
+
+ /* We need to serialize the unregister and register so they need
+ * to be queued as separate tasks.
+ */
+ if (queue_unregister(state)) {
+ astman_send_ack(s, m, "Failed to queue unregistration");
+ return 0;
+ }
+ if (queue_register(state)) {
+ astman_send_ack(s, m, "Failed to queue unregistration");
+ return 0;
+ }
+
+ astman_send_ack(s, m, "Reregistration sent");
+ return 0;
+}
+
struct sip_ami_outbound {
struct ast_sip_ami *ami;
int registered;
@@ -1426,7 +1528,8 @@ static char *my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct as
}
static struct ast_cli_entry cli_outbound_registration[] = {
- AST_CLI_DEFINE(cli_unregister, "Send a REGISTER request to an outbound registration target with a expiration of 0"),
+ AST_CLI_DEFINE(cli_unregister, "Unregisters outbound registration target"),
+ 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"
@@ -1450,6 +1553,7 @@ static int unload_module(void)
ast_sip_unregister_cli_formatter(cli_formatter);
ast_manager_unregister("PJSIPShowRegistrationsOutbound");
ast_manager_unregister("PJSIPUnregister");
+ ast_manager_unregister("PJSIPRegister");
ao2_global_obj_release(current_states);
@@ -1486,6 +1590,7 @@ static int load_module(void)
ast_sip_register_endpoint_identifier(&line_identifier);
ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
+ ast_manager_register_xml("PJSIPRegister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_register);
ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_show_outbound_registrations);
cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);