]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_pjsip: Add PJSIPHangup dialplan app and manager action
authorGeorge Joseph <gjoseph@sangoma.com>
Tue, 31 Oct 2023 21:08:14 +0000 (15:08 -0600)
committerAsterisk Development Team <asteriskteam@digium.com>
Fri, 12 Jan 2024 18:32:13 +0000 (18:32 +0000)
See UserNote below.

Exposed the existing Hangup AMI action in manager.c so we can use
all of it's channel search and AMI protocol handling without
duplicating that code in dialplan_functions.c.

Added a lookup function to res_pjsip.c that takes in the
string represenation of the pjsip_status_code enum and returns
the actual status code.  I.E.  ast_sip_str2rc("DECLINE") returns
603.  This allows the caller to specify PJSIPHangup(decline) in
the dialplan, just like Hangup(call_rejected).

Also extracted the XML documentation to its own file since it was
almost as large as the code itself.

UserNote: A new dialplan app PJSIPHangup and AMI action allows you
to hang up an unanswered incoming PJSIP call with a specific SIP
response code in the 400 -> 699 range.

(cherry picked from commit af7e89ebf82f9d23e1f81c7cc6ec20b4ffdf70e6)

channels/chan_pjsip.c
channels/pjsip/dialplan_functions.c
channels/pjsip/dialplan_functions.xml [new file with mode: 0644]
channels/pjsip/include/dialplan_functions.h
include/asterisk/manager.h
include/asterisk/res_pjsip.h
main/manager.c
res/res_pjsip.c

index 8582af93ef36ebfb8baecda6f3276c714150de97..18a46ab2ddb25c1ca02048130c126d41a9c78f34 100644 (file)
@@ -3266,6 +3266,8 @@ static struct ast_custom_function session_refresh_function = {
        .write = pjsip_acf_session_refresh_write,
 };
 
+static char *app_pjsip_hangup = "PJSIPHangup";
+
 /*!
  * \brief Load the module
  *
@@ -3323,6 +3325,13 @@ static int load_module(void)
                goto end;
        }
 
+       if (ast_register_application_xml(app_pjsip_hangup, pjsip_app_hangup)) {
+               ast_log(LOG_WARNING, "Unable to register PJSIPHangup dialplan application\n");
+               goto end;
+       }
+       ast_manager_register_xml(app_pjsip_hangup, EVENT_FLAG_SYSTEM | EVENT_FLAG_CALL, pjsip_action_hangup);
+
+
        ast_sip_register_service(&refer_callback_module);
 
        ast_sip_session_register_supplement(&chan_pjsip_supplement);
@@ -3370,6 +3379,9 @@ end:
        ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
        ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
        ast_custom_function_unregister(&session_refresh_function);
+       ast_unregister_application(app_pjsip_hangup);
+       ast_manager_unregister(app_pjsip_hangup);
+
        ast_channel_unregister(&chan_pjsip_tech);
        ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
 
@@ -3399,6 +3411,8 @@ static int unload_module(void)
        ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
        ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
        ast_custom_function_unregister(&session_refresh_function);
+       ast_unregister_application(app_pjsip_hangup);
+       ast_manager_unregister(app_pjsip_hangup);
 
        ast_channel_unregister(&chan_pjsip_tech);
        ao2_ref(chan_pjsip_tech.capabilities, -1);
index 0496f048e3f93cddb221e0eae16a910d7f8193e3..f1365adba9532783a35eb6f1f6a6a115d969b73c 100644 (file)
        <support_level>core</support_level>
  ***/
 
