summaryrefslogtreecommitdiff
path: root/res/res_pjsip_outbound_registration.c
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2015-01-06 17:35:21 +0000
committerGeorge Joseph <george.joseph@fairview5.com>2015-01-06 17:35:21 +0000
commit0fa6c34dc6fb6927baf58d19cff326577745c12c (patch)
treeeb83347ec1c1add54ca9d5fa7426cdebf4f9af63 /res/res_pjsip_outbound_registration.c
parentd873b09075bbcc584b936ec1f46e0f58c7ec7279 (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/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430223 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_outbound_registration.c')
-rw-r--r--res/res_pjsip_outbound_registration.c127
1 files changed, 116 insertions, 11 deletions
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 6de264647..c643f2d9a 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -140,11 +140,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">
@@ -1043,6 +1059,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;
}
@@ -1062,6 +1080,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;
}
@@ -1112,11 +1142,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);
@@ -1142,6 +1168,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");
@@ -1167,6 +1237,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;
@@ -1345,7 +1447,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"
@@ -1368,6 +1471,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);
@@ -1401,6 +1505,7 @@ static int load_module(void)
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, support_path));
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);