include "logger.h" and errno.h from asterisk.h - usage shows that they
[asterisk/asterisk.git] / apps / app_dial.c
index 0acdc17..dfaa682 100644 (file)
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <sys/time.h>
 #include <sys/signal.h>
 #include <sys/stat.h>
@@ -42,7 +36,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/lock.h"
 #include "asterisk/file.h"
-#include "asterisk/logger.h"
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/options.h"
@@ -278,7 +271,7 @@ enum {
        OPT_ARG_ARRAY_SIZE,
 };
 
-AST_APP_OPTIONS(dial_exec_options, {
+AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
        AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
        AST_APP_OPTION('C', OPT_RESETCDR),
        AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
@@ -293,13 +286,15 @@ AST_APP_OPTIONS(dial_exec_options, {
        AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
        AST_APP_OPTION('k', OPT_CALLEE_PARK),
        AST_APP_OPTION('K', OPT_CALLER_PARK),
+       AST_APP_OPTION('k', OPT_CALLEE_PARK),
+       AST_APP_OPTION('K', OPT_CALLER_PARK),
        AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
        AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
        AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
        AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
        AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
-       AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
        AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
+       AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
        AST_APP_OPTION('p', OPT_SCREENING),
        AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
        AST_APP_OPTION('r', OPT_RINGBACK),
@@ -309,7 +304,11 @@ AST_APP_OPTIONS(dial_exec_options, {
        AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
        AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
        AST_APP_OPTION('W', OPT_CALLER_MONITOR),
-});
+END_OPTIONS );
+
+#define CAN_EARLY_BRIDGE(flags) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
+       OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
+       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK))
 
 /*
  * The list of active channels
@@ -474,12 +473,10 @@ static void do_forward(struct chanlist *o,
        /* Before processing channel, go ahead and check for forwarding */
        o->forwards++;
        if (o->forwards < AST_MAX_FORWARDS) {
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
+               ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
                /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
                if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
+                       ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
                        c = o->chan = NULL;
                        cause = AST_CAUSE_BUSY;
                } else {
@@ -493,8 +490,7 @@ static void do_forward(struct chanlist *o,
                                ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
                }
        } else {
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
+               ast_verb(3, "Too many forwards from %s\n", c->name);
                cause = AST_CAUSE_CONGESTION;
                c = o->chan = NULL;
        }
@@ -563,6 +559,9 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
        struct ast_channel *peer = NULL;
        /* single is set if only one destination is enabled */
        int single = outgoing && !outgoing->next && !ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
+#ifdef HAVE_EPOLL
+       struct chanlist *epollo;
+#endif
        
        if (single) {
                /* Turn off hold music, etc */
@@ -570,7 +569,11 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                /* If we are calling a single channel, make them compatible for in-band tone purpose */
                ast_channel_make_compatible(outgoing->chan, in);
        }
-       
+
+#ifdef HAVE_EPOLL
+       for (epollo = outgoing; epollo; epollo = epollo->next)
+               ast_poll_channel_add(in, epollo->chan);
+#endif 
        
        while (*to && !peer) {
                struct chanlist *o;
@@ -588,8 +591,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                }
                if (pos == 1) { /* only the input channel is available */
                        if (numlines == (num.busy + num.congestion + num.nochan)) {
-                               if (option_verbose > 2)
-                                       ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
+                               ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
                                if (num.busy)
                                        strcpy(pa->status, "BUSY");     
                                else if (num.congestion)
@@ -597,8 +599,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                else if (num.nochan)
                                        strcpy(pa->status, "CHANUNAVAIL");
                        } else {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
+                               ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
                        }
                        *to = 0;
                        return NULL;
@@ -612,8 +613,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                continue;
                        if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
                                if (!peer) {
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
+                                       ast_verb(3, "%s answered %s\n", c->name, in->name);
                                        peer = c;
                                        ast_copy_flags64(peerflags, o,
                                                       OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
@@ -647,8 +647,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                case AST_CONTROL_ANSWER:
                                        /* This is our guy if someone answered. */
                                        if (!peer) {
-                                               if (option_verbose > 2)
-                                                       ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
+                                               ast_verb(3, "%s answered %s\n", c->name, in->name);
                                                peer = c;
                                                ast_copy_flags64(peerflags, o,
                                                               OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
@@ -658,16 +657,16 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                               DIAL_NOFORWARDHTML);
                                                ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
                                                ast_copy_string(c->exten, "", sizeof(c->exten));
-                                               /* Setup early bridge if appropriate */
-                                               ast_channel_early_bridge(in, peer);
+                                               if (CAN_EARLY_BRIDGE(peerflags))
+                                                       /* Setup early bridge if appropriate */
+                                                       ast_channel_early_bridge(in, peer);
                                        }
                                        /* If call has been answered, then the eventual hangup is likely to be normal hangup */
                                        in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
                                        c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
                                        break;
                                case AST_CONTROL_BUSY:
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
+                                       ast_verb(3, "%s is busy\n", c->name);
                                        in->hangupcause = c->hangupcause;
                                        ast_hangup(c);
                                        c = o->chan = NULL;
@@ -675,8 +674,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                        handle_cause(AST_CAUSE_BUSY, &num);
                                        break;
                                case AST_CONTROL_CONGESTION:
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
+                                       ast_verb(3, "%s is circuit-busy\n", c->name);
                                        in->hangupcause = c->hangupcause;
                                        ast_hangup(c);
                                        c = o->chan = NULL;
@@ -684,10 +682,9 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                        handle_cause(AST_CAUSE_CONGESTION, &num);
                                        break;
                                case AST_CONTROL_RINGING:
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
+                                       ast_verb(3, "%s is ringing\n", c->name);
                                        /* Setup early media if appropriate */
-                                       if (single)
+                                       if (single && CAN_EARLY_BRIDGE(peerflags))
                                                ast_channel_early_bridge(in, c);
                                        if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
                                                ast_indicate(in, AST_CONTROL_RINGING);
@@ -695,35 +692,30 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                        }
                                        break;
                                case AST_CONTROL_PROGRESS:
-                                       if (option_verbose > 2)
-                                               ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
+                                       ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
                                        /* Setup early media if appropriate */
-                                       if (single)
+                                       if (single && CAN_EARLY_BRIDGE(peerflags))
                                                ast_channel_early_bridge(in, c);
                                        if (!ast_test_flag64(outgoing, OPT_RINGBACK))
                                                ast_indicate(in, AST_CONTROL_PROGRESS);
                                        break;
                                case AST_CONTROL_VIDUPDATE:
-                                       if (option_verbose > 2)
-                                               ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
+                                       ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
                                        ast_indicate(in, AST_CONTROL_VIDUPDATE);
                                        break;
                                case AST_CONTROL_PROCEEDING:
-                                       if (option_verbose > 2)
-                                               ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
-                                       if (single)
+                                       ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
+                                       if (single && CAN_EARLY_BRIDGE(peerflags))
                                                ast_channel_early_bridge(in, c);
                                        if (!ast_test_flag64(outgoing, OPT_RINGBACK))
                                                ast_indicate(in, AST_CONTROL_PROCEEDING);
                                        break;
                                case AST_CONTROL_HOLD:
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
+                                       ast_verb(3, "Call on %s placed on hold\n", c->name);
                                        ast_indicate(in, AST_CONTROL_HOLD);
                                        break;
                                case AST_CONTROL_UNHOLD:
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
+                                       ast_verb(3, "Call on %s left from hold\n", c->name);
                                        ast_indicate(in, AST_CONTROL_UNHOLD);
                                        break;
                                case AST_CONTROL_OFFHOOK:
@@ -732,8 +724,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                        break;
                                case -1:
                                        if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
+                                               ast_verb(3, "%s stopped sounds\n", c->name);
                                                ast_indicate(in, -1);
                                                pa->sentringing = 0;
                                        }
@@ -782,8 +773,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
                                        const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
                                        if (onedigit_goto(in, context, (char) f->subclass, 1)) {
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
+                                               ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
                                                *to=0;
                                                ast_cdr_noanswer(in->cdr);
                                                *result = f->subclass;
@@ -795,8 +785,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
 
                                if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) && 
                                                  (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
+                                       ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
                                        *to=0;
                                        strcpy(pa->status, "CANCEL");
                                        ast_cdr_noanswer(in->cdr);
@@ -819,20 +808,24 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                ((f->subclass == AST_CONTROL_HOLD) || 
                                 (f->subclass == AST_CONTROL_UNHOLD) || 
                                 (f->subclass == AST_CONTROL_VIDUPDATE))) {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
+                               ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
                                ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
                        }
                        ast_frfree(f);
                }
-               if (!*to && (option_verbose > 2))
-                       ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
+               if (!*to)
+                       ast_verb(3, "Nobody picked up in %d ms\n", orig);
                if (!*to || ast_check_hangup(in)) {
                        ast_cdr_noanswer(in->cdr);
                }
                
        }
 