-/*** DOCUMENTATION
-<function name="PJSIP_DIAL_CONTACTS" language="en_US">
-       <synopsis>
-               Return a dial string for dialing all contacts on an AOR.
-       </synopsis>
-       <syntax>
-               <parameter name="endpoint" required="true">
-                       <para>Name of the endpoint</para>
-               </parameter>
-               <parameter name="aor" required="false">
-                       <para>Name of an AOR to use, if not specified the configured AORs on the endpoint are used</para>
-               </parameter>
-               <parameter name="request_user" required="false">
-                       <para>Optional request user to use in the request URI</para>
-               </parameter>
-       </syntax>
-       <description>
-               <para>Returns a properly formatted dial string for dialing all contacts on an AOR.</para>
-       </description>
-</function>
-<function name="PJSIP_MEDIA_OFFER" language="en_US">
-       <synopsis>
-               Media and codec offerings to be set on an outbound SIP channel prior to dialing.
-       </synopsis>
-       <syntax>
-               <parameter name="media" required="true">
-                       <para>types of media offered</para>
-               </parameter>
-       </syntax>
-       <description>
-               <para>When read, returns the codecs offered based upon the media choice.</para>
-               <para>When written, sets the codecs to offer when an outbound dial attempt is made,
-               or when a session refresh is sent using <replaceable>PJSIP_SEND_SESSION_REFRESH</replaceable>.
-               </para>
-       </description>
-       <see-also>
-               <ref type="function">PJSIP_SEND_SESSION_REFRESH</ref>
-       </see-also>
-</function>
-<function name="PJSIP_DTMF_MODE" language="en_US">
-       <since>
-               <version>13.18.0</version>
-               <version>14.7.0</version>
-               <version>15.1.0</version>
-               <version>16.0.0</version>
-       </since>
-       <synopsis>
-               Get or change the DTMF mode for a SIP call.
-       </synopsis>
-       <syntax>
-       </syntax>
-       <description>
-               <para>When read, returns the current DTMF mode</para>
-               <para>When written, sets the current DTMF mode</para>
-               <para>This function uses the same DTMF mode naming as the dtmf_mode configuration option</para>
-       </description>
-</function>
-<function name="PJSIP_MOH_PASSTHROUGH" language="en_US">
-       <synopsis>
-               Get or change the on-hold behavior for a SIP call.
-       </synopsis>
-       <syntax>
-       </syntax>
-       <description>
-               <para>When read, returns the current moh passthrough mode</para>
-               <para>When written, sets the current moh passthrough mode</para>
-               <para>If <replaceable>yes</replaceable>, on-hold re-INVITEs are sent. If <replaceable>no</replaceable>, music on hold is generated.</para>
-               <para>This function can be used to override the moh_passthrough configuration option</para>
-       </description>
-</function>
-<function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
-       <since>
-               <version>13.12.0</version>
-               <version>14.1.0</version>
-               <version>15.0.0</version>
-       </since>
-       <synopsis>
-               W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session
-       </synopsis>
-       <syntax>
-               <parameter name="update_type" required="false">
-                       <para>The type of update to send. Default is <literal>invite</literal>.</para>
-                       <enumlist>
-                               <enum name="invite">
-                                       <para>Send the session refresh as a re-INVITE.</para>
-                               </enum>
-                               <enum name="update">
-                                       <para>Send the session refresh as an UPDATE.</para>
-                               </enum>
-                       </enumlist>
-               </parameter>
-       </syntax>
-       <description>
-               <para>This function will cause the PJSIP stack to immediately refresh
-               the media session for the channel. This will be done using either a
-               re-INVITE (default) or an UPDATE request.
-               </para>
-               <para>This is most useful when combined with the <replaceable>PJSIP_MEDIA_OFFER</replaceable>
-               dialplan function, as it allows the formats in use on a channel to be
-               re-negotiated after call setup.</para>
-               <warning>
-                       <para>The formats the endpoint supports are <emphasis>not</emphasis>
-                       checked or enforced by this function. Using this function to offer
-                       formats not supported by the endpoint <emphasis>may</emphasis> result
-                       in a loss of media.</para>
-               </warning>
-               <example title="Re-negotiate format to g722">
-                ; Within some existing extension on an answered channel
-                same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,g722)
-                same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite)
-               </example>
-       </description>
-       <see-also>
-               <ref type="function">PJSIP_MEDIA_OFFER</ref>
-       </see-also>
-</function>
-<function name="PJSIP_PARSE_URI" language="en_US">
-       <since>
-               <version>13.24.0</version>
-               <version>16.1.0</version>
-               <version>17.0.0</version>
-       </since>
-       <synopsis>
-               Parse an uri and return a type part of the URI.
-       </synopsis>
-       <syntax>
-               <parameter name="uri" required="true">
-                       <para>URI to parse</para>
-               </parameter>
-               <parameter name="type" required="true">
-                       <para>The <literal>type</literal> parameter specifies which URI part to read</para>
-                       <enumlist>
-                               <enum name="display">
-                                       <para>Display name.</para>
-                               </enum>
-                               <enum name="scheme">
-                                       <para>URI scheme.</para>
-                               </enum>
-                               <enum name="user">
-                                       <para>User part.</para>
-                               </enum>
-                               <enum name="passwd">
-                                       <para>Password part.</para>
-                               </enum>
-                               <enum name="host">
-                                       <para>Host part.</para>
-                               </enum>
-                               <enum name="port">
-                                       <para>Port number, or zero.</para>
-                               </enum>
-                               <enum name="user_param">
-                                       <para>User parameter.</para>
-                               </enum>
-                               <enum name="method_param">
-                                       <para>Method parameter.</para>
-                               </enum>
-                               <enum name="transport_param">
-                                       <para>Transport parameter.</para>
-                               </enum>
-                               <enum name="ttl_param">
-                                       <para>TTL param, or -1.</para>
-                               </enum>
-                               <enum name="lr_param">
-                                       <para>Loose routing param, or zero.</para>
-                               </enum>
-                               <enum name="maddr_param">
-                                       <para>Maddr param.</para>
-                               </enum>
-                       </enumlist>
-               </parameter>
-       </syntax>
-       <description>
-               <para>Parse an URI and return a specified part of the URI.</para>
-       </description>
-</function>
-<info name="CHANNEL" language="en_US" tech="PJSIP">
-       <enumlist>
-               <enum name="rtp">
-                       <para>R/O Retrieve media related information.</para>
-                       <parameter name="type" required="true">
-                               <para>When <replaceable>rtp</replaceable> is specified, the
-                               <literal>type</literal> parameter must be provided. It specifies
-                               which RTP parameter to read.</para>
-                               <enumlist>
-                                       <enum name="src">
-                                               <para>Retrieve the local address for RTP.</para>
-                                       </enum>
-                                       <enum name="dest">
-                                               <para>Retrieve the remote address for RTP.</para>
-                                       </enum>
-                                       <enum name="direct">
-                                               <para>If direct media is enabled, this address is the remote address
-                                               used for RTP.</para>
-                                       </enum>
-                                       <enum name="secure">
-                                               <para>Whether or not the media stream is encrypted.</para>
-                                               <enumlist>
-                                                       <enum name="0">
-                                                               <para>The media stream is not encrypted.</para>
-                                                       </enum>
-                                                       <enum name="1">
-                                                               <para>The media stream is encrypted.</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="hold">
-                                               <para>Whether or not the media stream is currently restricted
-                                               due to a call hold.</para>
-                                               <enumlist>
-                                                       <enum name="0">
-                                                               <para>The media stream is not held.</para>
-                                                       </enum>
-                                                       <enum name="1">
-                                                               <para>The media stream is held.</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                               </enumlist>
-                       </parameter>
-                       <parameter name="media_type" required="false">
-                               <para>When <replaceable>rtp</replaceable> is specified, the
-                               <literal>media_type</literal> parameter may be provided. It specifies
-                               which media stream the chosen RTP parameter should be retrieved
-                               from.</para>
-                               <enumlist>
-                                       <enum name="audio">
-                                               <para>Retrieve information from the audio media stream.</para>
-                                               <note><para>If not specified, <literal>audio</literal> is used
-                                               by default.</para></note>
-                                       </enum>
-                                       <enum name="video">
-                                               <para>Retrieve information from the video media stream.</para>
-                                       </enum>
-                               </enumlist>
-                       </parameter>
-               </enum>
-               <enum name="rtcp">
-                       <para>R/O Retrieve RTCP statistics.</para>
-                       <parameter name="statistic" required="true">
-                               <para>When <replaceable>rtcp</replaceable> is specified, the
-                               <literal>statistic</literal> parameter must be provided. It specifies
-                               which RTCP statistic parameter to read.</para>
-                               <enumlist>
-                                       <enum name="all">
-                                               <para>Retrieve a summary of all RTCP statistics.</para>
-                                               <para>The following data items are returned in a semi-colon
-                                               delineated list:</para>
-                                               <enumlist>
-                                                       <enum name="ssrc">
-                                                               <para>Our Synchronization Source identifier</para>
-                                                       </enum>
-                                                       <enum name="themssrc">
-                                                               <para>Their Synchronization Source identifier</para>
-                                                       </enum>
-                                                       <enum name="lp">
-                                                               <para>Our lost packet count</para>
-                                                       </enum>
-                                                       <enum name="rxjitter">
-                                                               <para>Received packet jitter</para>
-                                                       </enum>
-                                                       <enum name="rxcount">
-                                                               <para>Received packet count</para>
-                                                       </enum>
-                                                       <enum name="txjitter">
-                                                               <para>Transmitted packet jitter</para>
-                                                       </enum>
-                                                       <enum name="txcount">
-                                                               <para>Transmitted packet count</para>
-                                                       </enum>
-                                                       <enum name="rlp">
-                                                               <para>Remote lost packet count</para>
-                                                       </enum>
-                                                       <enum name="rtt">
-                                                               <para>Round trip time</para>
-                                                       </enum>
-                                                       <enum name="txmes">
-                                                               <para>Transmitted Media Experience Score</para>
-                                                       </enum>
-                                                       <enum name="rxmes">
-                                                               <para>Received Media Experience Score</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="all_jitter">
-                                               <para>Retrieve a summary of all RTCP Jitter statistics.</para>
-                                               <para>The following data items are returned in a semi-colon
-                                               delineated list:</para>
-                                               <enumlist>
-                                                       <enum name="minrxjitter">
-                                                               <para>Our minimum jitter</para>
-                                                       </enum>
-                                                       <enum name="maxrxjitter">
-                                                               <para>Our max jitter</para>
-                                                       </enum>
-                                                       <enum name="avgrxjitter">
-                                                               <para>Our average jitter</para>
-                                                       </enum>
-                                                       <enum name="stdevrxjitter">
-                                                               <para>Our jitter standard deviation</para>
-                                                       </enum>
-                                                       <enum name="reported_minjitter">
-                                                               <para>Their minimum jitter</para>
-                                                       </enum>
-                                                       <enum name="reported_maxjitter">
-                                                               <para>Their max jitter</para>
-                                                       </enum>
-                                                       <enum name="reported_avgjitter">
-                                                               <para>Their average jitter</para>
-                                                       </enum>
-                                                       <enum name="reported_stdevjitter">
-                                                               <para>Their jitter standard deviation</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="all_loss">
-                                               <para>Retrieve a summary of all RTCP packet loss statistics.</para>
-                                               <para>The following data items are returned in a semi-colon
-                                               delineated list:</para>
-                                               <enumlist>
-                                                       <enum name="minrxlost">
-                                                               <para>Our minimum lost packets</para>
-                                                       </enum>
-                                                       <enum name="maxrxlost">
-                                                               <para>Our max lost packets</para>
-                                                       </enum>
-                                                       <enum name="avgrxlost">
-                                                               <para>Our average lost packets</para>
-                                                       </enum>
-                                                       <enum name="stdevrxlost">
-                                                               <para>Our lost packets standard deviation</para>
-                                                       </enum>
-                                                       <enum name="reported_minlost">
-                                                               <para>Their minimum lost packets</para>
-                                                       </enum>
-                                                       <enum name="reported_maxlost">
-                                                               <para>Their max lost packets</para>
-                                                       </enum>
-                                                       <enum name="reported_avglost">
-                                                               <para>Their average lost packets</para>
-                                                       </enum>
-                                                       <enum name="reported_stdevlost">
-                                                               <para>Their lost packets standard deviation</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="all_rtt">
-                                               <para>Retrieve a summary of all RTCP round trip time information.</para>
-                                               <para>The following data items are returned in a semi-colon
-                                               delineated list:</para>
-                                               <enumlist>
-                                                       <enum name="minrtt">
-                                                               <para>Minimum round trip time</para>
-                                                       </enum>
-                                                       <enum name="maxrtt">
-                                                               <para>Maximum round trip time</para>
-                                                       </enum>
-                                                       <enum name="avgrtt">
-                                                               <para>Average round trip time</para>
-                                                       </enum>
-                                                       <enum name="stdevrtt">
-                                                               <para>Standard deviation round trip time</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="all_mes">
-                                               <para>Retrieve a summary of all RTCP Media Experience Score information.</para>
-                                               <para>The following data items are returned in a semi-colon
-                                               delineated list:</para>
-                                               <enumlist>
-                                                       <enum name="minmes">
-                                                               <para>Minimum MES based on us analysing received packets.</para>
-                                                       </enum>
-                                                       <enum name="maxmes">
-                                                               <para>Maximum MES based on us analysing received packets.</para>
-                                                       </enum>
-                                                       <enum name="avgmes">
-                                                               <para>Average MES based on us analysing received packets.</para>
-                                                       </enum>
-                                                       <enum name="stdevmes">
-                                                               <para>Standard deviation MES based on us analysing received packets.</para>
-                                                       </enum>
-                                                       <enum name="reported_minmes">
-                                                               <para>Minimum MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
-                                                       </enum>
-                                                       <enum name="reported_maxmes">
-                                                               <para>Maximum MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
-                                                       </enum>
-                                                       <enum name="reported_avgmes">
-                                                               <para>Average MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
-                                                       </enum>
-                                                       <enum name="reported_stdevmes">
-                                                               <para>Standard deviation MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
-                                                       </enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="txcount"><para>Transmitted packet count</para></enum>
-                                       <enum name="rxcount"><para>Received packet count</para></enum>
-                                       <enum name="txjitter"><para>Transmitted packet jitter</para></enum>
-                                       <enum name="rxjitter"><para>Received packet jitter</para></enum>
-                                       <enum name="remote_maxjitter"><para>Their max jitter</para></enum>
-                                       <enum name="remote_minjitter"><para>Their minimum jitter</para></enum>
-                                       <enum name="remote_normdevjitter"><para>Their average jitter</para></enum>
-                                       <enum name="remote_stdevjitter"><para>Their jitter standard deviation</para></enum>
-                                       <enum name="local_maxjitter"><para>Our max jitter</para></enum>
-                                       <enum name="local_minjitter"><para>Our minimum jitter</para></enum>
-                                       <enum name="local_normdevjitter"><para>Our average jitter</para></enum>
-                                       <enum name="local_stdevjitter"><para>Our jitter standard deviation</para></enum>
-                                       <enum name="txploss"><para>Transmitted packet loss</para></enum>
-                                       <enum name="rxploss"><para>Received packet loss</para></enum>
-                                       <enum name="remote_maxrxploss"><para>Their max lost packets</para></enum>
-                                       <enum name="remote_minrxploss"><para>Their minimum lost packets</para></enum>
-                                       <enum name="remote_normdevrxploss"><para>Their average lost packets</para></enum>
-                                       <enum name="remote_stdevrxploss"><para>Their lost packets standard deviation</para></enum>
-                                       <enum name="local_maxrxploss"><para>Our max lost packets</para></enum>
-                                       <enum name="local_minrxploss"><para>Our minimum lost packets</para></enum>
-                                       <enum name="local_normdevrxploss"><para>Our average lost packets</para></enum>
-                                       <enum name="local_stdevrxploss"><para>Our lost packets standard deviation</para></enum>
-                                       <enum name="rtt"><para>Round trip time</para></enum>
-                                       <enum name="maxrtt"><para>Maximum round trip time</para></enum>
-                                       <enum name="minrtt"><para>Minimum round trip time</para></enum>
-                                       <enum name="normdevrtt"><para>Average round trip time</para></enum>
-                                       <enum name="stdevrtt"><para>Standard deviation round trip time</para></enum>
-                                       <enum name="local_ssrc"><para>Our Synchronization Source identifier</para></enum>
-                                       <enum name="remote_ssrc"><para>Their Synchronization Source identifier</para></enum>
-                                       <enum name="txmes"><para>
-                                       Current MES based on us analyzing rtt, jitter and loss
-                                       in the actual received RTP stream received from the remote end.
-                                       I.E.  This is the MES for the incoming audio stream.
-                                       </para></enum>
-                                       <enum name="rxmes"><para>
-                                       Current MES based on rtt and the jitter and loss values in
-                                       RTCP sender and receiver reports we receive from the
-                                       remote end. I.E.  This is the MES for the outgoing audio stream.
-                                       </para></enum>
-                                       <enum name="remote_maxmes"><para>Max MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
-                                       <enum name="remote_minmes"><para>Min MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
-                                       <enum name="remote_normdevmes"><para>Average MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
-                                       <enum name="remote_stdevmes"><para>Standard deviation MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
-                                       <enum name="local_maxmes"><para>Max MES based on us analyzing the received RTP stream</para></enum>
-                                       <enum name="local_minmes"><para>Min MES based on us analyzing the received RTP stream</para></enum>
-                                       <enum name="local_normdevmes"><para>Average MES based on us analyzing the received RTP stream</para></enum>
-                                       <enum name="local_stdevmes"><para>Standard deviation MES based on us analyzing the received RTP stream</para></enum>
-                               </enumlist>
-                       </parameter>
-                       <parameter name="media_type" required="false">
-                               <para>When <replaceable>rtcp</replaceable> is specified, the
-                               <literal>media_type</literal> parameter may be provided. It specifies
-                               which media stream the chosen RTCP parameter should be retrieved
-                               from.</para>
-                               <enumlist>
-                                       <enum name="audio">
-                                               <para>Retrieve information from the audio media stream.</para>
-                                               <note><para>If not specified, <literal>audio</literal> is used
-                                               by default.</para></note>
-                                       </enum>
-                                       <enum name="video">
-                                               <para>Retrieve information from the video media stream.</para>
-                                       </enum>
-                               </enumlist>
-                       </parameter>
-               </enum>
-               <enum name="endpoint">
-                       <para>R/O The name of the endpoint associated with this channel.
-                       Use the <replaceable>PJSIP_ENDPOINT</replaceable> function to obtain
-                       further endpoint related information.</para>
-               </enum>
-               <enum name="contact">
-                       <para>R/O The name of the contact associated with this channel.
-                       Use the <replaceable>PJSIP_CONTACT</replaceable> function to obtain
-                       further contact related information. Note this may not be present and if so
-                       is only available on outgoing legs.</para>
-               </enum>
-               <enum name="aor">
-                       <para>R/O The name of the AOR associated with this channel.
-                       Use the <replaceable>PJSIP_AOR</replaceable> function to obtain
-                       further AOR related information. Note this may not be present and if so
-                       is only available on outgoing legs.</para>
-               </enum>
-               <enum name="pjsip">
-                       <para>R/O Obtain information about the current PJSIP channel and its
-                       session.</para>
-                       <parameter name="type" required="true">
-                               <para>When <replaceable>pjsip</replaceable> is specified, the
-                               <literal>type</literal> parameter must be provided. It specifies
-                               which signalling parameter to read.</para>
-                               <enumlist>
-                                       <enum name="call-id">
-                                               <para>The SIP call-id.</para>
-                                       </enum>
-                                       <enum name="secure">
-                                               <para>Whether or not the signalling uses a secure transport.</para>
-                                               <enumlist>
-                                                       <enum name="0"><para>The signalling uses a non-secure transport.</para></enum>
-                                                       <enum name="1"><para>The signalling uses a secure transport.</para></enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="target_uri">
-                                               <para>The contact URI where requests are sent.</para>
-                                       </enum>
-                                       <enum name="local_uri">
-                                               <para>The local URI.</para>
-                                       </enum>
-                                       <enum name="local_tag">
-                                               <para>Tag in From header</para>
-                                       </enum>
-                                       <enum name="remote_uri">
-                                               <para>The remote URI.</para>
-                                       </enum>
-                                       <enum name="remote_tag">
-                                               <para>Tag in To header</para>
-                                       </enum>
-                                       <enum name="request_uri">
-                                               <para>The request URI of the incoming <literal>INVITE</literal>
-                                               associated with the creation of this channel.</para>
-                                       </enum>
-                                       <enum name="t38state">
-                                               <para>The current state of any T.38 fax on this channel.</para>
-                                               <enumlist>
-                                                       <enum name="DISABLED"><para>T.38 faxing is disabled on this channel.</para></enum>
-                                                       <enum name="LOCAL_REINVITE"><para>Asterisk has sent a <literal>re-INVITE</literal> to the remote end to initiate a T.38 fax.</para></enum>
-                                                       <enum name="REMOTE_REINVITE"><para>The remote end has sent a <literal>re-INVITE</literal> to Asterisk to initiate a T.38 fax.</para></enum>
-                                                       <enum name="ENABLED"><para>A T.38 fax session has been enabled.</para></enum>
-                                                       <enum name="REJECTED"><para>A T.38 fax session was attempted but was rejected.</para></enum>
-                                               </enumlist>
-                                       </enum>
-                                       <enum name="local_addr">
-                                               <para>On inbound calls, the full IP address and port number that
-                                               the <literal>INVITE</literal> request was received on. On outbound
-                                               calls, the full IP address and port number that the <literal>INVITE</literal>
-                                               request was transmitted from.</para>
-                                       </enum>
-                                       <enum name="remote_addr">
-                                               <para>On inbound calls, the full IP address and port number that
-                                               the <literal>INVITE</literal> request was received from. On outbound
-                                               calls, the full IP address and port number that the <literal>INVITE</literal>
-                                               request was transmitted to.</para>
-                                       </enum>
-                               </enumlist>
-                       </parameter>
-               </enum>
-       </enumlist>
-</info>
-<info name="CHANNEL_EXAMPLES" language="en_US" tech="PJSIP">
-       <example title="PJSIP specific CHANNEL examples">
-               ; Log the current Call-ID
-               same => n,Log(NOTICE, ${CHANNEL(pjsip,call-id)})
-
-               ; Log the destination address of the audio stream
-               same => n,Log(NOTICE, ${CHANNEL(rtp,dest)})
-
-               ; Store the round-trip time associated with a
-               ; video stream in the CDR field video-rtt
-               same => n,Set(CDR(video-rtt)=${CHANNEL(rtcp,rtt,video)})
-       </example>
-</info>
-***/
-
 #include "asterisk.h"
 
 #include <pjsip.h>
 #include "asterisk/module.h"
 #include "asterisk/acl.h"
 #include "asterisk/app.h"
