diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 2e3fd3982c..5ec7f29629 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -644,7 +644,7 @@ typedef enum { This flag will never send any. Sheesh.... */ - RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6) + RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6), /* Guess Who? ... Yep, Sonus (and who know's who else) likes to interweave DTMF with the audio stream making it take @@ -652,6 +652,15 @@ typedef enum { This flag will treat every dtmf as if it were 50ms and queue it on recipt of the leading packet rather than at the end. */ + RTP_BUG_PAUSE_BETWEEN_DTMF = (1 << 7) + + /* + Sonus says they need time to generate the dtmf so we should not send it so fast so with this flag we will wait a few clicks after each send to + start sending the next one. + */ + + + } switch_rtp_bug_flag_t; #ifdef _MSC_VER diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 5ab6bdcc66..7e6836a09e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6542,6 +6542,14 @@ void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str if (switch_stristr("~IGNORE_DTMF_DURATION", str)) { *flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION; } + + if (switch_stristr("PAUSE_BETWEEN_DTMF", str)) { + *flag_pole |= RTP_BUG_PAUSE_BETWEEN_DTMF; + } + + if (switch_stristr("~PAUSE_BETWEEN_DTMF", str)) { + *flag_pole &= ~RTP_BUG_PAUSE_BETWEEN_DTMF; + } } char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0ce47d9231..81904418dd 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -46,6 +46,9 @@ #include #include +/* number of writes to delay sending new DTMF when RTP_BUG_PAUSE_BETWEEN_DTMF flag is set */ +#define BUGGY_DIGIT_DELAY_PERIOD 3 + #define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++ #define READ_DEC(rtp_session) switch_mutex_unlock(rtp_session->read_mutex); rtp_session->reading-- #define WRITE_INC(rtp_session) switch_mutex_lock(rtp_session->write_mutex); rtp_session->writing++ @@ -138,6 +141,7 @@ struct switch_rtp_rfc2833_data { switch_queue_t *dtmf_inqueue; switch_mutex_t *dtmf_mutex; uint8_t in_digit_queued; + uint32_t out_digit_delay; }; struct switch_rtp { @@ -2234,6 +2238,11 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) switch_frame_flag_t flags = 0; uint32_t samples = rtp_session->samples_per_interval; + if (rtp_session->dtmf_data.out_digit_delay) { + rtp_session->dtmf_data.out_digit_delay--; + return; + } + if (rtp_session->dtmf_data.out_digit_dur > 0) { int x, loops = 1; @@ -2280,6 +2289,10 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) rtp_session->next_write_samplecount = rtp_session->timer.samplecount + samples * 5; } rtp_session->dtmf_data.out_digit_dur = 0; + if ((rtp_session->rtp_bugs & RTP_BUG_PAUSE_BETWEEN_DTMF) && switch_queue_size(rtp_session->dtmf_data.dtmf_queue)) { + rtp_session->dtmf_data.out_digit_delay = BUGGY_DIGIT_DELAY_PERIOD; + } + return; } }