Do not queue up DTMF frames while a call is on hold.

(Fixes ABE-2110)


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@278167 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Tilghman Lesher 15 years ago
parent b765278efe
commit 8618bacfd8

@ -1246,6 +1246,18 @@ int ast_autoservice_start(struct ast_channel *chan);
*/
int ast_autoservice_stop(struct ast_channel *chan);
/*!
* \brief Ignore certain frame types
* \note Normally, we cache DTMF, IMAGE, HTML, TEXT, and CONTROL frames
* while a channel is in autoservice and queue them up when taken out of
* autoservice. When this is not desireable, this API may be used to
* cause the channel to ignore those frametypes after the channel is put
* into autoservice, but before autoservice is stopped.
* \retval 0 success
* \retval -1 channel is not in autoservice
*/
int ast_autoservice_ignore(struct ast_channel *chan, enum ast_frame_type ftype);
/* If built with DAHDI optimizations, force a scheduled expiration on the
timer fd, at which point we call the callback function / data */
int ast_settimeout(struct ast_channel *c, int samples, int (*func)(const void *data), void *data);

@ -61,6 +61,7 @@ struct asent {
* it gets stopped for the last time. */
unsigned int use_count;
unsigned int orig_end_dtmf_flag:1;
unsigned int ignore_frame_types;
/*! Frames go on at the head of deferred_frames, so we have the frames
* from newest to oldest. As we put them at the head of the readq, we'll
* end up with them in the right order for the channel's readq. */
@ -292,7 +293,9 @@ int ast_autoservice_stop(struct ast_channel *chan)
ast_channel_lock(chan);
while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
ast_queue_frame_head(chan, f);
if (!((1 << f->frametype) & as->ignore_frame_types)) {
ast_queue_frame_head(chan, f);
}
ast_frfree(f);
}
ast_channel_unlock(chan);
@ -302,6 +305,23 @@ int ast_autoservice_stop(struct ast_channel *chan)
return res;
}
int ast_autoservice_ignore(struct ast_channel *chan, enum ast_frame_type ftype)
{
struct asent *as;
int res = -1;
AST_LIST_LOCK(&aslist);
AST_LIST_TRAVERSE(&aslist, as, list) {
if (as->chan == chan) {
res = 0;
as->ignore_frame_types |= (1 << ftype);
break;
}
}
AST_LIST_UNLOCK(&aslist);
return res;
}
void ast_autoservice_init(void)
{
ast_cond_init(&as_cond, NULL);

@ -695,6 +695,7 @@ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *pee
if (!ast_strlen_zero(courtesytone)) {
if (ast_autoservice_start(callee_chan))
return -1;
ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
if (ast_stream_and_wait(caller_chan, courtesytone, caller_chan->language, "")) {
ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
ast_autoservice_stop(callee_chan);
@ -798,6 +799,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
transferer_real_context = real_ctx(transferer, transferee);
/* Start autoservice on chan while we talk to the originator */
ast_autoservice_start(transferee);
ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
ast_indicate(transferee, AST_CONTROL_HOLD);
memset(xferto, 0, sizeof(xferto));
@ -914,6 +916,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
transferer_real_context = real_ctx(transferer, transferee);
/* Start autoservice on chan while we talk to the originator */
ast_autoservice_start(transferee);
ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
ast_indicate(transferee, AST_CONTROL_HOLD);
/* Transfer */
@ -1229,6 +1232,7 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
}
ast_autoservice_start(idle);
ast_autoservice_ignore(idle, AST_FRAME_DTMF_END);
if (!ast_strlen_zero(feature->moh_class))
ast_moh_start(idle, feature->moh_class, NULL);

Loading…
Cancel
Save