+#include "asterisk/conversions.h"
 #include "asterisk/channel.h"
 #include "asterisk/stream.h"
 #include "asterisk/format.h"
@@ -1784,3 +1228,121 @@ int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, c
 
        return ast_sip_push_task_wait_serializer(channel->session->serializer, refresh_write_cb, &rdata);
 }
+
+struct hangup_data {
+       struct ast_sip_session *session;
+       int response_code;
+};
+
+/*!
+ * \brief Serializer task to hangup channel
+ */
+static int pjsip_hangup(void *obj)
+{
+       struct hangup_data *hdata = obj;
+       pjsip_tx_data *packet = NULL;
+
+       if ((hdata->session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
+               (pjsip_inv_answer(hdata->session->inv_session, hdata->response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
+               ast_sip_session_send_response(hdata->session, packet);
+       }
+
+       return 0;
+}
+
+/*!
+ * \brief Callback that validates the response code
+ */
+static int response_code_validator(const char *channel_name,
+       const char *response) {
+       int response_code;
+
+       int rc = ast_str_to_int(response, &response_code);
+       if (rc != 0) {
+               response_code = ast_sip_str2rc(response);
+               if (response_code < 0) {
+                       ast_log(LOG_WARNING, "%s: Unrecognized response code parameter '%s'."
+                               " Defaulting to 603 DECLINE\n",
+                               channel_name, response);
+                       return PJSIP_SC_DECLINE;
+               }
+       }
+
+       if (response_code < 400 || response_code > 699) {
+               ast_log(LOG_WARNING, "%s: Response code %d is out of range 400 -> 699."
+                       " Defaulting to 603 DECLINE\n",
+                       channel_name, response_code);
+               return PJSIP_SC_DECLINE;
+       }
+       return response_code;
+}
+
+/*!
+ * \brief Called by pjsip_app_hangup and pjsip_action_hangup
+ *        to actually perform the hangup
+ */
+static void pjsip_app_hangup_handler(struct ast_channel *chan, int response_code)
+{
+       struct ast_sip_channel_pvt *channel;
+       struct hangup_data hdata = { NULL, -1 };
+       const char *tag = ast_channel_name(chan);
+
+       hdata.response_code = response_code;
+
+       ast_channel_lock(chan);
+       if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
+               ast_log(LOG_WARNING, "%s: Not a PJSIP channel\n", tag);
+               ast_channel_unlock(chan);
+               return;
+       }
+
+       channel = ast_channel_tech_pvt(chan);
+       hdata.session = channel->session;
+
+       if (hdata.session->inv_session->role != PJSIP_ROLE_UAS || (
+               hdata.session->inv_session->state != PJSIP_INV_STATE_INCOMING &&
+               hdata.session->inv_session->state != PJSIP_INV_STATE_EARLY)) {
+               ast_log(LOG_WARNING, "%s: Not an incoming channel or invalid state '%s'\n",
+                       tag, pjsip_inv_state_name(hdata.session->inv_session->state));
+               ast_channel_unlock(chan);
+               return;
+       }
+
+       ast_channel_unlock(chan);
+
+       if (ast_sip_push_task_wait_serializer(channel->session->serializer,
+               pjsip_hangup, &hdata) != 0) {
+               ast_log(LOG_WARNING, "%s: failed to push hangup task to serializer\n", tag);
+       }
+
+       return;
+}
+
+/*!
+ * \brief PJSIPHangup Dialplan App
+ */
+int pjsip_app_hangup(struct ast_channel *chan, const char *data)
+{
+       int response_code;
+       const char *tag = ast_channel_name(chan);
+
+       if (ast_strlen_zero(data)) {
+               ast_log(LOG_WARNING, "%s: Missing response code parameter\n", tag);
+               return -1;
+       }
+
+       response_code = response_code_validator(tag, data);
+
+       pjsip_app_hangup_handler(chan, response_code);
+
+       return -1;
+}
+
+/*!
+ * \brief PJSIPHangup Manager Action
+ */
+int pjsip_action_hangup(struct mansession *s, const struct message *m)
+{
+       return ast_manager_hangup_helper(s, m,
+               pjsip_app_hangup_handler, response_code_validator);
+}
diff --git a/channels/pjsip/dialplan_functions.xml b/channels/pjsip/dialplan_functions.xml
new file mode 100644 (file)
index 0000000..be4ce91
--- /dev/null
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE docs SYSTEM "appdocsxml.dtd">
+<docs>
+       <application name="PJSIPHangup" language="en_US">
+               <synopsis>
+                       Hangup an incoming PJSIP channel with a SIP response code
+               </synopsis>
+               <syntax>
+                       <parameter name="Cause" required="true">
+                               <para>May be one of...</para>
+                               <enumlist>
+                               <enum name="Response code"><para>A numeric response code in the range 400 ->699</para></enum>
+                               <enum name="Response code name"><para>A response code name from
+                               <literal>third-party/pjproject/source/pjsip/include/pjsip/sip_msg.h</literal>
+                               such as <literal>USE_IDENTITY_HEADER</literal> or 
+                               <literal>PJSIP_SC_USE_IDENTITY_HEADER</literal></para></enum>
+                               </enumlist>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>
+                       Hangs up an incoming PJSIP channel and returns the
+                       specified SIP response code in the final response to the caller.
+                       </para>
+                       <para>
+                       </para>
+                       <warning><para>
+                       This function must be called BEFORE anything that
+                       might cause any other final (non 1XX) response to be sent.
+                       For example calling <literal>Answer()</literal> or
+                       <literal>Playback</literal> without the
+                       <literal>noanswer</literal> option will cause the call
+                       to be answered and a final 200 response to be sent.
+                       </para></warning>
+                       <para>
+                       </para>
+                       <para>As with the <literal>Hangup</literal> application, 
+                       the dialplan will terminate after calling this function.</para>
+                       <para>
+                       </para>
+                       <para>The cause code set on the channel will be translated to
+                       a standard ISDN cause code using the table defined in
+                       ast_sip_hangup_sip2cause() in res_pjsip.c</para>
+                       <para>
+                       </para>
+                       <example title="Terminate call with 437 response code">
+                       same = n,PJSIPHangup(437)
+                       </example>
+                       <example title="Terminate call with 437 response code using the response code name">
+                       same = n,PJSIPHangup(UNSUPPORTED_CERTIFICATE)
+                       </example>
+                       <example title="Terminate call with 437 response code based on condition">
+                       same = n,ExecIf($[${SOMEVALUE} = ${SOME_BAD_VALUE}]?PJSIPHangup(437))
+                       </example>
+               </description>
+       </application>
+
+       <manager name="PJSIPHangup" language="en_US">
+               <synopsis>
+                       Hangup an incoming PJSIP channel with a SIP response code
+               </synopsis>
+               <syntax>
+                       <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+                       <xi:include xpointer="xpointer(/docs/manager[@name='Hangup']/syntax/parameter[@name='Channel'])" />
+                       <xi:include xpointer="xpointer(/docs/application[@name='PJSIPHangup']/syntax/parameter[@name='Cause'])" />
+               </syntax>
+               <description>
+                       <para>
+                       Hangs up an incoming PJSIP channel and returns the
+                       specified SIP response code in the final response to the caller.
+                       </para>
+                       <para>
+                       </para>
+                       <warning><para>
+                       This function must be called BEFORE anything that
+                       might cause any other final (non 1XX) response to be sent.
+                       For example calling <literal>Answer()</literal> or
+                       <literal>Playback</literal> without the
+                       <literal>noanswer</literal> option will cause the call
+                       to be answered and a final 200 response to be sent.
+                       </para></warning>
+                       <para>
+                       </para>
+                       <para>The cause code set on the channel will be translated to
+                       a standard ISDN cause code using the table defined in
+                       ast_sip_hangup_sip2cause() in res_pjsip.c</para>
+                       <para>
+                       </para>
+                       <example title="Terminate call with 437 response code">
+                       Action: PJSIPHangup
+                       ActionID: 12345678
+                       Channel: PJSIP/alice-00000002
+                       Cause: 437
+                       </example>
+                       <example title="Terminate call with 437 response code using the response code name">
+                       Action: PJSIPHangup
+                       ActionID: 12345678
+                       Channel: PJSIP/alice-00000002
+                       Cause: UNSUPPORTED_CERTIFICATE
+                       </example>
+               </description>
+       </manager>
+
+       <function name="PJSIP_DIAL_CONTACTS" language="en_US">
+               <synopsis>
+                       Return a dial string for dialing all contacts on an AOR.
+               </synopsis>
+               <syntax>
+                       <parameter name="endpoint" required="true">
+                               <para>Name of the endpoint</para>
+                       </parameter>
+                       <parameter name="aor" required="false">
+                               <para>Name of an AOR to use, if not specified the configured AORs on the endpoint are used</para>
+                       </parameter>
+                       <parameter name="request_user" required="false">
+                               <para>Optional request user to use in the request URI</para>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>Returns a properly formatted dial string for dialing all contacts on an AOR.</para>
+               </description>
+       </function>
+       <function name="PJSIP_MEDIA_OFFER" language="en_US">
+               <synopsis>
+                       Media and codec offerings to be set on an outbound SIP channel prior to dialing.
+               </synopsis>
+               <syntax>
+                       <parameter name="media" required="true">
+                               <para>types of media offered</para>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>When read, returns the codecs offered based upon the media choice.</para>
+                       <para>When written, sets the codecs to offer when an outbound dial attempt is made,
+                       or when a session refresh is sent using <replaceable>PJSIP_SEND_SESSION_REFRESH</replaceable>.
+                       </para>
+               </description>
+               <see-also>
+                       <ref type="function">PJSIP_SEND_SESSION_REFRESH</ref>
+               </see-also>
+       </function>
+       <function name="PJSIP_DTMF_MODE" language="en_US">
+               <since>
+                       <version>13.18.0</version>
+                       <version>14.7.0</version>
+                       <version>15.1.0</version>
+                       <version>16.0.0</version>
+               </since>
+               <synopsis>
+                       Get or change the DTMF mode for a SIP call.
+               </synopsis>
+               <syntax>
+               </syntax>
+               <description>
+                       <para>When read, returns the current DTMF mode</para>
+                       <para>When written, sets the current DTMF mode</para>
+                       <para>This function uses the same DTMF mode naming as the dtmf_mode configuration option</para>
+               </description>
+       </function>
+       <function name="PJSIP_MOH_PASSTHROUGH" language="en_US">
+               <synopsis>
+                       Get or change the on-hold behavior for a SIP call.
+               </synopsis>
+               <syntax>
+               </syntax>
+               <description>
+                       <para>When read, returns the current moh passthrough mode</para>
+                       <para>When written, sets the current moh passthrough mode</para>
+                       <para>If <replaceable>yes</replaceable>, on-hold re-INVITEs are sent. If <replaceable>no</replaceable>, music on hold is generated.</para>
+                       <para>This function can be used to override the moh_passthrough configuration option</para>
+               </description>
+       </function>
+       <function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
+               <since>
+                       <version>13.12.0</version>
+                       <version>14.1.0</version>
+                       <version>15.0.0</version>
+               </since>
+               <synopsis>
+                       W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session
+               </synopsis>
+               <syntax>
+                       <parameter name="update_type" required="false">
+                               <para>The type of update to send. Default is <literal>invite</literal>.</para>
+                               <enumlist>
+                                       <enum name="invite">
+                                               <para>Send the session refresh as a re-INVITE.</para>
+                                       </enum>
+                                       <enum name="update">
+                                               <para>Send the session refresh as an UPDATE.</para>
+                                       </enum>
+                               </enumlist>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>This function will cause the PJSIP stack to immediately refresh
+                       the media session for the channel. This will be done using either a
+                       re-INVITE (default) or an UPDATE request.
+                       </para>
+                       <para>This is most useful when combined with the <replaceable>PJSIP_MEDIA_OFFER</replaceable>
+                       dialplan function, as it allows the formats in use on a channel to be
+                       re-negotiated after call setup.</para>
+                       <warning>
+                               <para>The formats the endpoint supports are <emphasis>not</emphasis>
+                               checked or enforced by this function. Using this function to offer
+                               formats not supported by the endpoint <emphasis>may</emphasis> result
+                               in a loss of media.</para>
+                       </warning>
+                       <example title="Re-negotiate format to g722">
+                        ; Within some existing extension on an answered channel
+                        same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,g722)
+                        same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite)
+                       </example>
+               </description>
+               <see-also>
+                       <ref type="function">PJSIP_MEDIA_OFFER</ref>
+               </see-also>
+       </function>
+       <function name="PJSIP_PARSE_URI" language="en_US">
+               <since>
+                       <version>13.24.0</version>
+                       <version>16.1.0</version>
+                       <version>17.0.0</version>
+               </since>
+               <synopsis>
+                       Parse an uri and return a type part of the URI.
+               </synopsis>
+               <syntax>
+                       <parameter name="uri" required="true">
+                               <para>URI to parse</para>
+                       </parameter>
+                       <parameter name="type" required="true">
+                               <para>The <literal>type</literal> parameter specifies which URI part to read</para>
+                               <enumlist>
+                                       <enum name="display">
+                                               <para>Display name.</para>
+                                       </enum>
+                                       <enum name="scheme">
+                                               <para>URI scheme.</para>
+                                       </enum>
+                                       <enum name="user">
+                                               <para>User part.</para>
+                                       </enum>
+                                       <enum name="passwd">
+                                               <para>Password part.</para>
+                                       </enum>
+                                       <enum name="host">
+                                               <para>Host part.</para>
+                                       </enum>
+                                       <enum name="port">
+                                               <para>Port number, or zero.</para>
+                                       </enum>
+                                       <enum name="user_param">
+                                               <para>User parameter.</para>
+                                       </enum>
+                                       <enum name="method_param">
+                                               <para>Method parameter.</para>
+                                       </enum>
+                                       <enum name="transport_param">
+                                               <para>Transport parameter.</para>
+                                       </enum>
+                                       <enum name="ttl_param">
+                                               <para>TTL param, or -1.</para>
+                                       </enum>
+                                       <enum name="lr_param">
+                                               <para>Loose routing param, or zero.</para>
+                                       </enum>
+                                       <enum name="maddr_param">
+                                               <para>Maddr param.</para>
+                                       </enum>
+                               </enumlist>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>Parse an URI and return a specified part of the URI.</para>
+               </description>
+       </function>
+
+       <info name="CHANNEL" language="en_US" tech="PJSIP">
+               <enumlist>
+                       <enum name="rtp">
+                               <para>R/O Retrieve media related information.</para>
+                               <parameter name="type" required="true">
+                                       <para>When <replaceable>rtp</replaceable> is specified, the
+                                       <literal>type</literal> parameter must be provided. It specifies
+                                       which RTP parameter to read.</para>
+                                       <enumlist>
+                                               <enum name="src">
+                                                       <para>Retrieve the local address for RTP.</para>
+                                               </enum>
+                                               <enum name="dest">
+                                                       <para>Retrieve the remote address for RTP.</para>
+                                               </enum>
+                                               <enum name="direct">
+                                                       <para>If direct media is enabled, this address is the remote address
+                                                       used for RTP.</para>
+                                               </enum>
+                                               <enum name="secure">
+                                                       <para>Whether or not the media stream is encrypted.</para>
+                                                       <enumlist>
+                                                               <enum name="0">
+                                                                       <para>The media stream is not encrypted.</para>
+                                                               </enum>
+                                                               <enum name="1">
+                                                                       <para>The media stream is encrypted.</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="hold">
+                                                       <para>Whether or not the media stream is currently restricted
+                                                       due to a call hold.</para>
+                                                       <enumlist>
+                                                               <enum name="0">
+                                                                       <para>The media stream is not held.</para>
+                                                               </enum>
+                                                               <enum name="1">
+                                                                       <para>The media stream is held.</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                       </enumlist>
+                               </parameter>
+                               <parameter name="media_type" required="false">
+                                       <para>When <replaceable>rtp</replaceable> is specified, the
+                                       <literal>media_type</literal> parameter may be provided. It specifies
+                                       which media stream the chosen RTP parameter should be retrieved
+                                       from.</para>
+                                       <enumlist>
+                                               <enum name="audio">
+                                                       <para>Retrieve information from the audio media stream.</para>
+                                                       <note><para>If not specified, <literal>audio</literal> is used
+                                                       by default.</para></note>
+                                               </enum>
+                                               <enum name="video">
+                                                       <para>Retrieve information from the video media stream.</para>
+                                               </enum>
+                                       </enumlist>
+                               </parameter>
+                       </enum>
+                       <enum name="rtcp">
+                               <para>R/O Retrieve RTCP statistics.</para>
+                               <parameter name="statistic" required="true">
+                                       <para>When <replaceable>rtcp</replaceable> is specified, the
+                                       <literal>statistic</literal> parameter must be provided. It specifies
+                                       which RTCP statistic parameter to read.</para>
+                                       <enumlist>
+                                               <enum name="all">
+                                                       <para>Retrieve a summary of all RTCP statistics.</para>
+                                                       <para>The following data items are returned in a semi-colon
+                                                       delineated list:</para>
+                                                       <enumlist>
+                                                               <enum name="ssrc">
+                                                                       <para>Our Synchronization Source identifier</para>
+                                                               </enum>
+                                                               <enum name="themssrc">
+                                                                       <para>Their Synchronization Source identifier</para>
+                                                               </enum>
+                                                               <enum name="lp">
+                                                                       <para>Our lost packet count</para>
+                                                               </enum>
+                                                               <enum name="rxjitter">
+                                                                       <para>Received packet jitter</para>
+                                                               </enum>
+                                                               <enum name="rxcount">
+                                                                       <para>Received packet count</para>
+                                                               </enum>
+                                                               <enum name="txjitter">
+                                                                       <para>Transmitted packet jitter</para>
+                                                               </enum>
+                                                               <enum name="txcount">
+                                                                       <para>Transmitted packet count</para>
+                                                               </enum>
+                                                               <enum name="rlp">
+                                                                       <para>Remote lost packet count</para>
+                                                               </enum>
+                                                               <enum name="rtt">
+                                                                       <para>Round trip time</para>
+                                                               </enum>
+                                                               <enum name="txmes">
+                                                                       <para>Transmitted Media Experience Score</para>
+                                                               </enum>
+                                                               <enum name="rxmes">
+                                                                       <para>Received Media Experience Score</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="all_jitter">
+                                                       <para>Retrieve a summary of all RTCP Jitter statistics.</para>
+                                                       <para>The following data items are returned in a semi-colon
+                                                       delineated list:</para>
+                                                       <enumlist>
+                                                               <enum name="minrxjitter">
+                                                                       <para>Our minimum jitter</para>
+                                                               </enum>
+                                                               <enum name="maxrxjitter">
+                                                                       <para>Our max jitter</para>
+                                                               </enum>
+                                                               <enum name="avgrxjitter">
+                                                                       <para>Our average jitter</para>
+                                                               </enum>
+                                                               <enum name="stdevrxjitter">
+                                                                       <para>Our jitter standard deviation</para>
+                                                               </enum>
+                                                               <enum name="reported_minjitter">
+                                                                       <para>Their minimum jitter</para>
+                                                               </enum>
+                                                               <enum name="reported_maxjitter">
+                                                                       <para>Their max jitter</para>
+                                                               </enum>
+                                                               <enum name="reported_avgjitter">
+                                                                       <para>Their average jitter</para>
+                                                               </enum>
+                                                               <enum name="reported_stdevjitter">
+                                                                       <para>Their jitter standard deviation</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="all_loss">
+                                                       <para>Retrieve a summary of all RTCP packet loss statistics.</para>
+                                                       <para>The following data items are returned in a semi-colon
+                                                       delineated list:</para>
+                                                       <enumlist>
+                                                               <enum name="minrxlost">
+                                                                       <para>Our minimum lost packets</para>
+                                                               </enum>
+                                                               <enum name="maxrxlost">
+                                                                       <para>Our max lost packets</para>
+                                                               </enum>
+                                                               <enum name="avgrxlost">
+                                                                       <para>Our average lost packets</para>
+                                                               </enum>
+                                                               <enum name="stdevrxlost">
+                                                                       <para>Our lost packets standard deviation</para>
+                                                               </enum>
+                                                               <enum name="reported_minlost">
+                                                                       <para>Their minimum lost packets</para>
+                                                               </enum>
+                                                               <enum name="reported_maxlost">
+                                                                       <para>Their max lost packets</para>
+                                                               </enum>
+                                                               <enum name="reported_avglost">
+                                                                       <para>Their average lost packets</para>
+                                                               </enum>
+                                                               <enum name="reported_stdevlost">
+                                                                       <para>Their lost packets standard deviation</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="all_rtt">
+                                                       <para>Retrieve a summary of all RTCP round trip time information.</para>
+                                                       <para>The following data items are returned in a semi-colon
+                                                       delineated list:</para>
+                                                       <enumlist>
+                                                               <enum name="minrtt">
+                                                                       <para>Minimum round trip time</para>
+                                                               </enum>
+                                                               <enum name="maxrtt">
+                                                                       <para>Maximum round trip time</para>
+                                                               </enum>
+                                                               <enum name="avgrtt">
+                                                                       <para>Average round trip time</para>
+                                                               </enum>
+                                                               <enum name="stdevrtt">
+                                                                       <para>Standard deviation round trip time</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="all_mes">
+                                                       <para>Retrieve a summary of all RTCP Media Experience Score information.</para>
+                                                       <para>The following data items are returned in a semi-colon
+                                                       delineated list:</para>
+                                                       <enumlist>
+                                                               <enum name="minmes">
+                                                                       <para>Minimum MES based on us analysing received packets.</para>
+                                                               </enum>
+                                                               <enum name="maxmes">
+                                                                       <para>Maximum MES based on us analysing received packets.</para>
+                                                               </enum>
+                                                               <enum name="avgmes">
+                                                                       <para>Average MES based on us analysing received packets.</para>
+                                                               </enum>
+                                                               <enum name="stdevmes">
+                                                                       <para>Standard deviation MES based on us analysing received packets.</para>
+                                                               </enum>
+                                                               <enum name="reported_minmes">
+                                                                       <para>Minimum MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
+                                                               </enum>
+                                                               <enum name="reported_maxmes">
+                                                                       <para>Maximum MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
+                                                               </enum>
+                                                               <enum name="reported_avgmes">
+                                                                       <para>Average MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
+                                                               </enum>
+                                                               <enum name="reported_stdevmes">
+                                                                       <para>Standard deviation MES based on data we get in Sender and Receiver Reports sent by the remote end</para>
+                                                               </enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="txcount"><para>Transmitted packet count</para></enum>
+                                               <enum name="rxcount"><para>Received packet count</para></enum>
+                                               <enum name="txjitter"><para>Transmitted packet jitter</para></enum>
+                                               <enum name="rxjitter"><para>Received packet jitter</para></enum>
+                                               <enum name="remote_maxjitter"><para>Their max jitter</para></enum>
+                                               <enum name="remote_minjitter"><para>Their minimum jitter</para></enum>
+                                               <enum name="remote_normdevjitter"><para>Their average jitter</para></enum>
+                                               <enum name="remote_stdevjitter"><para>Their jitter standard deviation</para></enum>
+                                               <enum name="local_maxjitter"><para>Our max jitter</para></enum>
+                                               <enum name="local_minjitter"><para>Our minimum jitter</para></enum>
+                                               <enum name="local_normdevjitter"><para>Our average jitter</para></enum>
+                                               <enum name="local_stdevjitter"><para>Our jitter standard deviation</para></enum>
+                                               <enum name="txploss"><para>Transmitted packet loss</para></enum>
+                                               <enum name="rxploss"><para>Received packet loss</para></enum>
+                                               <enum name="remote_maxrxploss"><para>Their max lost packets</para></enum>
+                                               <enum name="remote_minrxploss"><para>Their minimum lost packets</para></enum>
+                                               <enum name="remote_normdevrxploss"><para>Their average lost packets</para></enum>
+                                               <enum name="remote_stdevrxploss"><para>Their lost packets standard deviation</para></enum>
+                                               <enum name="local_maxrxploss"><para>Our max lost packets</para></enum>
+                                               <enum name="local_minrxploss"><para>Our minimum lost packets</para></enum>
+                                               <enum name="local_normdevrxploss"><para>Our average lost packets</para></enum>
+                                               <enum name="local_stdevrxploss"><para>Our lost packets standard deviation</para></enum>
+                                               <enum name="rtt"><para>Round trip time</para></enum>
+                                               <enum name="maxrtt"><para>Maximum round trip time</para></enum>
+                                               <enum name="minrtt"><para>Minimum round trip time</para></enum>
+                                               <enum name="normdevrtt"><para>Average round trip time</para></enum>
+                                               <enum name="stdevrtt"><para>Standard deviation round trip time</para></enum>
+                                               <enum name="local_ssrc"><para>Our Synchronization Source identifier</para></enum>
+                                               <enum name="remote_ssrc"><para>Their Synchronization Source identifier</para></enum>
+                                               <enum name="txmes"><para>
+                                               Current MES based on us analyzing rtt, jitter and loss
+                                               in the actual received RTP stream received from the remote end.
+                                               I.E.  This is the MES for the incoming audio stream.
+                                               </para></enum>
+                                               <enum name="rxmes"><para>
+                                               Current MES based on rtt and the jitter and loss values in
+                                               RTCP sender and receiver reports we receive from the
+                                               remote end. I.E.  This is the MES for the outgoing audio stream.
+                                               </para></enum>
+                                               <enum name="remote_maxmes"><para>Max MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
+                                               <enum name="remote_minmes"><para>Min MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
+                                               <enum name="remote_normdevmes"><para>Average MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
+                                               <enum name="remote_stdevmes"><para>Standard deviation MES based on data we get in Sender and Receiver Reports sent by the remote end</para></enum>
+                                               <enum name="local_maxmes"><para>Max MES based on us analyzing the received RTP stream</para></enum>
+                                               <enum name="local_minmes"><para>Min MES based on us analyzing the received RTP stream</para></enum>
+                                               <enum name="local_normdevmes"><para>Average MES based on us analyzing the received RTP stream</para></enum>
+                                               <enum name="local_stdevmes"><para>Standard deviation MES based on us analyzing the received RTP stream</para></enum>
+                                       </enumlist>
+                               </parameter>
+                               <parameter name="media_type" required="false">
+                                       <para>When <replaceable>rtcp</replaceable> is specified, the
+                                       <literal>media_type</literal> parameter may be provided. It specifies
+                                       which media stream the chosen RTCP parameter should be retrieved
+                                       from.</para>
+                                       <enumlist>
+                                               <enum name="audio">
+                                                       <para>Retrieve information from the audio media stream.</para>
+                                                       <note><para>If not specified, <literal>audio</literal> is used
+                                                       by default.</para></note>
+                                               </enum>
+                                               <enum name="video">
+                                                       <para>Retrieve information from the video media stream.</para>
+                                               </enum>
+                                       </enumlist>
+                               </parameter>
+                       </enum>
+                       <enum name="endpoint">
+                               <para>R/O The name of the endpoint associated with this channel.
+                               Use the <replaceable>PJSIP_ENDPOINT</replaceable> function to obtain
+                               further endpoint related information.</para>
+                       </enum>
+                       <enum name="contact">
+                               <para>R/O The name of the contact associated with this channel.
+                               Use the <replaceable>PJSIP_CONTACT</replaceable> function to obtain
+                               further contact related information. Note this may not be present and if so
+                               is only available on outgoing legs.</para>
+                       </enum>
+                       <enum name="aor">
+                               <para>R/O The name of the AOR associated with this channel.
+                               Use the <replaceable>PJSIP_AOR</replaceable> function to obtain
+                               further AOR related information. Note this may not be present and if so
+                               is only available on outgoing legs.</para>
+                       </enum>
+                       <enum name="pjsip">
+                               <para>R/O Obtain information about the current PJSIP channel and its
+                               session.</para>
+                               <parameter name="type" required="true">
+                                       <para>When <replaceable>pjsip</replaceable> is specified, the
+                                       <literal>type</literal> parameter must be provided. It specifies
+                                       which signalling parameter to read.</para>
+                                       <enumlist>
+                                               <enum name="call-id">
+                                                       <para>The SIP call-id.</para>
+                                               </enum>
+                                               <enum name="secure">
+                                                       <para>Whether or not the signalling uses a secure transport.</para>
+                                                       <enumlist>
+                                                               <enum name="0"><para>The signalling uses a non-secure transport.</para></enum>
+                                                               <enum name="1"><para>The signalling uses a secure transport.</para></enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="target_uri">
+                                                       <para>The contact URI where requests are sent.</para>
+                                               </enum>
+                                               <enum name="local_uri">
+                                                       <para>The local URI.</para>
+                                               </enum>
+                                               <enum name="local_tag">
+                                                       <para>Tag in From header</para>
+                                               </enum>
+                                               <enum name="remote_uri">
+                                                       <para>The remote URI.</para>
+                                               </enum>
+                                               <enum name="remote_tag">
+                                                       <para>Tag in To header</para>
+                                               </enum>
+                                               <enum name="request_uri">
+                                                       <para>The request URI of the incoming <literal>INVITE</literal>
+                                                       associated with the creation of this channel.</para>
+                                               </enum>
+                                               <enum name="t38state">
+                                                       <para>The current state of any T.38 fax on this channel.</para>
+                                                       <enumlist>
+                                                               <enum name="DISABLED"><para>T.38 faxing is disabled on this channel.</para></enum>
+                                                               <enum name="LOCAL_REINVITE"><para>Asterisk has sent a <literal>re-INVITE</literal> to the remote end to initiate a T.38 fax.</para></enum>
+                                                               <enum name="REMOTE_REINVITE"><para>The remote end has sent a <literal>re-INVITE</literal> to Asterisk to initiate a T.38 fax.</para></enum>
+                                                               <enum name="ENABLED"><para>A T.38 fax session has been enabled.</para></enum>
+                                                               <enum name="REJECTED"><para>A T.38 fax session was attempted but was rejected.</para></enum>
+                                                       </enumlist>
+                                               </enum>
+                                               <enum name="local_addr">
+                                                       <para>On inbound calls, the full IP address and port number that
+                                                       the <literal>INVITE</literal> request was received on. On outbound
+                                                       calls, the full IP address and port number that the <literal>INVITE</literal>
+                                                       request was transmitted from.</para>
+                                               </enum>
+                                               <enum name="remote_addr">
+                                                       <para>On inbound calls, the full IP address and port number that
+                                                       the <literal>INVITE</literal> request was received from. On outbound
+                                                       calls, the full IP address and port number that the <literal>INVITE</literal>
+                                                       request was transmitted to.</para>
+                                               </enum>
+                                       </enumlist>
+                               </parameter>
+                       </enum>
+               </enumlist>
+       </info>
+       <info name="CHANNEL_EXAMPLES" language="en_US" tech="PJSIP">
+               <example title="PJSIP specific CHANNEL examples">
+                       ; Log the current Call-ID
+                       same => n,Log(NOTICE, ${CHANNEL(pjsip,call-id)})
+       
+                       ; Log the destination address of the audio stream
+                       same => n,Log(NOTICE, ${CHANNEL(rtp,dest)})
+       
+                       ; Store the round-trip time associated with a
+                       ; video stream in the CDR field video-rtt
+                       same => n,Set(CDR(video-rtt)=${CHANNEL(rtcp,rtt,video)})
+               </example>
+       </info>
+</docs>
\ No newline at end of file
index d0bf130fe8fccde5ba8ee9a49b56ad8de4f44c0d..03005d5d8f2b8a3ffac0bfe7a1bcfa6b20a15844 100644 (file)
@@ -148,4 +148,24 @@ int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char
  */
 int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
 
