]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 227829 via svnmerge from
authorMatthew Nicholson <mnicholson@digium.com>
Wed, 4 Nov 2009 21:15:46 +0000 (21:15 +0000)
committerMatthew Nicholson <mnicholson@digium.com>
Wed, 4 Nov 2009 21:15:46 +0000 (21:15 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r227829 | mnicholson | 2009-11-04 15:03:33 -0600 (Wed, 04 Nov 2009) | 17 lines

  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/branches/1.6.1@227832 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_dial.c

index 8a6a2663af3b4a69a03fce82c86fcce07cbe322f..21f4100cb7bb5235352771108eabddcb300fba54 100644 (file)
@@ -1732,21 +1732,70 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                        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;
+                                                       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) {
+                                                               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])) {