Merged revisions 227827 via svnmerge from
[asterisk/asterisk.git] / apps / app_dial.c
index 68a0b04..7a74d8d 100644 (file)
@@ -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])) {