#include <datatypes.h>
#include <srtp.h>
-/* number of writes to delay sending new DTMF when RTP_BUG_PAUSE_BETWEEN_DTMF flag is set */
-#define BUGGY_DIGIT_DELAY_PERIOD 5
-
#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++
switch_queue_t *dtmf_inqueue;
switch_mutex_t *dtmf_mutex;
uint8_t in_digit_queued;
- uint32_t out_digit_delay;
};
struct switch_rtp {
uint32_t last_read_ts;
uint32_t last_cng_ts;
uint32_t last_write_samplecount;
+ uint32_t next_write_samplecount;
+ uint32_t max_next_write_samplecount;
+ uint32_t queue_delay;
switch_time_t last_write_timestamp;
uint32_t flags;
switch_memory_pool_t *pool;
}
}
-static void set_dtmf_delay(switch_rtp_t *rtp_session, uint32_t ms)
+static void set_dtmf_delay(switch_rtp_t *rtp_session, uint32_t ms, uint32_t max_ms)
{
- int mspp = 20;
+ int upsamp, max_upsamp;
+
+ if (!max_ms) max_ms = ms;
- if (rtp_session->ms_per_packet) {
- if (!(mspp = (int) (rtp_session->ms_per_packet / 1000))) {
- mspp = 20;
- }
+ upsamp = ms * (rtp_session->samples_per_second / 1000);
+ max_upsamp = max_ms * (rtp_session->samples_per_second / 1000);
+
+ rtp_session->queue_delay = upsamp;
+
+ if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
+ rtp_session->max_next_write_samplecount = rtp_session->timer.samplecount + max_upsamp;
}
-
- 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);
-
+
+ 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;
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->sending_dtmf > 1) {
rtp_session->sending_dtmf--;
return;
}
+ if (!rtp_session->last_write_ts) {
+ return;
+ }
+
if (rtp_session->dtmf_data.out_digit_dur > 0) {
int x, loops = 1;
rtp_session->stats.outbound.raw_bytes += wrote;
rtp_session->stats.outbound.dtmf_packet_count++;
+ if (loops == 1) {
+ rtp_session->last_write_ts += samples;
+
+ if (rtp_session->rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833) {
+ rtp_session->dtmf_data.timestamp_dtmf = rtp_session->last_write_ts;
+ }
+ }
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Send %s packet for [%c] ts=%u dur=%d/%d/%d seq=%d\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Send %s packet for [%c] ts=%u dur=%d/%d/%d seq=%d lw=%d\n",
loops == 1 ? "middle" : "end", rtp_session->dtmf_data.out_digit,
rtp_session->dtmf_data.timestamp_dtmf,
rtp_session->dtmf_data.out_digit_sofar,
- rtp_session->dtmf_data.out_digit_sub_sofar, rtp_session->dtmf_data.out_digit_dur, rtp_session->seq);
- if (loops == 1 && rtp_session->rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833) {
- rtp_session->dtmf_data.timestamp_dtmf = rtp_session->last_write_ts + samples;
- }
+ rtp_session->dtmf_data.out_digit_sub_sofar, rtp_session->dtmf_data.out_digit_dur, rtp_session->seq, rtp_session->last_write_ts);
}
if (loops != 1) {
- rtp_session->sending_dtmf = -1;
+ rtp_session->sending_dtmf = 0;
rtp_session->need_mark = 1;
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
rtp_session->last_write_samplecount = rtp_session->timer.samplecount;
}
+
rtp_session->dtmf_data.out_digit_dur = 0;
+ set_dtmf_delay(rtp_session, 40, 500);
- if ((rtp_session->rtp_bugs & RTP_BUG_PAUSE_BETWEEN_DTMF)) {
- rtp_session->dtmf_data.out_digit_delay = BUGGY_DIGIT_DELAY_PERIOD;
- }
return;
}
}
if (!rtp_session->dtmf_data.out_digit_dur && rtp_session->dtmf_data.dtmf_queue && switch_queue_size(rtp_session->dtmf_data.dtmf_queue)) {
void *pop;
+ if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
+ if (rtp_session->last_write_ts < rtp_session->next_write_samplecount && rtp_session->timer.samplecount < rtp_session->max_next_write_samplecount) {
+ return;
+ }
+ if (rtp_session->timer.samplecount >= rtp_session->max_next_write_samplecount) {
+ rtp_session->queue_delay = 0;
+ }
+
+ } else {
+ if (rtp_session->last_write_ts < rtp_session->next_write_samplecount) {
+ return;
+ }
+ }
+
+ if (rtp_session->queue_delay) {
+ return;
+ }
+
+
if (!rtp_session->sending_dtmf) {
rtp_session->sending_dtmf = 2;
return;
switch_size_t wrote;
if (rdigit->digit == 'w') {
- set_dtmf_delay(rtp_session, 500);
+ set_dtmf_delay(rtp_session, 500, 0);
free(rdigit);
return;
}
if (rdigit->digit == 'W') {
- set_dtmf_delay(rtp_session, 1000);
+ set_dtmf_delay(rtp_session, 1000, 0);
free(rdigit);
return;
}
rtp_session->dtmf_data.out_digit_packet[2] = (unsigned char) (rtp_session->dtmf_data.out_digit_sub_sofar >> 8);
rtp_session->dtmf_data.out_digit_packet[3] = (unsigned char) rtp_session->dtmf_data.out_digit_sub_sofar;
- rtp_session->dtmf_data.timestamp_dtmf = rtp_session->last_write_ts + samples;
+ rtp_session->dtmf_data.timestamp_dtmf = rtp_session->last_write_ts + samples;
+ rtp_session->last_write_ts = rtp_session->dtmf_data.timestamp_dtmf;
+
wrote = switch_rtp_write_manual(rtp_session,
rtp_session->dtmf_data.out_digit_packet,
4,
rtp_session->rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ? 0 : 1,
rtp_session->te, rtp_session->dtmf_data.timestamp_dtmf, &flags);
+
rtp_session->stats.outbound.raw_bytes += wrote;
rtp_session->stats.outbound.dtmf_packet_count++;
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Send start packet for [%c] ts=%u dur=%d/%d/%d seq=%d\n",
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Send start packet for [%c] ts=%u dur=%d/%d/%d seq=%d lw=%d\n",
rtp_session->dtmf_data.out_digit,
rtp_session->dtmf_data.timestamp_dtmf,
rtp_session->dtmf_data.out_digit_sofar,
- rtp_session->dtmf_data.out_digit_sub_sofar, rtp_session->dtmf_data.out_digit_dur, rtp_session->seq);
+ rtp_session->dtmf_data.out_digit_sub_sofar, rtp_session->dtmf_data.out_digit_dur, rtp_session->seq, rtp_session->last_write_ts);
free(rdigit);
}
this_ts = ntohl(send_msg->header.ts);
- if (!switch_rtp_ready(rtp_session) || rtp_session->sending_dtmf || !this_ts) {
+ if (!switch_rtp_ready(rtp_session) || rtp_session->sending_dtmf || !this_ts || this_ts < rtp_session->last_write_ts) {
send = 0;
}
- if (rtp_session->sending_dtmf == -1) {
- rtp_session->sending_dtmf = 0;
-
- }
if (send) {
send_msg->header.seq = htons(++rtp_session->seq);
}
rtp_session->last_write_ts = this_ts;
+ if (rtp_session->queue_delay) {
+ rtp_session->next_write_samplecount = rtp_session->last_write_ts + rtp_session->queue_delay;
+ rtp_session->queue_delay = 0;
+ }
+
+
+
rtp_session->stats.outbound.raw_bytes += bytes;
rtp_session->stats.outbound.packet_count++;