[asterisk-commits] oej: branch oej/pine-pine-pine-pine-everywhere-pine-1.6.0 r312383 - in /team/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Apr 1 06:56:47 CDT 2011
Author: oej
Date: Fri Apr 1 06:56:36 2011
New Revision: 312383
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=312383
Log:
Adding the DTMF work
Modified:
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_meetme.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_senddtmf.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_h323.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_iax2.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_local.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_mgcp.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_sip.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/channel.h
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/frame.h
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/rtp.h
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/autoservice.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/channel.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/features.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/frame.c
team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/rtp.c
Modified: team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_meetme.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_meetme.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_meetme.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_senddtmf.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_senddtmf.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_senddtmf.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/apps/app_senddtmf.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_h323.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_h323.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_h323.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_h323.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_iax2.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_iax2.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_iax2.c Fri Apr 1 06:56:36 2011
@@ -988,6 +988,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);
@@ -1035,6 +1036,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,
@@ -3914,6 +3916,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/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_local.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_local.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_local.c Fri Apr 1 06:56:36 2011
@@ -71,6 +71,7 @@
static struct ast_channel *local_request(const char *type, int format, 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);
@@ -95,6 +96,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,
@@ -596,6 +598,26 @@
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;
+
+ ast_mutex_lock(&p->lock);
+ isoutbound = IS_OUTBOUND(ast, p);
+ f.subclass = digit;
+ f.len = duration;
+ if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
+ ast_mutex_unlock(&p->lock);
+
+ 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/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_mgcp.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_mgcp.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_mgcp.c Fri Apr 1 06:56:36 2011
@@ -424,6 +424,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);
@@ -443,6 +444,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_bridge,
};
@@ -1330,6 +1332,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(1, "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;
@@ -1348,7 +1365,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/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_sip.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_sip.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/channels/chan_sip.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/channel.h?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/channel.h (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/channel.h Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/frame.h?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/frame.h (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/frame.h Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/rtp.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/rtp.h?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/rtp.h (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/include/asterisk/rtp.h Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/main/autoservice.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/autoservice.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/autoservice.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/autoservice.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/channel.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/channel.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/channel.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/features.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/features.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/features.c Fri Apr 1 06:56:36 2011
@@ -1794,7 +1794,9 @@
if (operation) {
res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
}
- memcpy(feature, tmpfeature, sizeof(feature));
+ if (feature) {
+ memcpy(feature, tmpfeature, sizeof(feature));
+ }
if (res != AST_FEATURE_RETURN_KEEPTRYING) {
AST_RWLIST_UNLOCK(&feature_list);
break;
@@ -2205,6 +2207,7 @@
int hasfeatures=0;
int hadfeatures=0;
int autoloopflag;
+ int sendingdtmfdigit = 0;
struct ast_option_header *aoh;
struct ast_bridge_config backup_config;
struct ast_cdr *bridge_cdr = NULL;
@@ -2389,11 +2392,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)
@@ -2459,11 +2462,10 @@
}
break;
}
- } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
- /* eat it */
- } else if (f->frametype == AST_FRAME_DTMF) {
+ } else if (f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_DTMF_BEGIN) {
char *featurecode;
int sense;
+ unsigned int dtmfduration = f->len;
hadfeatures = hasfeatures;
/* This cannot overrun because the longest feature is one shorter than our buffer */
@@ -2479,14 +2481,24 @@
* \todo XXX how do we guarantee the latter ?
*/
featurecode[strlen(featurecode)] = f->subclass;
+ config->feature_timer = backup_config.feature_timer;
+
+ if (f->frametype == AST_FRAME_DTMF_BEGIN) {
+ /* Take a peek if this is the beginning of a feature. If not, just pass this DTMF along untouched. */
+ res = ast_feature_detect(chan, sense == FEATURE_SENSE_CHAN ? &(config->features_caller) : &(config->features_callee),featurecode, NULL);
+ if (res == FEATURE_RETURN_PASSDIGITS) {
+ ast_log(LOG_DEBUG, "We are doing nothing here, but this DTMF is not a feature code\n");
+ }
+ break;
+ }
/* Get rid of the frame before we start doing "stuff" with the channels */
ast_frfree(f);
f = NULL;
- config->feature_timer = backup_config.feature_timer;
res = ast_feature_interpret(chan, peer, config, featurecode, sense);
switch(res) {
case FEATURE_RETURN_PASSDIGITS:
- ast_dtmf_stream(other, who, featurecode, 0, 0);
+ ast_log(LOG_DEBUG, "--- Sending DTMF here - 3 Duration %d\n", dtmfduration);
+ ast_dtmf_stream(other, who, featurecode, 0, dtmfduration);
/* Fall through */
case FEATURE_RETURN_SUCCESS:
memset(featurecode, 0, sizeof(chan_featurecode));
Modified: team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/frame.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/frame.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/frame.c Fri Apr 1 06:56:36 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/pine-pine-pine-pine-everywhere-pine-1.6.0/main/rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/rtp.c?view=diff&rev=312383&r1=312382&r2=312383
==============================================================================
--- team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/rtp.c (original)
+++ team/oej/pine-pine-pine-pine-everywhere-pine-1.6.0/main/rtp.c Fri Apr 1 06:56:36 2011
@@ -144,8 +144,11 @@
unsigned int lastdigitts;
char sending_digit; /*!< boolean - are we sending digits */
char send_digit; /*!< digit we are sending */
+ char send_dtmf_frame; /*!< Number of samples in a frame with the current packetization */
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 +193,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 +807,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 +1016,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 (%ld ms)\n", rtp->dtmf_duration, f->len);
rtp->dtmf_duration = rtp->dtmf_timeout = 0;
AST_LIST_INSERT_TAIL(frames, f, frame_list);
}
@@ -1033,6 +1036,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 +1455,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,10 +2726,8 @@
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));
+ /* Raise the seqno */
+ rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
}
/* Since we received a begin, we can safely store the digit and disable any compensation */
@@ -2721,6 +2735,32 @@
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 * (rtp_get_rate(rtp->f.subclass) / 1000); /* How do we get the sample rate for the primary media in this call? */
+
+ 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 +2773,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->received_duration == 0 || 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);
+ /* 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 +2807,68 @@
/* 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 Duration %d Endflag %d Digit %d Send-digit %d\n", rtp->send_duration, rtp->received_duration, duration, rtp->send_endflag, digit, rtp->send_digit);
+
+ //if (dursamples > rtp->received_duration) {
+ //rtp->received_duration = dursamples;
+ //}
+
+ 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 += 160;
+
+ if (rtp->received_duration > rtp->send_duration) {
+ rtp->send_duration = rtp->received_duration;
+ }
rtpheader = (unsigned int *)data;
rtpheader[1] = htonl(rtp->lastdigitts);
@@ -2810,9 +2891,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 sent %d got %d ms (%d samples)\n", rtp->send_duration, duration, dursamples);
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