-#endif /* _PJSIP_DIALPLAN_FUNCTIONS */
\ No newline at end of file
+/*!
+ * \brief Hang up an incoming PJSIP channel with a SIP response code
+ * \param chan The channel the function is called on
+ * \param data SIP response code or name
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int pjsip_app_hangup(struct ast_channel *chan, const char *data);
+
+/*!
+ * \brief Manager action to hang up an incoming PJSIP channel with a SIP response code
+ * \param s session
+ * \param m message
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int pjsip_action_hangup(struct mansession *s, const struct message *m);
+
+#endif /* _PJSIP_DIALPLAN_FUNCTIONS */
index b531956bbf2e476a7a31518e31145cbdfe4fc49b..923f1738cdde7cce6e6a520a6c52298a5a4af2db 100644 (file)
@@ -621,4 +621,45 @@ void ast_manager_publish_event(const char *type, int class_type, struct ast_json
  */
 struct stasis_message_router *ast_manager_get_message_router(void);
 
+/*!
+ * \brief Callback used by ast_manager_hangup_helper
+ *        that will actually hangup a channel
+ *
+ * \param chan The channel to hang up
+ * \param causecode Cause code to set on the channel
+ */
+typedef void (*manager_hangup_handler_t)(struct ast_channel *chan, int causecode);
+
+/*!
+ * \brief Callback used by ast_manager_hangup_helper
+ *        that will validate the cause code.
+
+ * \param channel_name Mostly for displaying log messages
+ * \param cause Cause code string
+ *
+ * \returns integer cause code
+ */
+typedef int (*manager_hangup_cause_validator_t)(const char *channel_name,
+       const char *cause);
+
+/*!
+ * \brief A manager helper function that hangs up a channel using a supplied
+ *        channel type specific hangup function and cause code validator
+ *
+ * This function handles the lookup of channel(s) and the AMI interaction
+ * but uses the supplied callbacks to actually perform the hangup.  It can be
+ * used to implement a custom AMI 'Hangup' action without having to duplicate
+ * all the code in the standard Hangup action.
+ *
+ * \param s Session
+ * \param m Message
+ * \param handler Function that actually performs the hangup
+ * \param cause_validator Function that validates the cause code
+ *
+ * \retval 0 on success.
+ * \retval non-zero on error.
+ */
+int ast_manager_hangup_helper(struct mansession *s, const struct message *m,
+       manager_hangup_handler_t handler, manager_hangup_cause_validator_t cause_validator);
+
 #endif /* _ASTERISK_MANAGER_H */
index 0f68a9bbcbab95460d7a4cc64256dcf0fedefed8..949f66fdc536eeff13ad4ec08bb2bfe6edb62dab 100644 (file)
@@ -4212,5 +4212,17 @@ unsigned int ast_sip_get_all_codecs_on_empty_reinvite(void);
  */
 const int ast_sip_hangup_sip2cause(int cause);
 
+/*!
+ * \brief Convert name to SIP response code
+ *
+ * \param name SIP response code name matching one of the
+ *             enum names defined in "enum pjsip_status_code"
+ *             defined in sip_msg.h.  May be specified with or
+ *             without the PJSIP_SC_ prefix.
+ *
+ * \retval SIP response code
+ * \retval -1 if matching code not found
+ */
+int ast_sip_str2rc(const char *name);
 
 #endif /* _RES_PJSIP_H */
index 47ccaa6e8f32342de2726f5f9b0a3a464390e1a8..490ac116e893f64db3bd9051087ddb90b44fef39 100644 (file)
@@ -4649,7 +4649,9 @@ static int action_challenge(struct mansession *s, const struct message *m)
        return 0;
 }
 
