chan_pjsip: add a new function PJSIP_DTMF_MODE

This function is a replica of SIPDtmfMode, allowing the DTMF mode of a
PJSIP call to be modified on a per-call basis

ASTERISK-27085 #close

Change-Id: I20eef5da3e5d1d3e58b304416bc79683f87e7612
This commit is contained in:
Torrey Searle
2017-06-26 14:52:52 +02:00
committed by George Joseph
parent b3914df10b
commit 65c560894d
10 changed files with 294 additions and 37 deletions

View File

@@ -37,6 +37,9 @@ res_musiconhold
which sends signals to the application and its descendants directly, or which sends signals to the application and its descendants directly, or
"process" which sends signals only to the application itself. "process" which sends signals only to the application itself.
* New dialplan function PJSIP_DTMF_MODE added to get or change the DTMF mode
of a channel on a per-call basis.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
--- Functionality changes from Asterisk 14.5.0 to Asterisk 14.6.0 ------------ --- Functionality changes from Asterisk 14.5.0 to Asterisk 14.6.0 ------------
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View File

@@ -1947,7 +1947,7 @@ static int chan_pjsip_digit_begin(struct ast_channel *chan, char digit)
media = channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]; media = channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
switch (channel->session->endpoint->dtmf) { switch (channel->session->dtmf) {
case AST_SIP_DTMF_RFC_4733: case AST_SIP_DTMF_RFC_4733:
if (!media || !media->rtp) { if (!media || !media->rtp) {
return -1; return -1;
@@ -2068,7 +2068,7 @@ static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned in
media = channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]; media = channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
switch (channel->session->endpoint->dtmf) { switch (channel->session->dtmf) {
case AST_SIP_DTMF_AUTO_INFO: case AST_SIP_DTMF_AUTO_INFO:
{ {
if (!media || !media->rtp) { if (!media || !media->rtp) {
@@ -2893,6 +2893,12 @@ 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 dtmf_mode_function = {
.name = "PJSIP_DTMF_MODE",
.read = pjsip_acf_dtmf_mode_read,
.write = pjsip_acf_dtmf_mode_write
};
static struct ast_custom_function session_refresh_function = { static struct ast_custom_function session_refresh_function = {
.name = "PJSIP_SEND_SESSION_REFRESH", .name = "PJSIP_SEND_SESSION_REFRESH",
.write = pjsip_acf_session_refresh_write, .write = pjsip_acf_session_refresh_write,
@@ -2937,6 +2943,11 @@ static int load_module(void)
goto end; goto end;
} }
if (ast_custom_function_register(&dtmf_mode_function)) {
ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
goto end;
}
if (ast_custom_function_register(&session_refresh_function)) { if (ast_custom_function_register(&session_refresh_function)) {
ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n"); ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
goto end; goto end;
@@ -2996,6 +3007,7 @@ static int load_module(void)
end: end:
ao2_cleanup(pjsip_uids_onhold); ao2_cleanup(pjsip_uids_onhold);
pjsip_uids_onhold = NULL; pjsip_uids_onhold = NULL;
ast_custom_function_unregister(&dtmf_mode_function);
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_custom_function_unregister(&session_refresh_function);
@@ -3018,6 +3030,7 @@ static int unload_module(void)
ast_sip_session_unregister_supplement(&chan_pjsip_ack_supplement); ast_sip_session_unregister_supplement(&chan_pjsip_ack_supplement);
ast_sip_session_unregister_supplement(&call_pickup_supplement); ast_sip_session_unregister_supplement(&call_pickup_supplement);
ast_custom_function_unregister(&dtmf_mode_function);
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_custom_function_unregister(&session_refresh_function);

View File

@@ -68,6 +68,18 @@
<ref type="function">PJSIP_SEND_SESSION_REFRESH</ref> <ref type="function">PJSIP_SEND_SESSION_REFRESH</ref>
</see-also> </see-also>
</function> </function>
<function name="PJSIP_DTMF_MODE" language="en_US">
<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_SEND_SESSION_REFRESH" language="en_US"> <function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
<synopsis> <synopsis>
W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session
@@ -439,6 +451,7 @@
#include "asterisk/channel.h" #include "asterisk/channel.h"
#include "asterisk/stream.h" #include "asterisk/stream.h"
#include "asterisk/format.h" #include "asterisk/format.h"
#include "asterisk/dsp.h"
#include "asterisk/pbx.h" #include "asterisk/pbx.h"
#include "asterisk/res_pjsip.h" #include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h" #include "asterisk/res_pjsip_session.h"
@@ -1167,6 +1180,34 @@ 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);
} }
int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
struct ast_sip_channel_pvt *channel;
if (!chan) {
ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
return -1;
}
ast_channel_lock(chan);
if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
ast_channel_unlock(chan);
return -1;
}
channel = ast_channel_tech_pvt(chan);
if (ast_sip_dtmf_to_str(channel->session->dtmf, buf, len) < 0) {
ast_log(LOG_WARNING, "Unknown DTMF mode %d on PJSIP channel %s\n", channel->session->dtmf, ast_channel_name(chan));
ast_channel_unlock(chan);
return -1;
}
ast_channel_unlock(chan);
return 0;
}
struct refresh_data { struct refresh_data {
struct ast_sip_session *session; struct ast_sip_session *session;
enum ast_sip_session_refresh_method method; enum ast_sip_session_refresh_method method;
@@ -1195,6 +1236,118 @@ static int sip_session_response_cb(struct ast_sip_session *session, pjsip_rx_dat
return 0; return 0;
} }
static int dtmf_mode_refresh_cb(void *obj)
{
struct refresh_data *data = obj;
if (data->session->inv_session->state == PJSIP_INV_STATE_CONFIRMED) {
ast_debug(3, "Changing DTMF mode on channel %s after OFFER/ANSER completion. Sending session refresh\n", ast_channel_name(data->session->channel));
ast_sip_session_refresh(data->session, NULL, NULL,
sip_session_response_cb, data->method, 1, NULL);
}
return 0;
}
int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
{
struct ast_sip_channel_pvt *channel;
struct ast_sip_session_media *media;
int dsp_features = 0;
int dtmf = -1;
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;
}
ast_channel_lock(chan);
if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
ast_channel_unlock(chan);
return -1;
}
channel = ast_channel_tech_pvt(chan);
rdata.session = channel->session;
dtmf = ast_sip_str_to_dtmf(value);
if (dtmf == -1) {
ast_log(LOG_WARNING, "Cannot set DTMF mode to '%s' on channel '%s' as value is invalid.\n", value,
ast_channel_name(chan));
ast_channel_unlock(chan);
return -1;
}
if (channel->session->dtmf == dtmf) {
/* DTMF mode unchanged, nothing to do! */
ast_channel_unlock(chan);
return 0;
}
channel->session->dtmf = dtmf;
media = channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
if (media && media->rtp) {
if (channel->session->dtmf == AST_SIP_DTMF_RFC_4733) {
ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_DTMF, 1);
ast_rtp_instance_dtmf_mode_set(media->rtp, AST_RTP_DTMF_MODE_RFC2833);
} else if (channel->session->dtmf == AST_SIP_DTMF_INFO) {
ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_DTMF, 0);
ast_rtp_instance_dtmf_mode_set(media->rtp, AST_RTP_DTMF_MODE_NONE);
} else if (channel->session->dtmf == AST_SIP_DTMF_INBAND) {
ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_DTMF, 0);
ast_rtp_instance_dtmf_mode_set(media->rtp, AST_RTP_DTMF_MODE_INBAND);
} else if (channel->session->dtmf == AST_SIP_DTMF_NONE) {
ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_DTMF, 0);
ast_rtp_instance_dtmf_mode_set(media->rtp, AST_RTP_DTMF_MODE_NONE);
} else if (channel->session->dtmf == AST_SIP_DTMF_AUTO) {
if (ast_rtp_instance_dtmf_mode_get(media->rtp) != AST_RTP_DTMF_MODE_RFC2833) {
/* no RFC4733 negotiated, enable inband */
ast_rtp_instance_dtmf_mode_set(media->rtp, AST_RTP_DTMF_MODE_INBAND);
}
} else if (channel->session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_DTMF, 0);
if (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND) {
/* if inband, switch to INFO */
ast_rtp_instance_dtmf_mode_set(media->rtp, AST_RTP_DTMF_MODE_NONE);
}
}
}
if (channel->session->dsp) {
dsp_features = ast_dsp_get_features(channel->session->dsp);
}
if (channel->session->dtmf == AST_SIP_DTMF_INBAND ||
channel->session->dtmf == AST_SIP_DTMF_AUTO) {
dsp_features |= DSP_FEATURE_DIGIT_DETECT;
} else {
dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
}
if (dsp_features) {
if (!channel->session->dsp) {
if (!(channel->session->dsp = ast_dsp_new())) {
ast_channel_unlock(chan);
return 0;
}
}
ast_dsp_set_features(channel->session->dsp, dsp_features);
} else if (channel->session->dsp) {
ast_dsp_free(channel->session->dsp);
channel->session->dsp = NULL;
}
ast_channel_unlock(chan);
return ast_sip_push_task_synchronous(channel->session->serializer, dtmf_mode_refresh_cb, &rdata);
}
static int refresh_write_cb(void *obj) static int refresh_write_cb(void *obj)
{ {
struct refresh_data *data = obj; struct refresh_data *data = obj;

View File

@@ -47,6 +47,31 @@ int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data
*/ */
int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value); int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
/*!
* \brief PJSIP_DTMF_MODE function read 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 buf Out buffer that should be populated with the data
* \param len Size of the buffer
*
* \retval 0 on success
* \retval -1 on failure
*/
int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
/*!
* \brief PJSIP_DTMF_MODE 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_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
/*! /*!
* \brief PJSIP_MEDIA_OFFER function read callback * \brief PJSIP_MEDIA_OFFER function read callback
* \param chan The channel the function is called on * \param chan The channel the function is called on

View File

@@ -2889,4 +2889,31 @@ int ast_sip_set_tpselector_from_ep_or_uri(const struct ast_sip_endpoint *endpoin
int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg, int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg,
pjsip_tpselector *selector); pjsip_tpselector *selector);
/*!
* \brief Convert the DTMF mode enum value into a string
* \since 13.18.0
*
* \param dtmf the dtmf mode
* \param buf Buffer to receive dtmf mode string
* \param buf_len Buffer length
*
* \retval 0 Success
* \retval -1 Failure
*
*/
int ast_sip_dtmf_to_str(const enum ast_sip_dtmf_mode dtmf,
char *buf, size_t buf_len);
/*!
* \brief Convert the DTMF mode name into an enum
* \since 13.18.0
*
* \param dtmf_mode dtmf mode as a string
*
* \retval >= 0 The enum value
* \retval -1 Failure
*
*/
int ast_sip_str_to_dtmf(const char *dtmf_mode);
#endif /* _RES_PJSIP_H */ #endif /* _RES_PJSIP_H */

View File

@@ -203,6 +203,8 @@ struct ast_sip_session {
unsigned int defer_end:1; unsigned int defer_end:1;
/*! Session end (remote hangup) requested while termination deferred */ /*! Session end (remote hangup) requested while termination deferred */
unsigned int ended_while_deferred:1; unsigned int ended_while_deferred:1;
/*! DTMF mode to use with this session, from endpoint but can change */
enum ast_sip_dtmf_mode dtmf;
}; };
typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata); typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);

