diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | channels/chan_pjsip.c | 37 | ||||
-rw-r--r-- | contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py | 57 | ||||
-rw-r--r-- | include/asterisk/res_pjsip.h | 2 | ||||
-rw-r--r-- | res/res_pjsip.c | 3 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 7 | ||||
-rw-r--r-- | res/res_pjsip_sdp_rtp.c | 19 |
7 files changed, 116 insertions, 13 deletions
@@ -40,6 +40,10 @@ res_pjsip whether to notify dialog-info state 'early' or 'confirmed' on Ringing when already INUSE. + * The endpoint option 'dtmf_mode' has a new option 'auto_dtmf' added. This + mode works similar to 'auto' except uses DTMF INFO as fallback instead of + INBAND. + res_agi ------------------ * The EAGI() application will now look for a dialplan variable named diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 7cab42873..0e4468cdc 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -1962,6 +1962,12 @@ static int chan_pjsip_digit_begin(struct ast_channel *chan, char digit) ast_rtp_instance_dtmf_begin(media->rtp, digit); break; + case AST_SIP_DTMF_AUTO_INFO: + if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) { + return -1; + } + ast_rtp_instance_dtmf_begin(media->rtp, digit); + break; case AST_SIP_DTMF_NONE: break; case AST_SIP_DTMF_INBAND: @@ -2063,6 +2069,20 @@ 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]; switch (channel->session->endpoint->dtmf) { + case AST_SIP_DTMF_AUTO_INFO: + { + if (!media || !media->rtp) { + return -1; + } + if (ast_rtp_instance_dtmf_mode_get(media->rtp) != AST_RTP_DTMF_MODE_NONE) { + ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast)); + ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration); + break; + } + /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */ + ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 NOT negotiated using INFO instead.\n", ast_channel_name(ast)); + } + case AST_SIP_DTMF_INFO: { struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration); @@ -2095,14 +2115,15 @@ static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned in } ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration); - break; - case AST_SIP_DTMF_AUTO: - if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) { - return -1; - } - - ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration); - break; + break; + case AST_SIP_DTMF_AUTO: + if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) { + return -1; + } + + ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration); + break; + case AST_SIP_DTMF_NONE: break; diff --git a/contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py b/contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py new file mode 100644 index 000000000..dbc8ce9c4 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/164abbd708c_add_auto_info_to_endpoint_dtmf_mode.py @@ -0,0 +1,57 @@ +"""Add auto_info to endpoint dtmf_mode + +Revision ID: 164abbd708c +Revises: 86bb1efa278d +Create Date: 2017-06-19 13:55:15.354706 + +""" + +# revision identifiers, used by Alembic. +revision = '164abbd708c' +down_revision = '86bb1efa278d' + +from alembic import op +import sqlalchemy as sa + +OLD_ENUM = ['rfc4733', 'inband', 'info', 'auto'] +NEW_ENUM = ['rfc4733', 'inband', 'info', 'auto', 'auto_info'] + +old_type = sa.Enum(*OLD_ENUM, name='pjsip_dtmf_mode_values_v2') +new_type = sa.Enum(*NEW_ENUM, name='pjsip_dtmf_mode_values_v3') + +def upgrade(): + context = op.get_context() + + # Upgrading to this revision WILL clear your directmedia values. + if context.bind.dialect.name != 'postgresql': + op.alter_column('ps_endpoints', 'dtmf_mode', + type_=new_type, + existing_type=old_type) + else: + enum = ENUM('rfc4733', 'inband', 'info', 'auto', 'auto_info', + name='pjsip_dtmf_mode_values_v3') + enum.create(op.get_bind(), checkfirst=False) + + op.execute('ALTER TABLE ps_endpoints ALTER COLUMN dtmf_mode TYPE' + ' pjsip_dtmf_mode_values_v3 USING' + ' dtmf_mode::text::pjsip_dtmf_mode_values_v3') + + ENUM(name="pjsip_dtmf_mode_values_v2").drop(op.get_bind(), checkfirst=False) + +def downgrade(): + context = op.get_context() + + if context.bind.dialect.name != 'postgresql': + op.alter_column('ps_endpoints', 'dtmf_mode', + type_=old_type, + existing_type=new_type) + else: + enum = ENUM('rfc4733', 'inband', 'info', 'auto', + name='pjsip_dtmf_mode_values_v2') + enum.create(op.get_bind(), checkfirst=False) + + op.execute('ALTER TABLE ps_endpoints ALTER COLUMN dtmf_mode TYPE' + ' pjsip_dtmf_mode_values USING' + ' dtmf_mode::text::pjsip_dtmf_mode_values_v2') + + ENUM(name="pjsip_dtmf_mode_values_v3").drop(op.get_bind(), checkfirst=False) diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index f907effcf..2cd27d37f 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -365,6 +365,8 @@ enum ast_sip_dtmf_mode { AST_SIP_DTMF_INFO, /*! Use SIP 4733 if supported by the other side or INBAND if not */ AST_SIP_DTMF_AUTO, + /*! Use SIP 4733 if supported by the other side or INFO DTMF (blech) if not */ + AST_SIP_DTMF_AUTO_INFO, }; /*! diff --git a/res/res_pjsip.c b/res/res_pjsip.c index e717fdb40..0cf034374 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -229,6 +229,9 @@ <enum name="auto"> <para>DTMF is sent as RFC 4733 if the other side supports it or as INBAND if not.</para> </enum> + <enum name="auto_info"> + <para>DTMF is sent as RFC 4733 if the other side supports it or as SIP INFO if not.</para> + </enum> </enumlist> </description> </configOption> diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 56a8419a8..372b01bc8 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -371,6 +371,8 @@ static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, 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")) { @@ -395,8 +397,11 @@ static int dtmf_to_str(const void *obj, const intptr_t *args, char **buf) *buf = "inband"; break; case AST_SIP_DTMF_INFO : *buf = "info"; break; - case AST_SIP_DTMF_AUTO : + case AST_SIP_DTMF_AUTO : *buf = "auto"; break; + case AST_SIP_DTMF_AUTO_INFO : + *buf = "auto_info"; + break; default: *buf = "none"; } diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 03fef40cf..a49130868 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -207,7 +207,7 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me ice->stop(session_media->rtp); } - if (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) { + if (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_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); } else if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND) { @@ -230,7 +230,7 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me } static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, - struct ast_sip_session_media *session_media) + struct ast_sip_session_media *session_media) { pjmedia_sdp_attr *attr; pjmedia_sdp_rtpmap *rtpmap; @@ -296,6 +296,16 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp if (!tel_event && (session->endpoint->dtmf == AST_SIP_DTMF_AUTO)) { ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); } + + if (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) { + if (tel_event) { + ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833); + } else { + ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_NONE); + } + } + + /* Get the packetization, if it exists */ if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) { unsigned long framing = pj_strtoul(pj_strltrim(&attr->value)); @@ -404,7 +414,8 @@ static int set_caps(struct ast_sip_session *session, ast_set_read_format(session->channel, ast_channel_readformat(session->channel)); ast_set_write_format(session->channel, ast_channel_writeformat(session->channel)); } - if ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) + + if ( ((session->endpoint->dtmf == AST_SIP_DTMF_AUTO) || (session->endpoint->dtmf == AST_SIP_DTMF_AUTO_INFO) ) && (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833) && (session->dsp)) { dsp_features = ast_dsp_get_features(session->dsp); @@ -1136,7 +1147,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as pj_str_t stmp; pjmedia_sdp_attr *attr; int index = 0; - int noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733 || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) ? AST_RTP_DTMF : 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 min_packet_size = 0, max_packet_size = 0; int rtp_code; RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup); |