diff --git a/src/include/switch_types.h b/src/include/switch_types.h index b20d68ffb3..f0c6dfed01 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1087,6 +1087,7 @@ typedef enum { CC_PROXY_MEDIA, CC_JITTERBUFFER, CC_FS_RTP, + CC_QUEUEABLE_DTMF_DELAY, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CC_FLAG_MAX } switch_channel_cap_t; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 9ccc1c698c..b9f4ca0f4f 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -876,6 +876,7 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA); switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER); switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP); + switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY); switch_core_session_set_private(session, tech_pvt); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 31c8d5fb25..100d8bf9f6 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -1345,11 +1345,22 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_sessio } if (session->endpoint_interface->io_routines->send_dtmf) { - if (dtmf->digit == 'w') { - switch_yield(500000); - } else if (dtmf->digit == 'W') { - switch_yield(1000000); + int send = 0; + status = SWITCH_STATUS_SUCCESS; + + if (switch_channel_test_cap(session->channel, CC_QUEUEABLE_DTMF_DELAY) && (dtmf->digit == 'w' || dtmf->digit == 'W')) { + send = 1; } else { + if (dtmf->digit == 'w') { + switch_yield(500000); + } else if (dtmf->digit == 'W') { + switch_yield(1000000); + } else { + send = 1; + } + } + + if (send) { status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf); } } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 44d8a219ed..2bc0a64520 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2233,6 +2233,21 @@ SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp } } +static void set_dtmf_delay(switch_rtp_t *rtp_session, uint32_t ms) +{ + int mspp = 20; + + if (rtp_session->ms_per_packet) { + if (!(mspp = (int) (rtp_session->ms_per_packet / 1000))) { + mspp = 20; + } + } + + rtp_session->dtmf_data.out_digit_delay += (ms / mspp); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Queue digit delay of %dms\n", ms); + +} + static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) { switch_frame_flag_t flags = 0; @@ -2310,6 +2325,19 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) switch_dtmf_t *rdigit = pop; int64_t offset; switch_size_t wrote; + + if (rdigit->digit == 'w') { + set_dtmf_delay(rtp_session, 500); + free(rdigit); + return; + } + + if (rdigit->digit == 'W') { + set_dtmf_delay(rtp_session, 1000); + free(rdigit); + return; + } + rtp_session->sending_dtmf = 1; memset(rtp_session->dtmf_data.out_digit_packet, 0, 4);