From ed2ed2717a6e59ac93653fd6a6b942aef69c369d Mon Sep 17 00:00:00 2001 From: Matthew Nicholson Date: Wed, 4 Nov 2009 21:03:33 +0000 Subject: Merged revisions 227827 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r227827 | mnicholson | 2009-11-04 14:52:27 -0600 (Wed, 04 Nov 2009) | 10 lines This patch modifies the Dial application to monitor the calling channel for hangups while playing back announcements. (closes issue #16005) Reported by: falves11 Patches: dial-announce-hangup-fix1.diff uploaded by mnicholson (license 96) Tested by: mnicholson, falves11 Review: https://reviewboard.asterisk.org/r/407/ ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@227829 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_dial.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 13 deletions(-) (limited to 'apps/app_dial.c') diff --git a/apps/app_dial.c b/apps/app_dial.c index 68a0b042c..7a74d8d22 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -2021,21 +2021,70 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast res = 0; } else { int digit = 0; - /* Start autoservice on the other chan */ - res = ast_autoservice_start(chan); - /* Now Stream the File */ - if (!res) - res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language); - if (!res) { - digit = ast_waitstream(peer, AST_DIGIT_ANY); + struct ast_channel *chans[2]; + struct ast_channel *active_chan; + + chans[0] = chan; + chans[1] = peer; + + /* we need to stream the announcment while monitoring the caller for a hangup */ + + /* stream the file */ + res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language); + if (res) { + res = 0; + ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]); } - /* Ok, done. stop autoservice */ - res = ast_autoservice_stop(chan); - if (digit > 0 && !res) - res = ast_senddigit(chan, digit, 0); - else - res = digit; + ast_set_flag(peer, AST_FLAG_END_DTMF_ONLY); + while (peer->stream) { + int ms; + + ms = ast_sched_wait(peer->sched); + + if (ms < 0 && !peer->timingfunc) { + ast_stopstream(peer); + break; + } + if (ms < 0) + ms = 1000; + + active_chan = ast_waitfor_n(chans, 2, &ms); + if (active_chan) { + struct ast_frame *fr = ast_read(active_chan); + if (!fr) { + ast_hangup(peer); + res = -1; + goto done; + } + switch(fr->frametype) { + case AST_FRAME_DTMF_END: + digit = fr->subclass.integer; + if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) { + ast_stopstream(peer); + res = ast_senddigit(chan, digit, 0); + } + break; + case AST_FRAME_CONTROL: + switch (fr->subclass.integer) { + case AST_CONTROL_HANGUP: + ast_frfree(fr); + ast_hangup(peer); + res = -1; + goto done; + default: + break; + } + break; + default: + /* Ignore all others */ + break; + } + ast_frfree(fr); + } + ast_sched_runq(peer->sched); + } + ast_clear_flag(peer, AST_FLAG_END_DTMF_ONLY); } if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) { -- cgit v1.2.3