[asterisk-commits] oej: branch oej/rana-dtmf-rtp-duration-1.6.0 r305743 - in /team/oej/rana-dtmf...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 2 04:39:57 CST 2011
Author: oej
Date: Wed Feb 2 04:39:51 2011
New Revision: 305743
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=305743
Log:
Code to fix the DTMF issues in RTP channels
Added:
team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration (with props)
Modified:
team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_meetme.c
team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_senddtmf.c
team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_h323.c
team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_mgcp.c
team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_sip.c
team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/channel.h
team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/frame.h
team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/rtp.h
team/oej/rana-dtmf-rtp-duration-1.6.0/main/autoservice.c
team/oej/rana-dtmf-rtp-duration-1.6.0/main/channel.c
team/oej/rana-dtmf-rtp-duration-1.6.0/main/frame.c
team/oej/rana-dtmf-rtp-duration-1.6.0/main/rtp.c
Added: team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration?view=auto&rev=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration (added)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration Wed Feb 2 04:39:51 2011
@@ -1,0 +1,22 @@
+EDVINA AB
+Olle E. Johansson
+
+
+This branch is trying to focus on DTMF in the RTP channel. Asterisk 1.4 and later
+doesn't send the proper DTMF duration on the outbound call leg. If we receive
+a DTMF with a duration of 480 samples, we might end up sending 1440 samples out.
+
+In order to handle this a lot of bugs was fixed. We also added a new control
+frame to update the outbound channel with the latest duration from the inbound,
+in order to try to prevent the outbound channel to run ahead of the inbound.
+
+The outbound channel sends a packet for every incoming RTP packet. As usual,
+the inbound and outbond channels are not synchronized at all. So the outbound
+always clocks dtmf in 160 samples /20 ms, something which will break wideband
+codecs. (another fix required for that).
+
+With this code, the outbound channel sends outbound DTMF for the duration of
+the inbound dtmf tone, a bit adjusted to match 160 samples per outbound
+transmission. We do not break outbound DTMF when we receive inbound
+DTMF end, we continue until we have reached the duration of the DTMF that
+we received on the inbound channel.
Propchange: team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/rana-dtmf-rtp-duration-1.6.0/README.rana-dtmf-rtp-duration
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_meetme.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_meetme.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_meetme.c Wed Feb 2 04:39:51 2011
@@ -2668,7 +2668,7 @@
ret = 0;
ast_frfree(f);
break;
- } else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
+ } else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_CONTINUE || f->frametype == AST_FRAME_DTMF_END)
&& confflags & CONFFLAG_PASS_DTMF) {
conf_queue_dtmf(conf, user, f);
} else if ((confflags & CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_senddtmf.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_senddtmf.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_senddtmf.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/apps/app_senddtmf.c Wed Feb 2 04:39:51 2011
@@ -80,13 +80,17 @@
"Description: Plays a dtmf digit on the specified channel.\n"
"Variables: (all are required)\n"
" Channel: Channel name to send digit to\n"
+" Duration: The length of the tone (100 MS default, optional)\n"
" Digit: The dtmf digit to play\n";
static int manager_play_dtmf(struct mansession *s, const struct message *m)
{
const char *channel = astman_get_header(m, "Channel");
const char *digit = astman_get_header(m, "Digit");
+ const char *duration = astman_get_header(m, "Duration");
struct ast_channel *chan = ast_get_channel_by_name_locked(channel);
+
+ int dtmfduration = 0;
if (!chan) {
astman_send_error(s, m, "Channel not specified");
@@ -97,8 +101,11 @@
ast_channel_unlock(chan);
return 0;
}
+ if (!ast_strlen_zero(duration)) {
+ dtmfduration = atoi(duration);
+ }
- ast_senddigit(chan, *digit, 0);
+ ast_senddigit(chan, *digit, dtmfduration);
ast_channel_unlock(chan);
astman_send_ack(s, m, "DTMF successfully queued");
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_h323.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_h323.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_h323.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_h323.c Wed Feb 2 04:39:51 2011
@@ -557,7 +557,7 @@
if (h323debug) {
ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration);
}
- ast_rtp_senddigit_end(pvt->rtp, digit);
+ ast_rtp_senddigit_end(pvt->rtp, digit, duration);
ast_mutex_unlock(&pvt->lock);
} else {
/* in-band DTMF */
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_mgcp.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_mgcp.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_mgcp.c Wed Feb 2 04:39:51 2011
@@ -1348,7 +1348,7 @@
tmp[2] = digit;
tmp[3] = '\0';
transmit_notify_request(sub, tmp);
- ast_rtp_senddigit_end(sub->rtp, digit);
+ ast_rtp_senddigit_end(sub->rtp, digit, duration);
} else {
ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);
}
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_sip.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_sip.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/channels/chan_sip.c Wed Feb 2 04:39:51 2011
@@ -1731,6 +1731,7 @@
static int sip_transfer(struct ast_channel *ast, const char *dest);
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int sip_senddigit_begin(struct ast_channel *ast, char digit);
+static int sip_senddigit_continue(struct ast_channel *ast, char digit, unsigned int duration);
static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int sip_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
static const char *sip_get_callid(struct ast_channel *chan);
@@ -2135,6 +2136,7 @@
.transfer = sip_transfer, /* called with chan locked */
.fixup = sip_fixup, /* called with chan locked */
.send_digit_begin = sip_senddigit_begin, /* called with chan unlocked */
+ .send_digit_continue = sip_senddigit_continue, /* called with chan unlocked */
.send_digit_end = sip_senddigit_end,
.bridge = ast_rtp_bridge, /* XXX chan unlocked ? */
.early_bridge = ast_rtp_early_bridge,
@@ -5497,6 +5499,26 @@
return res;
}
+/*! \brief Update DTMF character on SIP channel
+ within one call, we're able to transmit in many methods simultaneously */
+static int sip_senddigit_continue(struct ast_channel *ast, char digit, unsigned int duration)
+{
+ struct sip_pvt *p = ast->tech_pvt;
+ int res = 0;
+
+ ast_log(LOG_DEBUG, " DTMF CONTINUE HERE!!! \n");
+
+ sip_pvt_lock(p);
+ switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
+ case SIP_DTMF_RFC2833:
+ if (p->rtp)
+ ast_rtp_senddigit_continue(p->rtp, digit, duration);
+ break;
+ }
+ sip_pvt_unlock(p);
+
+ return res;
+}
/*! \brief Send DTMF character on SIP channel
within one call, we're able to transmit in many methods simultaneously */
static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
@@ -5512,7 +5534,7 @@
break;
case SIP_DTMF_RFC2833:
if (p->rtp)
- ast_rtp_senddigit_end(p->rtp, digit);
+ ast_rtp_senddigit_end(p->rtp, digit, duration);
break;
case SIP_DTMF_INBAND:
res = -1; /* Tell Asterisk to stop inband indications */
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/channel.h?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/channel.h (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/channel.h Wed Feb 2 04:39:51 2011
@@ -271,6 +271,13 @@
* \note The channel is not locked when this function gets called.
*/
int (* const send_digit_begin)(struct ast_channel *chan, char digit);
+
+ /*!
+ * \brief Continue sending a literal DTMF digit
+ *
+ * \note The channel is not locked when this function gets called.
+ */
+ int (* const send_digit_continue)(struct ast_channel *chan, char digit, unsigned int duration);
/*!
* \brief Stop sending a literal DTMF digit
@@ -1254,6 +1261,15 @@
*/
int ast_senddigit_begin(struct ast_channel *chan, char digit);
+/*! \brief Continue to send a DTMF digit to a channel
+ * used on RTP bridges mainly (to get the duration correct)
+ * Send a DTMF digit to a channel.
+ * \param chan channel to act upon
+ * \param digit the DTMF digit to send, encoded in ASCII
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_senddigit_continue(struct ast_channel *chan, char digit, unsigned int duration);
+
/*! \brief Send a DTMF digit to a channel
* Send a DTMF digit to a channel.
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/frame.h?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/frame.h (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/frame.h Wed Feb 2 04:39:51 2011
@@ -121,6 +121,8 @@
AST_FRAME_MODEM,
/*! DTMF begin event, subclass is the digit */
AST_FRAME_DTMF_BEGIN,
+ /*! DTMF continue event, subclass is the digit */
+ AST_FRAME_DTMF_CONTINUE,
};
#define AST_FRAME_DTMF AST_FRAME_DTMF_END
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/rtp.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/rtp.h?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/rtp.h (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/include/asterisk/rtp.h Wed Feb 2 04:39:51 2011
@@ -181,7 +181,9 @@
int ast_rtp_senddigit_begin(struct ast_rtp *rtp, char digit);
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
+int ast_rtp_senddigit_continue(struct ast_rtp *rtp, char digit, unsigned int duration);
+
+int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit, unsigned int duration);
int ast_rtp_sendcng(struct ast_rtp *rtp, int level);
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/main/autoservice.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/main/autoservice.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/main/autoservice.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/main/autoservice.c Wed Feb 2 04:39:51 2011
@@ -146,6 +146,7 @@
/* Throw these frames away */
case AST_FRAME_DTMF_BEGIN:
+ case AST_FRAME_DTMF_CONTINUE:
case AST_FRAME_VOICE:
case AST_FRAME_VIDEO:
case AST_FRAME_NULL:
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/main/channel.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/main/channel.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/main/channel.c Wed Feb 2 04:39:51 2011
@@ -1902,6 +1902,7 @@
case AST_FRAME_VIDEO:
case AST_FRAME_TEXT:
case AST_FRAME_DTMF_BEGIN:
+ case AST_FRAME_DTMF_CONTINUE:
case AST_FRAME_DTMF_END:
case AST_FRAME_IMAGE:
case AST_FRAME_HTML:
@@ -2454,6 +2455,7 @@
switch (f->frametype) {
case AST_FRAME_DTMF_BEGIN:
+ case AST_FRAME_DTMF_CONTINUE:
break;
case AST_FRAME_DTMF_END:
res = f->subclass;
@@ -2750,7 +2752,7 @@
* there are cases where we want to leave DTMF frames on the queue until
* some later time. */
- if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
+ if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_CONTINUE || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
continue;
}
@@ -2903,6 +2905,13 @@
}
}
break;
+ case AST_FRAME_DTMF_CONTINUE:
+ /* No manager event at this point
+ send_dtmf_event(chan, "Received", f->subclass, "Yes", "No");
+ */
+ ast_log(LOG_DTMF, "DTMF continue '%c' received on %s\n", f->subclass, chan->name);
+ ast_log(LOG_DEBUG, "---DEBUG--- DTMF continue '%c' received on %s\n", f->subclass, chan->name);
+ break;
case AST_FRAME_DTMF_BEGIN:
send_dtmf_event(chan, "Received", f->subclass, "Yes", "No");
ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
@@ -3345,6 +3354,17 @@
return 0;
}
+int ast_senddigit_continue(struct ast_channel *chan, char digit, unsigned int duration)
+{
+ int res = -1;
+
+ ast_log(LOG_DEBUG, "DEBUG --- COntinue frame passed on to tech for %s\n", chan->name);
+ if (chan->tech->send_digit_continue)
+ res = chan->tech->send_digit_continue(chan, digit, duration);
+
+ return 0;
+}
+
int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
{
int res = -1;
@@ -3466,6 +3486,22 @@
ast_clear_flag(chan, AST_FLAG_BLOCKING);
ast_channel_unlock(chan);
res = ast_senddigit_begin(chan, fr->subclass);
+ ast_channel_lock(chan);
+ CHECK_BLOCKING(chan);
+ break;
+ case AST_FRAME_DTMF_CONTINUE:
+ if (chan->audiohooks) {
+ struct ast_frame *old_frame = fr;
+ fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
+ if (old_frame != fr)
+ f = fr;
+ }
+ ast_log(LOG_DEBUG, "---Continue FRAME received, forwarding to channel %s", chan->name);
+ // Skip manager for continue events (at least for now)
+ //send_dtmf_event(chan, "Sent", fr->subclass, "Yes", "No");
+ ast_clear_flag(chan, AST_FLAG_BLOCKING);
+ ast_channel_unlock(chan);
+ res = ast_senddigit_continue(chan, fr->subclass, fr->len);
ast_channel_lock(chan);
CHECK_BLOCKING(chan);
break;
@@ -4904,6 +4940,7 @@
}
if ((f->frametype == AST_FRAME_VOICE) ||
(f->frametype == AST_FRAME_DTMF_BEGIN) ||
+ (f->frametype == AST_FRAME_DTMF_CONTINUE) ||
(f->frametype == AST_FRAME_DTMF) ||
(f->frametype == AST_FRAME_VIDEO) ||
(f->frametype == AST_FRAME_IMAGE) ||
@@ -4919,7 +4956,7 @@
*fo = f;
*rc = who;
ast_debug(1, "Got DTMF %s on channel (%s)\n",
- f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
+ f->frametype == AST_FRAME_DTMF_END ? "end" : "begin", /* BUG for continue. Ignored now. OEJ */
who->name);
break;
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/main/frame.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/main/frame.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/main/frame.c Wed Feb 2 04:39:51 2011
@@ -769,6 +769,11 @@
subclass[0] = f->subclass;
subclass[1] = '\0';
break;
+ case AST_FRAME_DTMF_CONTINUE:
+ strcpy(ftype, "DTMF Continue");
+ subclass[0] = f->subclass;
+ subclass[1] = '\0';
+ break;
case AST_FRAME_DTMF_END:
strcpy(ftype, "DTMF End");
subclass[0] = f->subclass;
Modified: team/oej/rana-dtmf-rtp-duration-1.6.0/main/rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-rtp-duration-1.6.0/main/rtp.c?view=diff&rev=305743&r1=305742&r2=305743
==============================================================================
--- team/oej/rana-dtmf-rtp-duration-1.6.0/main/rtp.c (original)
+++ team/oej/rana-dtmf-rtp-duration-1.6.0/main/rtp.c Wed Feb 2 04:39:51 2011
@@ -146,6 +146,8 @@
char send_digit; /*!< digit we are sending */
int send_payload;
int send_duration;
+ int send_endflag:1; /*!< We have received END marker but are in waiting mode */
+ unsigned int received_duration; /*!< Received duration (according to control frames) */
int nat;
unsigned int flags;
struct sockaddr_in us; /*!< Socket representation of the local endpoint. */
@@ -190,7 +192,6 @@
static int ast_rtcp_write_rr(const void *data);
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp);
static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp);
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
#define FLAG_3389_WARNING (1 << 0)
#define FLAG_NAT_ACTIVE (3 << 1)
@@ -805,7 +806,7 @@
rtp->dtmfsamples = 0;
return &ast_null_frame;
}
- ast_debug(1, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr));
+ ast_debug(1, "Sending dtmf: %d (%c), at %s \n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr));
if (rtp->resp == 'X') {
rtp->f.frametype = AST_FRAME_CONTROL;
rtp->f.subclass = AST_CONTROL_FLASH;
@@ -1014,6 +1015,7 @@
f = ast_frdup(create_dtmf_frame(rtp, AST_FRAME_DTMF_END));
f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass)), ast_tv(0, 0));
rtp->resp = 0;
+ ast_log(LOG_DEBUG, "--GOT DTMF END message. Duration samples %d\n", rtp->dtmf_duration);
rtp->dtmf_duration = rtp->dtmf_timeout = 0;
AST_LIST_INSERT_TAIL(frames, f, frame_list);
}
@@ -1033,6 +1035,10 @@
if (rtp->resp) {
/* Digit continues */
rtp->dtmf_duration = new_duration;
+ f = ast_frdup(create_dtmf_frame(rtp, AST_FRAME_DTMF_CONTINUE));
+ f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass)), ast_tv(0, 0));
+ AST_LIST_INSERT_TAIL(frames, f, frame_list);
+ ast_log(LOG_DEBUG, "Queued frame AST_FRAME_DTMF_CONTINUE, Samples %d Ms %d\n", rtp->dtmf_duration, (int)f->len);
} else {
/* New digit began */
rtp->resp = resp;
@@ -1448,9 +1454,18 @@
struct ast_rtp *bridged = NULL;
struct frame_list frames;
- /* If time is up, kill it */
- if (rtp->sending_digit)
+ if (rtp->sending_digit > 1) {
ast_rtp_senddigit_continuation(rtp);
+ } else {
+ /* Skip the first one due to possible BEGIN retransmits
+ Yes, this is a poor coding solution, more of a bad hack.
+ Tests have shown that there's always one CONT packet sent without an incoming CONT
+ right after we've sent the BEGIN. Un-needed.
+ */
+ if (rtp->sending_digit == 1) {
+ rtp->sending_digit = 2;
+ }
+ }
len = sizeof(sin);
@@ -2710,17 +2725,44 @@
ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
/* Increment sequence number */
rtp->seqno++;
- /* Increment duration */
- rtp->send_duration += 160;
/* Clear marker bit and set seqno */
rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
}
+ /* Increment duration */
+ rtp->send_duration += 160;
/* Since we received a begin, we can safely store the digit and disable any compensation */
rtp->sending_digit = 1;
rtp->send_digit = digit;
rtp->send_payload = payload;
+ ast_log(LOG_DEBUG, "DEBUG DTMF BEGIN - Digit %d send-digit %d\n", digit, rtp->send_digit);
+
+ return 0;
+}
+
+/*! \brief Get notification of duration updates */
+int ast_rtp_senddigit_continue(struct ast_rtp *rtp, char digit, unsigned int duration)
+{
+ ast_log(LOG_DEBUG, "DEBUG DTMF CONTINUE - Duration %d Digit %d Send-digit %d\n", duration, digit, rtp->send_digit);
+
+ /* Duration is in ms. Calculate the duration in timestamps */
+ if (duration > 0) {
+ /* We have an incoming duration from the incoming channel. This needs
+ to be matched with our outbound pacing. The inbound can be paced
+ in either 50 ms or whatever packetization that is used on that channel,
+ so we can't assume 20 ms (160 units in 8000 hz audio).
+ */
+ // int dursamples = duration * (rtp_get_rate(f->subclass) / 1000)
+ int dursamples = duration * (8000 / 1000); /* How do we get the sample rate for the primary media in this call? */
+ // f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass)), ast_tv(0, 0));
+
+ ast_log(LOG_DEBUG, "DTMF CONTINUE : %d ms %d samples\n", duration, dursamples);
+ rtp->received_duration = dursamples;
+ } else {
+ ast_log(LOG_DEBUG, "DTMF CONTINUE : Missing duration!!!!!!!\n");
+
+ }
return 0;
}
@@ -2733,6 +2775,18 @@
if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
return 0;
+
+ ast_log(LOG_DEBUG, "---- Send duration %d Received duration %d Endflag %d Send-digit %d\n", rtp->send_duration, rtp->received_duration, rtp->send_endflag, rtp->send_digit);
+ if (rtp->send_duration + 160 < rtp->received_duration) {
+ rtp->send_duration += 160;
+ } else if (rtp->send_endflag) {
+ ast_log(LOG_DEBUG, "---- Send duration %d Received duration %d - sending END packet\n", rtp->send_duration, rtp->received_duration);
+ rtp->send_duration += 160;
+ /* We are done, ready to send end flag */
+ rtp->send_endflag = 0;
+ return ast_rtp_senddigit_end(rtp, 0, rtp->received_duration);
+ }
+
/* Setup packet to send */
rtpheader = (unsigned int *)data;
@@ -2755,39 +2809,60 @@
/* Increment sequence number */
rtp->seqno++;
- /* Increment duration */
- rtp->send_duration += 160;
return 0;
}
/*! \brief Send end packets for DTMF */
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit)
+int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit, unsigned int duration)
{
unsigned int *rtpheader;
int hdrlen = 12, res = 0, i = 0;
char data[256];
+ int dursamples = duration * (8000 / 1000); /* How do we get the sample rate for the primary media in this call? */
/* If no address, then bail out */
if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
return 0;
-
- if ((digit <= '9') && (digit >= '0'))
- digit -= '0';
- else if (digit == '*')
- digit = 10;
- else if (digit == '#')
- digit = 11;
- else if ((digit >= 'A') && (digit <= 'D'))
- digit = digit - 'A' + 12;
- else if ((digit >= 'a') && (digit <= 'd'))
- digit = digit - 'a' + 12;
- else {
- ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
- return 0;
+
+
+ ast_log(LOG_DEBUG, "---- Send duration %d Received duration %d Endflag %d Digit %d Send-digit %d\n", rtp->send_duration, rtp->received_duration, rtp->send_endflag, digit, rtp->send_digit);
+
+ if (!rtp->send_endflag && rtp->send_duration + 160 < rtp->received_duration) {
+ /* We still have to send DTMF continuation, because otherwise we will end prematurely. Set end flag to indicate
+ that we will have to end ourselves when we're done with the actual duration
+ */
+ ast_log(LOG_DEBUG, "---- Send duration %d Received duration %d - Avoiding sending END packet\n", rtp->send_duration, rtp->received_duration);
+ rtp->send_endflag = 1;
+ return ast_rtp_senddigit_continuation(rtp);
+ }
+
+ if (digit) {
+ if ((digit <= '9') && (digit >= '0'))
+ digit -= '0';
+ else if (digit == '*')
+ digit = 10;
+ else if (digit == '#')
+ digit = 11;
+ else if ((digit >= 'A') && (digit <= 'D'))
+ digit = digit - 'A' + 12;
+ else if ((digit >= 'a') && (digit <= 'd'))
+ digit = digit - 'a' + 12;
+ else {
+ ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
+ rtp->sending_digit = 0;
+ rtp->send_digit = 0;
+ rtp->received_duration = 0;
+ return 0;
+ }
+ } else {
+ digit = rtp->send_digit;
}
rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
+
+ //rtp->send_duration = rtp->received_duration; /* Compensate for the last CONT packet */
+ rtp->send_duration = dursamples; /* Compensate for the last CONT packet */
rtpheader = (unsigned int *)data;
rtpheader[1] = htonl(rtp->lastdigitts);
@@ -2810,9 +2885,11 @@
ast_inet_ntoa(rtp->them.sin_addr),
ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
}
+ ast_log(LOG_DEBUG, "-- DTMF END: Duration samples %d ms %d\n", rtp->send_duration, duration);
rtp->lastts += rtp->send_duration;
rtp->sending_digit = 0;
rtp->send_digit = 0;
+ rtp->received_duration = 0;
return res;
}
More information about the asterisk-commits
mailing list