-static int action_hangup(struct mansession *s, const struct message *m)
+int ast_manager_hangup_helper(struct mansession *s,
+       const struct message *m, manager_hangup_handler_t hangup_handler,
+       manager_hangup_cause_validator_t cause_validator)
 {
        struct ast_channel *c = NULL;
        int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
@@ -4673,7 +4675,9 @@ static int action_hangup(struct mansession *s, const struct message *m)
                idText[0] = '\0';
        }
 
-       if (!ast_strlen_zero(cause)) {
+       if (cause_validator) {
+               causecode = cause_validator(name_or_regex, cause);
+       } else if (!ast_strlen_zero(cause)) {
                char *endptr;
                causecode = strtol(cause, &endptr, 10);
                if (causecode < 0 || causecode > 127 || *endptr != '\0') {
@@ -4700,7 +4704,7 @@ static int action_hangup(struct mansession *s, const struct message *m)
                        ast_sockaddr_stringify_addr(&s->session->addr),
                        ast_channel_name(c));
 
-               ast_channel_softhangup_withcause_locked(c, causecode);
+               hangup_handler(c, causecode);
                c = ast_channel_unref(c);
 
                astman_send_ack(s, m, "Channel Hungup");
@@ -4746,7 +4750,7 @@ static int action_hangup(struct mansession *s, const struct message *m)
                                ast_sockaddr_stringify_addr(&s->session->addr),
                                ast_channel_name(c));
 
-                       ast_channel_softhangup_withcause_locked(c, causecode);
+                       hangup_handler(c, causecode);
                        channels_matched++;
 
                        astman_append(s,
@@ -4766,6 +4770,12 @@ static int action_hangup(struct mansession *s, const struct message *m)
        return 0;
 }
 
+static int action_hangup(struct mansession *s, const struct message *m)
+{
+       return ast_manager_hangup_helper(s, m,
+               ast_channel_softhangup_withcause_locked, NULL);
+}
+
 static int action_setvar(struct mansession *s, const struct message *m)
 {
        struct ast_channel *c = NULL;
index 781446eb2a54f819a1a872fc5ba2e4f8afed792b..50bb6575fa30b5417bd2350c0448cdc9df0c173e 100644 (file)
@@ -3618,6 +3618,118 @@ const int ast_sip_hangup_sip2cause(int cause)
        return 0;
 }
 
+struct response_code_map {
+       int code;
+       const char *long_name;
+       const char *short_name;
+};
+
+/*
+ * This map was generated from sip_msg.h with
+ *
+ * sed -n -r -e 's/^\s+(PJSIP_SC_([^ =]+))\s*=\s*[0-9]+,/{ \1, "\1", "\2" },/gp' \
+ *     third-party/pjproject/source/pjsip/include/pjsip/sip_msg.h
+ *
+ */
+static const struct response_code_map rc_map[] = {
+       { PJSIP_SC_NULL, "PJSIP_SC_NULL", "NULL" },
+       { PJSIP_SC_TRYING, "PJSIP_SC_TRYING", "TRYING" },
+       { PJSIP_SC_RINGING, "PJSIP_SC_RINGING", "RINGING" },
+       { PJSIP_SC_CALL_BEING_FORWARDED, "PJSIP_SC_CALL_BEING_FORWARDED", "CALL_BEING_FORWARDED" },
+       { PJSIP_SC_QUEUED, "PJSIP_SC_QUEUED", "QUEUED" },
+       { PJSIP_SC_PROGRESS, "PJSIP_SC_PROGRESS", "PROGRESS" },
+       { PJSIP_SC_EARLY_DIALOG_TERMINATED, "PJSIP_SC_EARLY_DIALOG_TERMINATED", "EARLY_DIALOG_TERMINATED" },
+       { PJSIP_SC_OK, "PJSIP_SC_OK", "OK" },
+       { PJSIP_SC_ACCEPTED, "PJSIP_SC_ACCEPTED", "ACCEPTED" },
+       { PJSIP_SC_NO_NOTIFICATION, "PJSIP_SC_NO_NOTIFICATION", "NO_NOTIFICATION" },
+       { PJSIP_SC_MULTIPLE_CHOICES, "PJSIP_SC_MULTIPLE_CHOICES", "MULTIPLE_CHOICES" },
+       { PJSIP_SC_MOVED_PERMANENTLY, "PJSIP_SC_MOVED_PERMANENTLY", "MOVED_PERMANENTLY" },
+       { PJSIP_SC_MOVED_TEMPORARILY, "PJSIP_SC_MOVED_TEMPORARILY", "MOVED_TEMPORARILY" },
+       { PJSIP_SC_USE_PROXY, "PJSIP_SC_USE_PROXY", "USE_PROXY" },
+       { PJSIP_SC_ALTERNATIVE_SERVICE, "PJSIP_SC_ALTERNATIVE_SERVICE", "ALTERNATIVE_SERVICE" },
+       { PJSIP_SC_BAD_REQUEST, "PJSIP_SC_BAD_REQUEST", "BAD_REQUEST" },
+       { PJSIP_SC_UNAUTHORIZED, "PJSIP_SC_UNAUTHORIZED", "UNAUTHORIZED" },
+       { PJSIP_SC_PAYMENT_REQUIRED, "PJSIP_SC_PAYMENT_REQUIRED", "PAYMENT_REQUIRED" },
+       { PJSIP_SC_FORBIDDEN, "PJSIP_SC_FORBIDDEN", "FORBIDDEN" },
+       { PJSIP_SC_NOT_FOUND, "PJSIP_SC_NOT_FOUND", "NOT_FOUND" },
+       { PJSIP_SC_METHOD_NOT_ALLOWED, "PJSIP_SC_METHOD_NOT_ALLOWED", "METHOD_NOT_ALLOWED" },
+       { PJSIP_SC_NOT_ACCEPTABLE, "PJSIP_SC_NOT_ACCEPTABLE", "NOT_ACCEPTABLE" },
+       { PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED, "PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED", "PROXY_AUTHENTICATION_REQUIRED" },
+       { PJSIP_SC_REQUEST_TIMEOUT, "PJSIP_SC_REQUEST_TIMEOUT", "REQUEST_TIMEOUT" },
+       { PJSIP_SC_CONFLICT, "PJSIP_SC_CONFLICT", "CONFLICT" },
+       { PJSIP_SC_GONE, "PJSIP_SC_GONE", "GONE" },
+       { PJSIP_SC_LENGTH_REQUIRED, "PJSIP_SC_LENGTH_REQUIRED", "LENGTH_REQUIRED" },
+       { PJSIP_SC_CONDITIONAL_REQUEST_FAILED, "PJSIP_SC_CONDITIONAL_REQUEST_FAILED", "CONDITIONAL_REQUEST_FAILED" },
+       { PJSIP_SC_REQUEST_ENTITY_TOO_LARGE, "PJSIP_SC_REQUEST_ENTITY_TOO_LARGE", "REQUEST_ENTITY_TOO_LARGE" },
+       { PJSIP_SC_REQUEST_URI_TOO_LONG, "PJSIP_SC_REQUEST_URI_TOO_LONG", "REQUEST_URI_TOO_LONG" },
+       { PJSIP_SC_UNSUPPORTED_MEDIA_TYPE, "PJSIP_SC_UNSUPPORTED_MEDIA_TYPE", "UNSUPPORTED_MEDIA_TYPE" },
+       { PJSIP_SC_UNSUPPORTED_URI_SCHEME, "PJSIP_SC_UNSUPPORTED_URI_SCHEME", "UNSUPPORTED_URI_SCHEME" },
+       { PJSIP_SC_UNKNOWN_RESOURCE_PRIORITY, "PJSIP_SC_UNKNOWN_RESOURCE_PRIORITY", "UNKNOWN_RESOURCE_PRIORITY" },
+       { PJSIP_SC_BAD_EXTENSION, "PJSIP_SC_BAD_EXTENSION", "BAD_EXTENSION" },
+       { PJSIP_SC_EXTENSION_REQUIRED, "PJSIP_SC_EXTENSION_REQUIRED", "EXTENSION_REQUIRED" },
+       { PJSIP_SC_SESSION_TIMER_TOO_SMALL, "PJSIP_SC_SESSION_TIMER_TOO_SMALL", "SESSION_TIMER_TOO_SMALL" },
+       { PJSIP_SC_INTERVAL_TOO_BRIEF, "PJSIP_SC_INTERVAL_TOO_BRIEF", "INTERVAL_TOO_BRIEF" },
+       { PJSIP_SC_BAD_LOCATION_INFORMATION, "PJSIP_SC_BAD_LOCATION_INFORMATION", "BAD_LOCATION_INFORMATION" },
+       { PJSIP_SC_USE_IDENTITY_HEADER, "PJSIP_SC_USE_IDENTITY_HEADER", "USE_IDENTITY_HEADER" },
+       { PJSIP_SC_PROVIDE_REFERRER_HEADER, "PJSIP_SC_PROVIDE_REFERRER_HEADER", "PROVIDE_REFERRER_HEADER" },
+       { PJSIP_SC_FLOW_FAILED, "PJSIP_SC_FLOW_FAILED", "FLOW_FAILED" },
+       { PJSIP_SC_ANONIMITY_DISALLOWED, "PJSIP_SC_ANONIMITY_DISALLOWED", "ANONIMITY_DISALLOWED" },
+       { PJSIP_SC_BAD_IDENTITY_INFO, "PJSIP_SC_BAD_IDENTITY_INFO", "BAD_IDENTITY_INFO" },
+       { PJSIP_SC_UNSUPPORTED_CERTIFICATE, "PJSIP_SC_UNSUPPORTED_CERTIFICATE", "UNSUPPORTED_CERTIFICATE" },
+       { PJSIP_SC_INVALID_IDENTITY_HEADER, "PJSIP_SC_INVALID_IDENTITY_HEADER", "INVALID_IDENTITY_HEADER" },
+       { PJSIP_SC_FIRST_HOP_LACKS_OUTBOUND_SUPPORT, "PJSIP_SC_FIRST_HOP_LACKS_OUTBOUND_SUPPORT", "FIRST_HOP_LACKS_OUTBOUND_SUPPORT" },
+       { PJSIP_SC_MAX_BREADTH_EXCEEDED, "PJSIP_SC_MAX_BREADTH_EXCEEDED", "MAX_BREADTH_EXCEEDED" },
+       { PJSIP_SC_BAD_INFO_PACKAGE, "PJSIP_SC_BAD_INFO_PACKAGE", "BAD_INFO_PACKAGE" },
+       { PJSIP_SC_CONSENT_NEEDED, "PJSIP_SC_CONSENT_NEEDED", "CONSENT_NEEDED" },
+       { PJSIP_SC_TEMPORARILY_UNAVAILABLE, "PJSIP_SC_TEMPORARILY_UNAVAILABLE", "TEMPORARILY_UNAVAILABLE" },
+       { PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, "PJSIP_SC_CALL_TSX_DOES_NOT_EXIST", "CALL_TSX_DOES_NOT_EXIST" },
+       { PJSIP_SC_LOOP_DETECTED, "PJSIP_SC_LOOP_DETECTED", "LOOP_DETECTED" },
+       { PJSIP_SC_TOO_MANY_HOPS, "PJSIP_SC_TOO_MANY_HOPS", "TOO_MANY_HOPS" },
+       { PJSIP_SC_ADDRESS_INCOMPLETE, "PJSIP_SC_ADDRESS_INCOMPLETE", "ADDRESS_INCOMPLETE" },
+       { PJSIP_SC_BUSY_HERE, "PJSIP_SC_BUSY_HERE", "BUSY_HERE" },
+       { PJSIP_SC_REQUEST_TERMINATED, "PJSIP_SC_REQUEST_TERMINATED", "REQUEST_TERMINATED" },
+       { PJSIP_SC_NOT_ACCEPTABLE_HERE, "PJSIP_SC_NOT_ACCEPTABLE_HERE", "NOT_ACCEPTABLE_HERE" },
+       { PJSIP_SC_BAD_EVENT, "PJSIP_SC_BAD_EVENT", "BAD_EVENT" },
+       { PJSIP_SC_REQUEST_UPDATED, "PJSIP_SC_REQUEST_UPDATED", "REQUEST_UPDATED" },
+       { PJSIP_SC_REQUEST_PENDING, "PJSIP_SC_REQUEST_PENDING", "REQUEST_PENDING" },
+       { PJSIP_SC_UNDECIPHERABLE, "PJSIP_SC_UNDECIPHERABLE", "UNDECIPHERABLE" },
+       { PJSIP_SC_SECURITY_AGREEMENT_NEEDED, "PJSIP_SC_SECURITY_AGREEMENT_NEEDED", "SECURITY_AGREEMENT_NEEDED" },
+       { PJSIP_SC_INTERNAL_SERVER_ERROR, "PJSIP_SC_INTERNAL_SERVER_ERROR", "INTERNAL_SERVER_ERROR" },
+       { PJSIP_SC_NOT_IMPLEMENTED, "PJSIP_SC_NOT_IMPLEMENTED", "NOT_IMPLEMENTED" },
+       { PJSIP_SC_BAD_GATEWAY, "PJSIP_SC_BAD_GATEWAY", "BAD_GATEWAY" },
+       { PJSIP_SC_SERVICE_UNAVAILABLE, "PJSIP_SC_SERVICE_UNAVAILABLE", "SERVICE_UNAVAILABLE" },
+       { PJSIP_SC_SERVER_TIMEOUT, "PJSIP_SC_SERVER_TIMEOUT", "SERVER_TIMEOUT" },
+       { PJSIP_SC_VERSION_NOT_SUPPORTED, "PJSIP_SC_VERSION_NOT_SUPPORTED", "VERSION_NOT_SUPPORTED" },
+       { PJSIP_SC_MESSAGE_TOO_LARGE, "PJSIP_SC_MESSAGE_TOO_LARGE", "MESSAGE_TOO_LARGE" },
+       { PJSIP_SC_PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED, "PJSIP_SC_PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED", "PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED" },
+       { PJSIP_SC_PRECONDITION_FAILURE, "PJSIP_SC_PRECONDITION_FAILURE", "PRECONDITION_FAILURE" },
+       { PJSIP_SC_BUSY_EVERYWHERE, "PJSIP_SC_BUSY_EVERYWHERE", "BUSY_EVERYWHERE" },
+       { PJSIP_SC_DECLINE, "PJSIP_SC_DECLINE", "DECLINE" },
+       { PJSIP_SC_DOES_NOT_EXIST_ANYWHERE, "PJSIP_SC_DOES_NOT_EXIST_ANYWHERE", "DOES_NOT_EXIST_ANYWHERE" },
+       { PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE, "PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE", "NOT_ACCEPTABLE_ANYWHERE" },
+       { PJSIP_SC_UNWANTED, "PJSIP_SC_UNWANTED", "UNWANTED" },
+       { PJSIP_SC_REJECTED, "PJSIP_SC_REJECTED", "REJECTED" },
+};
+
+int ast_sip_str2rc(const char *name)
+{
+       int i;
+
+       if (ast_strlen_zero(name)) {
+               return -1;
+       }
+
+       for (i = 0; i < ARRAY_LEN(rc_map); i++) {
+               if (strcasecmp(rc_map[i].short_name, name) == 0 ||
+                       strcasecmp(rc_map[i].long_name, name) == 0) {
+                       return rc_map[i].code;
+               }
+       }
+
+       return -1;
+}
+
+
 #ifdef TEST_FRAMEWORK
 AST_TEST_DEFINE(xml_sanitization_end_null)
 {