+#ifdef HAVE_EPOLL
+       for (epollo = outgoing; epollo; epollo = epollo->next)
+               ast_poll_channel_del(in, epollo->chan);
+#endif
+
        return peer;
 }
 
@@ -931,21 +924,20 @@ static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *conf
        /* more efficient to do it like S(x) does since no advanced opts */
        if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
                *calldurationlimit = config->timelimit / 1000;
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n",
+               ast_verb(3, "Setting call duration limit to %d seconds.\n",
                                *calldurationlimit);
                config->timelimit = play_to_caller = play_to_callee =
                config->play_warning = config->warning_freq = 0;
-       } else if (option_verbose > 2) {
-               ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
-               ast_verbose(VERBOSE_PREFIX_4 "timelimit      = %ld\n", config->timelimit);
-               ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", config->play_warning);
-               ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
-               ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
-               ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", config->warning_freq);
-               ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", S_OR(config->start_sound, ""));
-               ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", config->warning_sound);
-               ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", S_OR(config->end_sound, ""));
+       } else {
+               ast_verb(3, "Limit Data for this call:\n");
+               ast_verb(4, "timelimit      = %ld\n", config->timelimit);
+               ast_verb(4, "play_warning   = %ld\n", config->play_warning);
+               ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
+               ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
+               ast_verb(4, "warning_freq   = %ld\n", config->warning_freq);
+               ast_verb(4, "start_sound    = %s\n", S_OR(config->start_sound, ""));
+               ast_verb(4, "warning_sound  = %s\n", config->warning_sound);
+               ast_verb(4, "end_sound      = %s\n", S_OR(config->end_sound, ""));
        }
         if (play_to_caller)
                 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
