[asterisk-commits] oej: branch oej/rana-dtmf-duration-1.8 r363327 - in /team/oej/rana-dtmf-durat...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 24 09:19:31 CDT 2012
Author: oej
Date: Tue Apr 24 09:19:25 2012
New Revision: 363327
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=363327
Log:
It compiles, which is a good start
Added:
team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration (with props)
Modified:
team/oej/rana-dtmf-duration-1.8/apps/app_senddtmf.c
team/oej/rana-dtmf-duration-1.8/channels/chan_iax2.c
team/oej/rana-dtmf-duration-1.8/channels/chan_local.c
team/oej/rana-dtmf-duration-1.8/channels/chan_mgcp.c
team/oej/rana-dtmf-duration-1.8/channels/chan_sip.c
team/oej/rana-dtmf-duration-1.8/funcs/func_frame_trace.c
team/oej/rana-dtmf-duration-1.8/include/asterisk/channel.h
team/oej/rana-dtmf-duration-1.8/include/asterisk/frame.h
team/oej/rana-dtmf-duration-1.8/include/asterisk/rtp_engine.h
team/oej/rana-dtmf-duration-1.8/main/channel.c
team/oej/rana-dtmf-duration-1.8/main/features.c
team/oej/rana-dtmf-duration-1.8/main/frame.c
team/oej/rana-dtmf-duration-1.8/main/rtp_engine.c
team/oej/rana-dtmf-duration-1.8/res/res_rtp_asterisk.c
Added: team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration?view=auto&rev=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration (added)
+++ team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration Tue Apr 24 09:19:25 2012
@@ -1,0 +1,43 @@
+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.
+
+Another issue is the delayed transmission when using the core bridge with features
+enabled. If you send a three second DTMF inbound, the outbound begins after the inbound
+ends, so you get a six second interruption to the call.
+
+A third issue is that if we get a new DTMF while we're still transmitting the old,
+we immediately jump to the new one without finishing the old DTMF tone.
+
+Fixes
+=====
+
+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.
+If the outbound channel gets these frames, it will stop adding to the outbound
+DTMF, but retransmit previous message instead.
+
+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.
+
+By adding a ast_feature_check function to main/features.c we now check
+the DTMF on the incoming DTMF_BEGIN. If it's not a feature code it's
+immediately forwarded to the outbound channel. If it's a feature code,
+it's dropped and the feature channel waits for DTMF_END (like now).
+This dramatically changes DTMF behaviour in a PBX bridged call.
+
+
+This work was sponsored by IPvision AS, Denmark
Propchange: team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/rana-dtmf-duration-1.8/README.rana-dtmf-rtp-duration
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/rana-dtmf-duration-1.8/apps/app_senddtmf.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/apps/app_senddtmf.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/apps/app_senddtmf.c (original)
+++ team/oej/rana-dtmf-duration-1.8/apps/app_senddtmf.c Tue Apr 24 09:19:25 2012
@@ -78,6 +78,9 @@
<parameter name="Digit" required="true">
<para>The DTMF digit to play.</para>
</parameter>
+ <parameter name="Duration" required="false">
+ <para>The duration in ms for the digit to play.</para>
+ </parameter>
</syntax>
<description>
<para>Plays a dtmf digit on the specified channel.</para>
@@ -134,7 +137,9 @@
{
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;
+ int dtmfduration = 0;
if (!(chan = ast_channel_get_by_name(channel))) {
astman_send_error(s, m, "Channel not found");
@@ -146,8 +151,11 @@
chan = ast_channel_unref(chan);
return 0;
}
+ if (!ast_strlen_zero(duration)) {
+ dtmfduration = atoi(duration);
+ }
- ast_senddigit(chan, *digit, 0);
+ ast_senddigit(chan, *digit, dtmfduration);
chan = ast_channel_unref(chan);
Modified: team/oej/rana-dtmf-duration-1.8/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/channels/chan_iax2.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/channels/chan_iax2.c (original)
+++ team/oej/rana-dtmf-duration-1.8/channels/chan_iax2.c Tue Apr 24 09:19:25 2012
@@ -1170,6 +1170,7 @@
static int iax2_call(struct ast_channel *c, char *dest, int timeout);
static int iax2_devicestate(void *data);
static int iax2_digit_begin(struct ast_channel *c, char digit);
+static int iax2_digit_continue(struct ast_channel *c, char digit, unsigned int duration);
static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int iax2_do_register(struct iax2_registry *reg);
static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
@@ -1221,6 +1222,7 @@
.requester = iax2_request,
.devicestate = iax2_devicestate,
.send_digit_begin = iax2_digit_begin,
+ .send_digit_continue = iax2_digit_continue,
.send_digit_end = iax2_digit_end,
.send_text = iax2_sendtext,
.send_image = iax2_sendimage,
@@ -4285,6 +4287,11 @@
static int iax2_digit_begin(struct ast_channel *c, char digit)
{
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
+}
+
+static int iax2_digit_continue(struct ast_channel *c, char digit, unsigned int duration)
+{
+ return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_CONTINUE, digit, 0, NULL, 0, -1);
}
static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
Modified: team/oej/rana-dtmf-duration-1.8/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/channels/chan_local.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/channels/chan_local.c (original)
+++ team/oej/rana-dtmf-duration-1.8/channels/chan_local.c Tue Apr 24 09:19:25 2012
@@ -94,6 +94,7 @@
static struct ast_channel *local_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static int local_digit_begin(struct ast_channel *ast, char digit);
+static int local_digit_continue(struct ast_channel *ast, char digit, unsigned int duration);
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int local_call(struct ast_channel *ast, char *dest, int timeout);
static int local_hangup(struct ast_channel *ast);
@@ -116,6 +117,7 @@
.capabilities = -1,
.requester = local_request,
.send_digit_begin = local_digit_begin,
+ .send_digit_continue = local_digit_continue,
.send_digit_end = local_digit_end,
.call = local_call,
.hangup = local_hangup,
@@ -734,6 +736,29 @@
return res;
}
+static int local_digit_continue(struct ast_channel *ast, char digit, unsigned int duration)
+{
+ struct local_pvt *p = ast->tech_pvt;
+ int res = -1;
+ struct ast_frame f = { AST_FRAME_DTMF_CONTINUE, };
+ int isoutbound;
+
+ if (!p) {
+ return -1;
+ }
+
+ ao2_ref(p, 1); /* ref for local_queue_frame */
+ ao2_lock(p);
+ isoutbound = IS_OUTBOUND(ast, p);
+ f.subclass.integer = digit;
+ f.len = duration;
+ res = local_queue_frame(p, isoutbound, &f, ast, 0);
+ ao2_unlock(p);
+ ao2_ref(p, -1);
+
+ return res;
+}
+
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct local_pvt *p = ast->tech_pvt;
Modified: team/oej/rana-dtmf-duration-1.8/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/channels/chan_mgcp.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/channels/chan_mgcp.c (original)
+++ team/oej/rana-dtmf-duration-1.8/channels/chan_mgcp.c Tue Apr 24 09:19:25 2012
@@ -450,6 +450,7 @@
static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int mgcp_senddigit_begin(struct ast_channel *ast, char digit);
+static int mgcp_senddigit_continue(struct ast_channel *ast, char digit, unsigned int duration);
static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int mgcp_devicestate(void *data);
static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone);
@@ -475,6 +476,7 @@
.indicate = mgcp_indicate,
.fixup = mgcp_fixup,
.send_digit_begin = mgcp_senddigit_begin,
+ .send_digit_continue = mgcp_senddigit_continue,
.send_digit_end = mgcp_senddigit_end,
.bridge = ast_rtp_instance_bridge,
.func_channel_read = acf_channel_read,
@@ -1317,6 +1319,21 @@
return res;
}
+static int mgcp_senddigit_continue(struct ast_channel *ast, char digit, unsigned int duration)
+{
+ struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_endpoint *p = sub->parent;
+
+ ast_mutex_lock(&sub->lock);
+
+ if (p->dtmfmode & MGCP_DTMF_RFC2833) {
+ ast_debug(4, "DTMF continue using RFC2833\n");
+ ast_rtp_senddigit_continue(sub->rtp, digit, duration);
+ }
+ ast_mutex_unlock(&sub->lock);
+
+ return 0;
+}
static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct mgcp_subchannel *sub = ast->tech_pvt;
Modified: team/oej/rana-dtmf-duration-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/channels/chan_sip.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/channels/chan_sip.c (original)
+++ team/oej/rana-dtmf-duration-1.8/channels/chan_sip.c Tue Apr 24 09:19:25 2012
@@ -1224,6 +1224,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_setoption(struct ast_channel *chan, int option, void *data, int datalen);
static int sip_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
@@ -1612,6 +1613,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_instance_bridge, /* XXX chan unlocked ? */
.early_bridge = ast_rtp_instance_early_bridge,
@@ -6652,6 +6654,27 @@
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)
Modified: team/oej/rana-dtmf-duration-1.8/funcs/func_frame_trace.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/funcs/func_frame_trace.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/funcs/func_frame_trace.c (original)
+++ team/oej/rana-dtmf-duration-1.8/funcs/func_frame_trace.c Tue Apr 24 09:19:25 2012
@@ -54,6 +54,7 @@
<para>Below are the different types of frames that can be filtered.</para>
<enumlist>
<enum name = "DTMF_BEGIN" />
+ <enum name = "DTMF_CONTINUE" />
<enum name = "DTMF_END" />
<enum name = "VOICE" />
<enum name = "VIDEO" />
@@ -83,6 +84,7 @@
const char *str;
} frametype2str[] = {
{ AST_FRAME_DTMF_BEGIN, "DTMF_BEGIN" },
+ { AST_FRAME_DTMF_CONTINUE, "DTMF_CONTINUE" },
{ AST_FRAME_DTMF_END, "DTMF_END" },
{ AST_FRAME_VOICE, "VOICE" },
{ AST_FRAME_VIDEO, "VIDEO" },
@@ -353,6 +355,10 @@
ast_verbose("FrameType: DTMF BEGIN\n");
ast_verbose("Digit: %d\n", frame->subclass.integer);
break;
+ case AST_FRAME_DTMF_CONTINUE:
+ ast_verbose("FrameType: DTMF CONTINUE\n");
+ ast_verbose("Digit: %d\n", frame->subclass.integer);
+ break;
}
ast_verbose("Src: %s\n", ast_strlen_zero(frame->src) ? "NOT PRESENT" : frame->src);
Modified: team/oej/rana-dtmf-duration-1.8/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/include/asterisk/channel.h?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/include/asterisk/channel.h (original)
+++ team/oej/rana-dtmf-duration-1.8/include/asterisk/channel.h Tue Apr 24 09:19:25 2012
@@ -526,6 +526,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
@@ -1851,6 +1858,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.
* \param chan channel to act upon
Modified: team/oej/rana-dtmf-duration-1.8/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/include/asterisk/frame.h?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/include/asterisk/frame.h (original)
+++ team/oej/rana-dtmf-duration-1.8/include/asterisk/frame.h Tue Apr 24 09:19:25 2012
@@ -124,6 +124,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-duration-1.8/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/include/asterisk/rtp_engine.h?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/include/asterisk/rtp_engine.h (original)
+++ team/oej/rana-dtmf-duration-1.8/include/asterisk/rtp_engine.h Tue Apr 24 09:19:25 2012
@@ -322,6 +322,8 @@
void (*stop)(struct ast_rtp_instance *instance);
/*! Callback for starting RFC2833 DTMF transmission */
int (*dtmf_begin)(struct ast_rtp_instance *instance, char digit);
+ /*! Callback for continuing RFC2833 DTMF transmission */
+ int (*dtmf_continue)(struct ast_rtp_instance *instance, char digit, unsigned int duration);
/*! Callback for stopping RFC2833 DTMF transmission */
int (*dtmf_end)(struct ast_rtp_instance *instance, char digit);
int (*dtmf_end_with_duration)(struct ast_rtp_instance *instance, char digit, unsigned int duration);
@@ -1190,6 +1192,28 @@
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit);
/*!
+ * \brief Continue sending a DTMF digit
+ *
+ * \param instance The RTP instance to send the DTMF on
+ * \param digit What DTMF digit to send
+ * \param duration Current duration of the DTMF
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * Example usage:
+ *
+ * \code
+ * ast_rtp_instance_dtmf_continue(instance, '1', 142857);
+ * \endcode
+ *
+ * This starts continues the DTMF '1' on the RTP instance pointed to by instance.
+ *
+ * \since 11
+ */
+int ast_rtp_instance_dtmf_continue(struct ast_rtp_instance *instance, char digit, unsigned int duration);
+
+/*!
* \brief Stop sending a DTMF digit
*
* \param instance The RTP instance to stop the DTMF on
Modified: team/oej/rana-dtmf-duration-1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/main/channel.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/main/channel.c (original)
+++ team/oej/rana-dtmf-duration-1.8/main/channel.c Tue Apr 24 09:19:25 2012
@@ -1790,6 +1790,7 @@
return 1;
case AST_FRAME_DTMF_END:
+ case AST_FRAME_DTMF_CONTINUE:
case AST_FRAME_DTMF_BEGIN:
case AST_FRAME_VOICE:
case AST_FRAME_VIDEO:
@@ -2992,6 +2993,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:
@@ -3562,6 +3564,7 @@
switch (f->frametype) {
case AST_FRAME_DTMF_BEGIN:
+ case AST_FRAME_DTMF_CONTINUE:
break;
case AST_FRAME_DTMF_END:
res = f->subclass.integer;
@@ -3872,7 +3875,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;
}
@@ -4077,6 +4080,13 @@
ast_frfree(old_frame);
}
}
+ 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.integer, chan->name);
+ ast_debug(4, "DTMF continue '%c' received on %s\n", f->subclass.integer, chan->name);
break;
case AST_FRAME_DTMF_BEGIN:
send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
@@ -4629,6 +4639,18 @@
return 0;
}
+int ast_senddigit_continue(struct ast_channel *chan, char digit, unsigned int duration)
+{
+ int res = -1;
+
+ ast_debug(4, "--- 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;
@@ -4866,6 +4888,22 @@
ast_clear_flag(chan, AST_FLAG_BLOCKING);
ast_channel_unlock(chan);
res = ast_senddigit_begin(chan, fr->subclass.integer);
+ 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\n", 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.integer, fr->len);
ast_channel_lock(chan);
CHECK_BLOCKING(chan);
break;
@@ -7139,6 +7177,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) ||
@@ -7154,7 +7193,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" : (AST_FRAME_DTMF_CONTINUE ? "cont" : "begin"),
who->name);
break;
Modified: team/oej/rana-dtmf-duration-1.8/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/main/features.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/main/features.c (original)
+++ team/oej/rana-dtmf-duration-1.8/main/features.c Tue Apr 24 09:19:25 2012
@@ -4055,11 +4055,11 @@
digits to come in for features. */
ast_debug(1, "Timed out for feature!\n");
if (!ast_strlen_zero(peer_featurecode)) {
- ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
+ ast_dtmf_stream(chan, peer, peer_featurecode, 0, f->len);
memset(peer_featurecode, 0, sizeof(peer_featurecode));
}
if (!ast_strlen_zero(chan_featurecode)) {
- ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
+ ast_dtmf_stream(peer, chan, chan_featurecode, 0, f->len);
memset(chan_featurecode, 0, sizeof(chan_featurecode));
}
if (f)
Modified: team/oej/rana-dtmf-duration-1.8/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/main/frame.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/main/frame.c (original)
+++ team/oej/rana-dtmf-duration-1.8/main/frame.c Tue Apr 24 09:19:25 2012
@@ -801,6 +801,11 @@
subclass[0] = f->subclass.integer;
subclass[1] = '\0';
break;
+ case AST_FRAME_DTMF_CONTINUE:
+ strcpy(ftype, "DTMF Continue");
+ subclass[0] = f->subclass.integer;
+ subclass[1] = '\0';
+ break;
case AST_FRAME_DTMF_END:
strcpy(ftype, "DTMF End");
subclass[0] = f->subclass.integer;
Modified: team/oej/rana-dtmf-duration-1.8/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/main/rtp_engine.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/main/rtp_engine.c (original)
+++ team/oej/rana-dtmf-duration-1.8/main/rtp_engine.c Tue Apr 24 09:19:25 2012
@@ -732,6 +732,11 @@
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
{
return instance->engine->dtmf_begin ? instance->engine->dtmf_begin(instance, digit) : -1;
+}
+
+int ast_rtp_instance_dtmf_continue(struct ast_rtp_instance *instance, char digit, unsigned int duration)
+{
+ return instance->engine->dtmf_continue ? instance->engine->dtmf_continue(instance, digit, duration) : -1;
}
int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
Modified: team/oej/rana-dtmf-duration-1.8/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/rana-dtmf-duration-1.8/res/res_rtp_asterisk.c?view=diff&rev=363327&r1=363326&r2=363327
==============================================================================
--- team/oej/rana-dtmf-duration-1.8/res/res_rtp_asterisk.c (original)
+++ team/oej/rana-dtmf-duration-1.8/res/res_rtp_asterisk.c Tue Apr 24 09:19:25 2012
@@ -105,6 +105,14 @@
STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
STRICT_RTP_LEARN, /*! Accept next packet as source */
STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
+};
+
+/*! \brief States for an outbound RTP stream that handles DTMF in RFC 2833 mode */
+enum dtmf_send_states {
+ DTMF_NOT_SENDING = 0, /*! Not sending DTMF this very moment */
+ DTMF_SEND_INIT, /*! Initializing */
+ DTMF_SEND_INPROGRESS, /*! Playing DTMF */
+ DTMF_SEND_INPROGRESS_WITH_QUEUE /*! Playing and having a queue to continue with */
};
#define FLAG_3389_WARNING (1 << 0)
@@ -155,10 +163,13 @@
enum ast_rtp_dtmf_mode dtmfmode;/*!< The current DTMF mode of the RTP stream */
/* DTMF Transmission Variables */
unsigned int lastdigitts;
+ enum dtmf_send_states sending_dtmf; /*!< - are we sending dtmf */
char sending_digit; /*!< boolean - are we sending digits */
char send_digit; /*!< digit we are sending */
int send_payload;
int send_duration;
+ unsigned int received_duration; /*!< Received duration (according to control frames) */
+ int send_endflag; /*!< We have received END marker but are in waiting mode */
unsigned int flags;
struct timeval rxcore;
struct timeval txcore;
@@ -271,6 +282,7 @@
static int ast_rtp_new(struct ast_rtp_instance *instance, struct sched_context *sched, struct ast_sockaddr *addr, void *data);
static int ast_rtp_destroy(struct ast_rtp_instance *instance);
static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit);
+static int ast_rtp_dtmf_continue(struct ast_rtp_instance *instance, char digit, unsigned int duration);
static int ast_rtp_dtmf_end(struct ast_rtp_instance *instance, char digit);
static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration);
static int ast_rtp_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode);
@@ -299,6 +311,7 @@
.new = ast_rtp_new,
.destroy = ast_rtp_destroy,
.dtmf_begin = ast_rtp_dtmf_begin,
+ .dtmf_continue = ast_rtp_dtmf_continue,
.dtmf_end = ast_rtp_dtmf_end,
.dtmf_end_with_duration = ast_rtp_dtmf_end_with_duration,
.dtmf_mode_set = ast_rtp_dtmf_mode_set,
@@ -699,7 +712,39 @@
return 0;
}
-static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
+/*! \brief Get notification of duration updates */
+static int ast_rtp_dtmf_continue(struct ast_rtp_instance *instance, char digit, unsigned int duration)
+{
+ struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+
+ ast_debug(4, "DTMF CONTINUE - Duration %d Digit %d Send-digit %d\n", duration, digit, rtp->send_digit);
+
+ /* If we missed the BEGIN, we will have to turn on the flag */
+ if (!rtp->sending_dtmf) {
+ rtp->sending_dtmf = DTMF_SEND_INPROGRESS;
+ }
+
+ /* 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(rtp->f.subclass.codec) / 1000;
+
+ /* How do we get the sample rate for the primary media in this call? */
+
+ ast_debug(4, "DTMF CONTINUE : %d ms %d samples\n", duration, dursamples);
+ rtp->received_duration = dursamples;
+ } else {
+ ast_debug(4, "DTMF CONTINUE : Missing duration!!!!!!!\n");
+
+ }
+ return 0;
+}
+
+static int ast_rtp_dtmf_cont(struct ast_rtp_instance *instance)
{
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
struct ast_sockaddr remote_address = { {0,} };
@@ -1552,7 +1597,7 @@
resp = 'X';
} else {
/* Not a supported event */
- ast_log(LOG_DEBUG, "Ignoring RTP 2833 Event: %08x. Not a DTMF Digit.\n", event);
+ ast_debug(4, "Ignoring RTP 2833 Event: %08x. Not a DTMF Digit.\n", event);
return;
}
@@ -1598,6 +1643,7 @@
f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass.codec)), ast_tv(0, 0));
rtp->resp = 0;
+ ast_debug(4, "--GOT DTMF END message. Duration samples %d (%ld ms)\n", rtp->dtmf_duration, f->len);
rtp->dtmf_duration = rtp->dtmf_timeout = 0;
AST_LIST_INSERT_TAIL(frames, f, frame_list);
}
@@ -1616,6 +1662,10 @@
if (rtp->resp) {
/* Digit continues */
rtp->dtmf_duration = new_duration;
+ f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_CONTINUE, 0));
+ f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass.codec)), ast_tv(0, 0));
+ AST_LIST_INSERT_TAIL(frames, f, frame_list);
+ ast_debug(4, "Queued frame AST_FRAME_DTMF_CONTINUE, Samples %d Ms %d\n", rtp->dtmf_duration, (int)f->len);
} else {
/* New digit began */
rtp->resp = resp;
@@ -1804,8 +1854,10 @@
length &= 0xffff;
if ((i + length) > packetwords) {
- if (option_debug || rtpdebug)
+ if (rtpdebug || option_debug) {
+ /* Because of rtpdebug, this can't be ast_debug() */
ast_log(LOG_DEBUG, "RTCP Read too short\n");
+ }
return &ast_null_frame;
}
@@ -2120,7 +2172,7 @@
/* If we are currently sending DTMF to the remote party send a continuation packet */
if (rtp->sending_digit) {
- ast_rtp_dtmf_continuation(instance);
+ ast_rtp_dtmf_cont(instance);
}
/* Actually read in the data from the socket */
More information about the asterisk-commits
mailing list