From 3375c0eb73bebd2fa38af23438779b0299be1e0a Mon Sep 17 00:00:00 2001 From: tilghman Date: Tue, 20 Jul 2010 22:30:46 +0000 Subject: Merged revisions 278272 via svnmerge from https://origsvn.digium.com/svn/asterisk/trunk ................ r278272 | tilghman | 2010-07-20 17:26:23 -0500 (Tue, 20 Jul 2010) | 11 lines Merged revisions 278167 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r278167 | tilghman | 2010-07-20 15:59:06 -0500 (Tue, 20 Jul 2010) | 4 lines Do not queue up DTMF frames while a call is on hold. (Fixes ABE-2110) ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@278273 f38db490-d61c-443f-a65b-d21fe96a405b --- include/asterisk/channel.h | 12 ++++++++++++ main/autoservice.c | 22 +++++++++++++++++++++- main/features.c | 7 +++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index f50229969..7dde431be 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -1584,6 +1584,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); + /*! * \brief Enable or disable timer ticks for a channel * diff --git a/main/autoservice.c b/main/autoservice.c index 6b9633301..731038fef 100644 --- a/main/autoservice.c +++ b/main/autoservice.c @@ -56,6 +56,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. */ @@ -286,7 +287,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); @@ -296,6 +299,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); diff --git a/main/features.c b/main/features.c index 0668ae657..d2f989835 100644 --- a/main/features.c +++ b/main/features.c @@ -978,6 +978,7 @@ static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct /* First play for caller, put other channel on auto service */ if (ast_autoservice_start(callee_chan)) return -1; + ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END); if (ast_stream_and_wait(caller_chan, audiofile, "")) { ast_log(LOG_WARNING, "Failed to play automon message!\n"); ast_autoservice_stop(callee_chan); @@ -988,6 +989,7 @@ static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct /* Then play for callee, put other channel on auto service */ if (ast_autoservice_start(caller_chan)) return -1; + ast_autoservice_ignore(caller_chan, AST_FRAME_DTMF_END); if (ast_stream_and_wait(callee_chan, audiofile, "")) { ast_log(LOG_WARNING, "Failed to play automon message !\n"); ast_autoservice_stop(caller_chan); @@ -1130,6 +1132,7 @@ static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel * 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, "")) { ast_log(LOG_WARNING, "Failed to play courtesy tone!\n"); ast_autoservice_stop(callee_chan); @@ -1277,6 +1280,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)); @@ -1418,6 +1422,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 */ @@ -1624,6 +1629,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st while (!newchan && !atxferdropcall && tries < atxfercallbackretries) { /* Trying to transfer again */ ast_autoservice_start(transferee); + ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END); ast_indicate(transferee, AST_CONTROL_HOLD); newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats), @@ -1964,6 +1970,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); -- cgit v1.2.3