@@ -1039,8 +1031,7 @@ static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
                static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
                static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
                int i = res2 - '1';
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to %s\n",
+               ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
                                             opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
                ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
        }
@@ -1079,8 +1070,8 @@ static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
                        ast_filedelete(pa->privintro, NULL);
                        if( ast_fileexists(pa->privintro, NULL, NULL ) > 0 )
                                ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
-                       else if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa->privintro);
+                       else
+                               ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
                }
                return 0;       /* the good exit path */
        } else {
@@ -1101,13 +1092,11 @@ static int setup_privacy_args(struct privacy_args *pa,
                l = ast_strdupa(chan->cid.cid_num);
                ast_shrink_phone_number(l);
                if (ast_test_flag64(opts, OPT_PRIVACY) ) {
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3  "Privacy DB is '%s', clid is '%s'\n",
+                       ast_verb(3, "Privacy DB is '%s', clid is '%s'\n",
                                             opt_args[OPT_ARG_PRIVACY], l);
                        pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
                } else {
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3  "Privacy Screening, clid is '%s'\n", l);
+                       ast_verb(3,  "Privacy Screening, clid is '%s'\n", l);
                        pa->privdb_val = AST_PRIVACY_UNKNOWN;
                }
        } else {
@@ -1119,8 +1108,7 @@ static int setup_privacy_args(struct privacy_args *pa,
                        if (*tn2=='/')  /* any other chars to be afraid of? */
                                *tn2 = '=';
                }
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3  "Privacy-- callerid is empty\n");
+               ast_verb(3, "Privacy-- callerid is empty\n");
 
                snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
                l = callerid;
@@ -1184,8 +1172,8 @@ static int setup_privacy_args(struct privacy_args *pa,
                                ast_filedelete(pa->privintro, NULL);
                                if (ast_fileexists(pa->privintro,NULL,NULL ) > 0 )
                                        ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
-                               else if (option_verbose > 2)
-                                       ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa->privintro);
+                               else
+                                       ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
                                return -1;
                        }
                        if (!ast_streamfile(chan, "vm-dialout", chan->language) )
@@ -1256,8 +1244,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 
        if (ast_test_flag64(&opts, OPT_OPERMODE)) {
                opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
+               ast_verb(3, "Setting operator services mode to %d.\n", opermode);
        }
        
        if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
@@ -1267,8 +1254,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                        pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
                        goto done;
                }
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
+               ast_verb(3, "Setting call duration limit to %d seconds.\n", calldurationlimit);
        }
 
        if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
