summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2016-12-09 05:30:02 -0600
committerGerrit Code Review <gerrit2@gerrit.digium.api>2016-12-09 05:30:02 -0600
commitcc9b30dd27b2628da48f279eb1d7c98fffefd0e1 (patch)
treee9513e89d1d3999c9651c21fe09428fef9b7fc5d
parent5a96e1fb5e0158bf29accff11aea8afea8b40f48 (diff)
parent79b09b5f18ad3de01030d9db1f9c45e91960fd0b (diff)
Merge "res_pjsip_registrar: AMI Add RegistrationInboundContactStatuses command"
-rw-r--r--CHANGES13
-rw-r--r--include/asterisk/res_pjsip.h10
-rw-r--r--res/res_pjsip.c25
-rw-r--r--res/res_pjsip/pjsip_options.c14
-rw-r--r--res/res_pjsip_registrar.c70
5 files changed, 122 insertions, 10 deletions
diff --git a/CHANGES b/CHANGES
index df0834d11..4c3d8dbfc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -91,6 +91,19 @@ res_pjsip_outbound_registration
for internal state transitions that don't change the reported public status
state.
+res_pjsip_registrar
+------------------
+ * The PJSIPShowRegistrationInboundContactStatuses AMI command has been added
+ to return ContactStatusDetail events as opposed to
+ PJSIPShowRegistrationsInbound which just a dumps every defined AOR.
+
+res_pjsip
+------------------
+ * Six existing contact fields have been added to the end of the
+ ContactStatusDetail AMI event:
+ ID, AuthenticateQualify, OutboundProxy, Path, QualifyFrequency and
+ QualifyTimeout. Existing fields have not been disturbed.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 14.1.0 to Asterisk 14.2.0 ------------
------------------------------------------------------------------------------
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 894ea76f5..09ace0775 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -2277,6 +2277,16 @@ int ast_sip_format_endpoint_ami(struct ast_sip_endpoint *endpoint,
struct ast_sip_ami *ami, int *count);
/*!
+ * \brief Formats the contact and sends over AMI.
+ *
+ * \param obj a pointer an ast_sip_contact_wrapper structure
+ * \param arg a pointer to an ast_sip_ami structure
+ * \param flags ignored
+ * \retval 0 Success, otherwise non-zero on error
+ */
+int ast_sip_format_contact_ami(void *obj, void *arg, int flags);
+
+/*!
* \brief Format auth details for AMI.
*
* \param auths an auth array
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 8c2d37137..144621f6b 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -2102,10 +2102,31 @@
<para>Absolute time that this contact is no longer valid after</para>
</parameter>
<parameter name="ViaAddress">
- <para>IP address:port of the last Via header in REGISTER request</para>
+ <para>IP address:port of the last Via header in REGISTER request.
+ Will only appear in the event if available.</para>
</parameter>
<parameter name="CallID">
- <para>Content of the Call-ID header in REGISTER request</para>
+ <para>Content of the Call-ID header in REGISTER request.
+ Will only appear in the event if available.</para>
+ </parameter>
+ <parameter name="ID">
+ <para>The sorcery ID of the contact.</para>
+ </parameter>
+ <parameter name="AuthenticateQualify">
+ <para>A boolean indicating whether a qualify should be authenticated.</para>
+ </parameter>
+ <parameter name="OutboundProxy">
+ <para>The contact's outbound proxy.</para>
+ </parameter>
+ <parameter name="Path">
+ <para>The Path header received on the REGISTER.</para>
+ </parameter>
+ <parameter name="QualifyFrequency">
+ <para>The interval in seconds at which the contact will be qualified.</para>
+ </parameter>
+ <parameter name="QualifyTimeout">
+ <para>The elapsed time in decimal seconds after which an OPTIONS
+ message is sent before the contact is considered unavailable.</para>
</parameter>
</syntax>
</managerEventInstance>
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 09fe1559b..d2b812dfc 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -1217,7 +1217,7 @@ static void qualify_and_schedule_all(void)
}
-static int format_contact_status(void *obj, void *arg, int flags)
+int ast_sip_format_contact_ami(void *obj, void *arg, int flags)
{
struct ast_sip_contact_wrapper *wrapper = obj;
struct ast_sip_contact *contact = wrapper->contact;
@@ -1256,7 +1256,15 @@ static int format_contact_status(void *obj, void *arg, int flags)
ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt);
}
ast_str_append(&buf, 0, "EndpointName: %s\r\n",
- ast_sorcery_object_get_id(endpoint));
+ endpoint ? ast_sorcery_object_get_id(endpoint) : S_OR(contact->endpoint_name, ""));
+
+ ast_str_append(&buf, 0, "ID: %s\r\n", ast_sorcery_object_get_id(contact));
+ ast_str_append(&buf, 0, "AuthenticateQualify: %d\r\n", contact->authenticate_qualify);
+ ast_str_append(&buf, 0, "OutboundProxy: %s\r\n", contact->outbound_proxy);
+ ast_str_append(&buf, 0, "Path: %s\r\n", contact->path);
+ ast_str_append(&buf, 0, "QualifyFrequency: %u\r\n", contact->qualify_frequency);
+ ast_str_append(&buf, 0, "QualifyTimeout: %.3f\r\n", contact->qualify_timeout);
+
astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
ami->count++;
@@ -1269,7 +1277,7 @@ static int format_contact_status_for_aor(void *obj, void *arg, int flags)
{
struct ast_sip_aor *aor = obj;
- return ast_sip_for_each_contact(aor, format_contact_status, arg);
+ return ast_sip_for_each_contact(aor, ast_sip_format_contact_ami, arg);
}
static int format_ami_contact_status(const struct ast_sip_endpoint *endpoint,
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index a8d2bdc4c..2db753889 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -46,11 +46,32 @@
<syntax />
<description>
<para>
- In response <literal>InboundRegistrationDetail</literal> events showing configuration and status
- information are raised for each inbound registration object. As well as <literal>AuthDetail</literal>
- events for each associated auth object. Once all events are completed an
- <literal>InboundRegistrationDetailComplete</literal> is issued.
- </para>
+ In response, <literal>InboundRegistrationDetail</literal> events showing configuration
+ and status information are raised for all contacts, static or dynamic. Once all events
+ are completed an <literal>InboundRegistrationDetailComplete</literal> is issued.
+ </para>
+ <warning><para>
+ This command just dumps all coonfigured AORs with contacts, even if the contact
+ is a permanent one. To really get just inbound registrations, use
+ <literal>PJSIPShowRegistrationInboundContactStatuses</literal>.
+ </para>
+ </warning>
+ </description>
+ <see-also>
+ <ref type="manager" module="res_pjsip_registrar">PJSIPShowRegistrationInboundContactStatuses</ref>
+ </see-also>
+ </manager>
+ <manager name="PJSIPShowRegistrationInboundContactStatuses" language="en_US">
+ <synopsis>
+ Lists ContactStatuses for PJSIP inbound registrations.
+ </synopsis>
+ <syntax />
+ <description>
+ <para>
+ In response, <literal>ContactStatusDetail</literal> events showing status information
+ are raised for each inbound registration (dynamic contact) object. Once all events
+ are completed a <literal>ContactStatusDetailComplete</literal> event is issued.
+ </para>
</description>
</manager>
***/
@@ -785,6 +806,42 @@ static int ami_show_registrations(struct mansession *s, const struct message *m)
return 0;
}
+static int ami_show_registration_contact_statuses(struct mansession *s, const struct message *m)
+{
+ int count = 0;
+ struct ast_sip_ami ami = { .s = s, .m = m, .arg = NULL, .action_id = astman_get_header(m, "ActionID"), };
+ struct ao2_container *contacts = ast_sorcery_retrieve_by_fields(
+ ast_sip_get_sorcery(), "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+ struct ao2_iterator i;
+ struct ast_sip_contact *contact;
+
+ astman_send_listack(s, m, "Following are ContactStatusEvents for each Inbound "
+ "registration", "start");
+
+ if (contacts) {
+ i = ao2_iterator_init(contacts, 0);
+ while ((contact = ao2_iterator_next(&i))) {
+ struct ast_sip_contact_wrapper wrapper;
+
+ wrapper.aor_id = (char *)contact->aor;
+ wrapper.contact = contact;
+ wrapper.contact_id = (char *)ast_sorcery_object_get_id(contact);
+
+ ast_sip_format_contact_ami(&wrapper, &ami, 0);
+ count++;
+
+ ao2_ref(contact, -1);
+ }
+ ao2_iterator_destroy(&i);
+ ao2_ref(contacts, -1);
+ }
+
+ astman_send_list_complete_start(s, m, "ContactStatusDetailComplete", count);
+ astman_send_list_complete_end(s);
+ return 0;
+}
+
+#define AMI_SHOW_REGISTRATION_CONTACT_STATUSES "PJSIPShowRegistrationInboundContactStatuses"
#define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
static pjsip_module registrar_module = {
@@ -817,6 +874,8 @@ static int load_module(void)
ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
ami_show_registrations);
+ ast_manager_register_xml(AMI_SHOW_REGISTRATION_CONTACT_STATUSES, EVENT_FLAG_SYSTEM,
+ ami_show_registration_contact_statuses);
return AST_MODULE_LOAD_SUCCESS;
}
@@ -824,6 +883,7 @@ static int load_module(void)
static int unload_module(void)
{
ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
+ ast_manager_unregister(AMI_SHOW_REGISTRATION_CONTACT_STATUSES);
ast_sip_unregister_service(&registrar_module);
return 0;
}