View File

@@ -4483,6 +4483,56 @@ const char *ast_sip_get_host_ip_string(int af)
return NULL; return NULL;
} }
int ast_sip_dtmf_to_str(const enum ast_sip_dtmf_mode dtmf,
char *buf, size_t buf_len)
{
switch (dtmf) {
case AST_SIP_DTMF_NONE:
ast_copy_string(buf, "none", buf_len);
break;
case AST_SIP_DTMF_RFC_4733:
ast_copy_string(buf, "rfc4733", buf_len);
break;
case AST_SIP_DTMF_INBAND:
ast_copy_string(buf, "inband", buf_len);
break;
case AST_SIP_DTMF_INFO:
ast_copy_string(buf, "info", buf_len);
break;
case AST_SIP_DTMF_AUTO:
ast_copy_string(buf, "auto", buf_len);
break;
case AST_SIP_DTMF_AUTO_INFO:
ast_copy_string(buf, "auto_info", buf_len);
break;
default:
buf[0] = '\0';
return -1;
}
return 0;
}
int ast_sip_str_to_dtmf(const char * dtmf_mode)
{
int result = -1;
if (!strcasecmp(dtmf_mode, "info")) {
result = AST_SIP_DTMF_INFO;
} else if (!strcasecmp(dtmf_mode, "rfc4733")) {
result = AST_SIP_DTMF_RFC_4733;
} else if (!strcasecmp(dtmf_mode, "inband")) {
result = AST_SIP_DTMF_INBAND;
} else if (!strcasecmp(dtmf_mode, "none")) {
result = AST_SIP_DTMF_NONE;
} else if (!strcasecmp(dtmf_mode, "auto")) {
result = AST_SIP_DTMF_AUTO;
} else if (!strcasecmp(dtmf_mode, "auto_info")) {
result = AST_SIP_DTMF_AUTO_INFO;
}
return result;
}
/*! /*!
* \brief Set name and number information on an identity header. * \brief Set name and number information on an identity header.
* *

View File

@@ -366,47 +366,29 @@ static int contact_acl_to_str(const void *obj, const intptr_t *args, char **buf)
static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
{ {
struct ast_sip_endpoint *endpoint = obj; struct ast_sip_endpoint *endpoint = obj;
enum ast_sip_dtmf_mode dtmf = ast_sip_str_to_dtmf(var->value);
if (!strcasecmp(var->value, "rfc4733")) { if (dtmf == -1) {
endpoint->dtmf = AST_SIP_DTMF_RFC_4733;
} else if (!strcasecmp(var->value, "inband")) {
endpoint->dtmf = AST_SIP_DTMF_INBAND;
} else if (!strcasecmp(var->value, "auto_info")) {
endpoint->dtmf = AST_SIP_DTMF_AUTO_INFO;
} else if (!strcasecmp(var->value, "info")) {
endpoint->dtmf = AST_SIP_DTMF_INFO;
} else if (!strcasecmp(var->value, "auto")) {
endpoint->dtmf = AST_SIP_DTMF_AUTO;
} else if (!strcasecmp(var->value, "none")) {
endpoint->dtmf = AST_SIP_DTMF_NONE;
} else {
return -1; return -1;
} }
endpoint->dtmf = dtmf;
return 0; return 0;
} }
static int dtmf_to_str(const void *obj, const intptr_t *args, char **buf) static int dtmf_to_str(const void *obj, const intptr_t *args, char **buf)
{ {
const struct ast_sip_endpoint *endpoint = obj; const struct ast_sip_endpoint *endpoint = obj;
char dtmf_str[20];
int result = -1;
switch (endpoint->dtmf) { result = ast_sip_dtmf_to_str(endpoint->dtmf, dtmf_str, sizeof(dtmf_str));
case AST_SIP_DTMF_RFC_4733 :
*buf = "rfc4733"; break; if (result == 0) {
case AST_SIP_DTMF_INBAND : *buf = ast_strdup(dtmf_str);
*buf = "inband"; break; } else {
case AST_SIP_DTMF_INFO : *buf = ast_strdup("none");
*buf = "info"; break;
case AST_SIP_DTMF_AUTO :
*buf = "auto"; break;
case AST_SIP_DTMF_AUTO_INFO :
*buf = "auto_info";
break;
default:
*buf = "none";
} }
*buf = ast_strdup(*buf);
return 0; return 0;
} }

View File

@@ -207,10 +207,10 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me
ice->stop(session_media->rtp); ice->stop(session_media->rtp);
} }
if (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO || session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) { if (session->dtmf == AST_SIP_DTMF_RFC_4733 || session->dtmf == AST_SIP_DTMF_AUTO || session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833); ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833);
ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 1); ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 1);
} else if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND) { } else if (session->dtmf == AST_SIP_DTMF_INBAND) {
ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);
} }
@@ -293,11 +293,11 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp
} }
} }
} }
if (!tel_event && (session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) { if (!tel_event && (session->dtmf == AST_SIP_DTMF_AUTO)) {
ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);
} }
if (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) { if (session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
if (tel_event) { if (tel_event) {
ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833); ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833);
} else { } else {
@@ -434,7 +434,7 @@ static int set_caps(struct ast_sip_session *session,
ast_set_write_format(session->channel, ast_channel_writeformat(session->channel)); ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
} }
if ( ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) || (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) ) if ( ((session->dtmf == AST_SIP_DTMF_AUTO) || (session->dtmf == AST_SIP_DTMF_AUTO_INFO) )
&& (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833) && (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833)
&& (session->dsp)) { && (session->dsp)) {
dsp_features = ast_dsp_get_features(session->dsp); dsp_features = ast_dsp_get_features(session->dsp);
@@ -1314,7 +1314,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
pj_str_t stmp; pj_str_t stmp;
pjmedia_sdp_attr *attr; pjmedia_sdp_attr *attr;
int index = 0; int index = 0;
int noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO || session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) ? AST_RTP_DTMF : 0; int noncodec = (session->dtmf == AST_SIP_DTMF_RFC_4733 || session->dtmf == AST_SIP_DTMF_AUTO || session->dtmf == AST_SIP_DTMF_AUTO_INFO) ? AST_RTP_DTMF : 0;
int min_packet_size = 0, max_packet_size = 0; int min_packet_size = 0, max_packet_size = 0;
int rtp_code; int rtp_code;
RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);

View File

@@ -2013,6 +2013,8 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
session->contact = ao2_bump(contact); session->contact = ao2_bump(contact);
session->inv_session = inv_session; session->inv_session = inv_session;
session->dtmf = endpoint->dtmf;
if (add_supplements(session)) { if (add_supplements(session)) {
/* Release the ref held by session->inv_session */ /* Release the ref held by session->inv_session */
ao2_ref(session, -1); ao2_ref(session, -1);