mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 04:11:08 +00:00
channels/chan_pjsip: Add PJSIP_SEND_SESSION_REFRESH
This patch adds a new PJSIP specific dialplan function,
PJSIP_SEND_SESSION_REFRESH. When invoked on a PJSIP channel, the media
session will be refreshed via either an UPDATE or re-INVITE request.
When used in conjunction with the PJSIP_MEDIA_OFFER dialplan function,
the formats in use on a PJSIP channel can be re-negotiated and changed
dynamically after call setup.
ASTERISK-26277 #close
Change-Id: Ib98fe09ba889aafe26d58d32f0fd1323f8fd9b1b
(cherry picked from commit eec60dd773
)
This commit is contained in:
51
CHANGES
51
CHANGES
@@ -12,6 +12,37 @@
|
|||||||
--- Functionality changes from Asterisk 14 to Asterisk 15 --------------------
|
--- Functionality changes from Asterisk 14 to Asterisk 15 --------------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
--- Functionality changes from Asterisk 14.0.0 to Asterisk 14.1.0 ----------
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
app_voicemail
|
||||||
|
------------------
|
||||||
|
* Added "tps_queue_high" and "tps_queue_low" options.
|
||||||
|
The options can modify the taskprocessor alert levels for this module.
|
||||||
|
Additional information can be found in the sample configuration file at
|
||||||
|
config/samples/voicemail.conf.sample.
|
||||||
|
|
||||||
|
res_pjsip_mwi
|
||||||
|
------------------
|
||||||
|
* Added "mwi_tps_queue_high" and "mwi_tps_queue_low" global configuration
|
||||||
|
options to tune taskprocessor alert levels.
|
||||||
|
|
||||||
|
* Added "mwi_disable_initial_unsolicited" global configuration option
|
||||||
|
to disable sending unsolicited MWI to all endpoints on startup.
|
||||||
|
Additional information can be found in the sample configuration file at
|
||||||
|
config/samples/pjsip.conf.sample.
|
||||||
|
|
||||||
|
chan_pjsip
|
||||||
|
------------------
|
||||||
|
* A new dialplan function, PJSIP_SEND_SESSION_REFRESH, has been added. When
|
||||||
|
invoked, a re-INVITE or UPDATE request will be sent immediately to the
|
||||||
|
endpoint underlying the channel. When used in combination with the existing
|
||||||
|
dialplan function PJSIP_MEDIA_OFFER, this allows the formats on a PJSIP
|
||||||
|
channel to be re-negotiated and updated after session set up.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
--- Functionality changes from Asterisk 13 to Asterisk 14 --------------------
|
--- Functionality changes from Asterisk 13 to Asterisk 14 --------------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@@ -378,26 +409,6 @@ cdr_csv
|
|||||||
post-1.8 CDR columns 'peeraccount', 'linkedid', and 'sequence'.
|
post-1.8 CDR columns 'peeraccount', 'linkedid', and 'sequence'.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
--- Functionality changes from Asterisk 13.11.0 to Asterisk 13.12.0 ----------
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
app_voicemail
|
|
||||||
------------------
|
|
||||||
* Added "tps_queue_high" and "tps_queue_low" options.
|
|
||||||
The options can modify the taskprocessor alert levels for this module.
|
|
||||||
Additional information can be found in the sample configuration file at
|
|
||||||
config/samples/voicemail.conf.sample.
|
|
||||||
|
|
||||||
res_pjsip_mwi
|
|
||||||
------------------
|
|
||||||
* Added "mwi_tps_queue_high" and "mwi_tps_queue_low" global configuration
|
|
||||||
options to tune taskprocessor alert levels.
|
|
||||||
* Added "mwi_disable_initial_unsolicited" global configuration option
|
|
||||||
to disable sending unsolicited MWI to all endpoints on startup.
|
|
||||||
Additional information can be found in the sample configuration file at
|
|
||||||
config/samples/pjsip.conf.sample.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
--- Functionality changes from Asterisk 13.10.0 to Asterisk 13.11.0 ----------
|
--- Functionality changes from Asterisk 13.10.0 to Asterisk 13.11.0 ----------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@@ -2433,6 +2433,11 @@ static struct ast_custom_function media_offer_function = {
|
|||||||
.write = pjsip_acf_media_offer_write
|
.write = pjsip_acf_media_offer_write
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ast_custom_function session_refresh_function = {
|
||||||
|
.name = "PJSIP_SEND_SESSION_REFRESH",
|
||||||
|
.write = pjsip_acf_session_refresh_write,
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Load the module
|
* \brief Load the module
|
||||||
*
|
*
|
||||||
@@ -2472,6 +2477,11 @@ static int load_module(void)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ast_custom_function_register(&session_refresh_function)) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (ast_sip_session_register_supplement(&chan_pjsip_supplement)) {
|
if (ast_sip_session_register_supplement(&chan_pjsip_supplement)) {
|
||||||
ast_log(LOG_ERROR, "Unable to register PJSIP supplement\n");
|
ast_log(LOG_ERROR, "Unable to register PJSIP supplement\n");
|
||||||
goto end;
|
goto end;
|
||||||
@@ -2528,6 +2538,7 @@ end:
|
|||||||
pjsip_uids_onhold = NULL;
|
pjsip_uids_onhold = NULL;
|
||||||
ast_custom_function_unregister(&media_offer_function);
|
ast_custom_function_unregister(&media_offer_function);
|
||||||
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
|
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
|
||||||
|
ast_custom_function_unregister(&session_refresh_function);
|
||||||
ast_channel_unregister(&chan_pjsip_tech);
|
ast_channel_unregister(&chan_pjsip_tech);
|
||||||
ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
|
ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
|
||||||
|
|
||||||
@@ -2549,6 +2560,7 @@ static int unload_module(void)
|
|||||||
|
|
||||||
ast_custom_function_unregister(&media_offer_function);
|
ast_custom_function_unregister(&media_offer_function);
|
||||||
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
|
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
|
||||||
|
ast_custom_function_unregister(&session_refresh_function);
|
||||||
|
|
||||||
ast_channel_unregister(&chan_pjsip_tech);
|
ast_channel_unregister(&chan_pjsip_tech);
|
||||||
ao2_ref(chan_pjsip_tech.capabilities, -1);
|
ao2_ref(chan_pjsip_tech.capabilities, -1);
|
||||||
|
@@ -59,8 +59,55 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
</syntax>
|
</syntax>
|
||||||
<description>
|
<description>
|
||||||
<para>Returns the codecs offered based upon the media choice</para>
|
<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>
|
</description>
|
||||||
|
<see-also>
|
||||||
|
<ref type="function">PJSIP_SEND_SESSION_REFRESH</ref>
|
||||||
|
</see-also>
|
||||||
|
</function>
|
||||||
|
<function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
|
||||||
|
<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>
|
||||||
<info name="PJSIPCHANNEL" language="en_US" tech="PJSIP">
|
<info name="PJSIPCHANNEL" language="en_US" tech="PJSIP">
|
||||||
<enumlist>
|
<enumlist>
|
||||||
@@ -961,3 +1008,70 @@ int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char
|
|||||||
|
|
||||||
return ast_sip_push_task_synchronous(channel->session->serializer, media_offer_write_av, &mdata);
|
return ast_sip_push_task_synchronous(channel->session->serializer, media_offer_write_av, &mdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct refresh_data {
|
||||||
|
struct ast_sip_session *session;
|
||||||
|
enum ast_sip_session_refresh_method method;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
|
||||||
|
{
|
||||||
|
struct ast_format *fmt;
|
||||||
|
|
||||||
|
if (!session->channel) {
|
||||||
|
/* Egads! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt = ast_format_cap_get_best_by_type(ast_channel_nativeformats(session->channel), AST_MEDIA_TYPE_AUDIO);
|
||||||
|
if (!fmt) {
|
||||||
|
/* No format? That's weird. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ast_channel_set_writeformat(session->channel, fmt);
|
||||||
|
ast_channel_set_rawwriteformat(session->channel, fmt);
|
||||||
|
ast_channel_set_readformat(session->channel, fmt);
|
||||||
|
ast_channel_set_rawreadformat(session->channel, fmt);
|
||||||
|
ao2_ref(fmt, -1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int refresh_write_cb(void *obj)
|
||||||
|
{
|
||||||
|
struct refresh_data *data = obj;
|
||||||
|
|
||||||
|
ast_sip_session_refresh(data->session, NULL, NULL,
|
||||||
|
sip_session_response_cb, data->method, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
|
||||||
|
{
|
||||||
|
struct ast_sip_channel_pvt *channel;
|
||||||
|
struct refresh_data rdata = {
|
||||||
|
.method = AST_SIP_SESSION_REFRESH_METHOD_INVITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!chan) {
|
||||||
|
ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
|
||||||
|
ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = ast_channel_tech_pvt(chan);
|
||||||
|
rdata.session = channel->session;
|
||||||
|
|
||||||
|
if (!strcmp(value, "invite")) {
|
||||||
|
rdata.method = AST_SIP_SESSION_REFRESH_METHOD_INVITE;
|
||||||
|
} else if (!strcmp(value, "update")) {
|
||||||
|
rdata.method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ast_sip_push_task_synchronous(channel->session->serializer, refresh_write_cb, &rdata);
|
||||||
|
}
|
||||||
|
@@ -60,6 +60,18 @@ int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char
|
|||||||
*/
|
*/
|
||||||
int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
|
int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief PJSIP_SEND_SESSION_REFRESH function write callback
|
||||||
|
* \param chan The channel the function is called on
|
||||||
|
* \param cmd the Name of the function
|
||||||
|
* \param data Arguments passed to the function
|
||||||
|
* \param value Value to be set by the function
|
||||||
|
*
|
||||||
|
* \retval 0 on success
|
||||||
|
* \retval -1 on failure
|
||||||
|
*/
|
||||||
|
int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief PJSIP_DIAL_CONTACTS function read callback
|
* \brief PJSIP_DIAL_CONTACTS function read callback
|
||||||
* \param chan The channel the function is called on
|
* \param chan The channel the function is called on
|
||||||
|
Reference in New Issue
Block a user