@@ -1358,8 +1344,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                        }
                        tmp->forwards++;
                        if (tmp->forwards < AST_MAX_FORWARDS) {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n",
+                               ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n",
                                        chan->name, tech, stuff, tc->name);
                                ast_hangup(tc);
                                /* If we have been told to ignore forwards, just set this channel to null
@@ -1367,8 +1352,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                                if (ast_test_flag64(&opts, OPT_IGNORE_FORWARDING)) {
                                        tc = NULL;
                                        cause = AST_CAUSE_BUSY;
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n",
+                                       ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n",
                                                        chan->name, tech, stuff);
                                } else {
                                        tc = ast_request(tech, chan->nativeformats, stuff, &cause);
@@ -1378,8 +1362,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                                else
                                        ast_channel_inherit_variables(chan, tc);
                        } else {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tc->name);
+                               ast_verb(3, "Too many forwards from %s\n", tc->name);
                                ast_hangup(tc);
                                tc = NULL;
                                cause = AST_CAUSE_CONGESTION;
@@ -1416,6 +1399,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                tc->cid.cid_pres = chan->cid.cid_pres;
                tc->cid.cid_ton = chan->cid.cid_ton;
                tc->cid.cid_tns = chan->cid.cid_tns;
+               tc->cid.cid_ani2 = chan->cid.cid_ani2;
                tc->adsicpe = chan->adsicpe;
                tc->transfercapability = chan->transfercapability;
 
@@ -1443,16 +1427,14 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                if (res) {
                        /* Again, keep going even if there's an error */
                        ast_debug(1, "ast call on peer returned %d\n", res);
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
+                       ast_verb(3, "Couldn't call %s\n", numsubst);
                        ast_hangup(tc);
                        tc = NULL;
                        ast_free(tmp);
                        continue;
                } else {
                        senddialevent(chan, tc);
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
+                       ast_verb(3, "Called %s\n", numsubst);
                        if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
                                ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
                }
@@ -1558,7 +1540,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                        /* Ok, done. stop autoservice */
                        res = ast_autoservice_stop(chan);
                        if (digit > 0 && !res)
-                               res = ast_senddigit(chan, digit); 
+                               res = ast_senddigit(chan, digit, 0); 
                        else
                                res = digit;
 
@@ -1727,12 +1709,12 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                        if (!ast_strlen_zero(dtmfcalled)) { 
                                if (option_verbose > 2)
                                        ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
-                               res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
+                               res = ast_dtmf_stream(peer,chan,dtmfcalled,250,0);
                        }
                        if (!ast_strlen_zero(dtmfcalling)) {
                                if (option_verbose > 2)
                                        ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
-                               res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
+                               res = ast_dtmf_stream(chan,peer,dtmfcalling,250,0);
                        }
                }
                
@@ -1802,21 +1784,25 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
                strcpy(peer->context, chan->context);
 
                if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
+                       int autoloopflag;
+                       int found;
                        strcpy(peer->exten, "h");
                        peer->priority = 1;
-                       while (ast_exists_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num)) {
-                               if ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num))) {
-                                       /* Something bad happened, or a hangup has been requested. */
-                                       ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
-                                       if (option_verbose > 1)
-                                               ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
-                                       break;
-                               }
+                       autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP);       /* save value to restore at the end */
+                       ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
+                       
+                       while ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found,1))) {
                                peer->priority++;
                        }
+                       if (found && res) {
+                               /* Something bad happened, or a hangup has been requested. */
+                               ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
+                               ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
+                       }
+                       ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);  /* set it back the way it was */
                }
                if (res != AST_PBX_NO_HANGUP_PEER) {
-                       if (!chan->_softhangup)
+                       if (!ast_check_hangup(chan))
                                chan->hangupcause = peer->hangupcause;
                        ast_hangup(peer);
                }
@@ -1835,7 +1821,7 @@ out:
        senddialendevent(chan, pa.status);
        ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
        
-       if ((ast_test_flag64(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
+       if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE)) {
                if (calldurationlimit)
                        chan->whentohangup = 0;
                res = 0;
@@ -1983,7 +1969,7 @@ static int load_module(void)
        if (!con)
                ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
        else
-               ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free, "app_dial");
+               ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free_ptr, "app_dial");
 
        res = ast_register_application(app, dial_exec, synopsis, descrip);
        res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);