[asterisk-commits] oej: branch oej/codename-pineapple r47362 - in /team/oej/codename-pineapple: ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Nov 9 06:44:10 MST 2006


Author: oej
Date: Thu Nov  9 07:44:09 2006
New Revision: 47362

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47362
Log:
update

Removed:
    team/oej/codename-pineapple/aclocal.m4
Modified:
    team/oej/codename-pineapple/apps/app_dial.c
    team/oej/codename-pineapple/apps/app_queue.c
    team/oej/codename-pineapple/apps/app_voicemail.c
    team/oej/codename-pineapple/channels/Makefile
    team/oej/codename-pineapple/channels/chan_agent.c
    team/oej/codename-pineapple/channels/chan_alsa.c
    team/oej/codename-pineapple/channels/chan_features.c
    team/oej/codename-pineapple/channels/chan_gtalk.c
    team/oej/codename-pineapple/channels/chan_h323.c
    team/oej/codename-pineapple/channels/chan_iax2.c
    team/oej/codename-pineapple/channels/chan_jingle.c
    team/oej/codename-pineapple/channels/chan_local.c
    team/oej/codename-pineapple/channels/chan_mgcp.c
    team/oej/codename-pineapple/channels/chan_misdn.c
    team/oej/codename-pineapple/channels/chan_nbs.c
    team/oej/codename-pineapple/channels/chan_oss.c
    team/oej/codename-pineapple/channels/chan_phone.c
    team/oej/codename-pineapple/channels/chan_sip.c
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/chan_skinny.c
    team/oej/codename-pineapple/channels/chan_zap.c
    team/oej/codename-pineapple/channels/sip3/Makefile
    team/oej/codename-pineapple/channels/sip3/sip3_auth.c
    team/oej/codename-pineapple/channels/sip3/sip3_callerid.c
    team/oej/codename-pineapple/channels/sip3/sip3_cliami.c
    team/oej/codename-pineapple/channels/sip3/sip3_compose.c
    team/oej/codename-pineapple/channels/sip3/sip3_config.c
    team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
    team/oej/codename-pineapple/channels/sip3/sip3_domain.c
    team/oej/codename-pineapple/channels/sip3/sip3_network.c
    team/oej/codename-pineapple/channels/sip3/sip3_parse.c
    team/oej/codename-pineapple/channels/sip3/sip3_refer.c
    team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c
    team/oej/codename-pineapple/channels/sip3/sip3_services.c
    team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c
    team/oej/codename-pineapple/channels/sip3/sip3funcs.h
    team/oej/codename-pineapple/configure
    team/oej/codename-pineapple/include/asterisk/channel.h
    team/oej/codename-pineapple/include/asterisk/frame.h
    team/oej/codename-pineapple/include/asterisk/manager.h
    team/oej/codename-pineapple/include/asterisk/stringfields.h
    team/oej/codename-pineapple/main/app.c
    team/oej/codename-pineapple/main/asterisk.c
    team/oej/codename-pineapple/main/channel.c
    team/oej/codename-pineapple/main/cli.c
    team/oej/codename-pineapple/main/frame.c
    team/oej/codename-pineapple/main/logger.c
    team/oej/codename-pineapple/main/manager.c
    team/oej/codename-pineapple/main/pbx.c
    team/oej/codename-pineapple/main/utils.c
    team/oej/codename-pineapple/pbx/pbx_dundi.c
    team/oej/codename-pineapple/res/res_agi.c
    team/oej/codename-pineapple/res/res_features.c
    team/oej/codename-pineapple/res/res_musiconhold.c

Modified: team/oej/codename-pineapple/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_dial.c?view=diff&rev=47362&r1=47361&r2=47362
==============================================================================
--- team/oej/codename-pineapple/apps/app_dial.c (original)
+++ team/oej/codename-pineapple/apps/app_dial.c Thu Nov  9 07:44:09 2006
@@ -318,30 +318,47 @@
 
 #define AST_MAX_WATCHERS 256
 
-#define HANDLE_CAUSE(cause, chan) do { \
-	switch(cause) { \
-	case AST_CAUSE_BUSY: \
-		if (chan->cdr) \
-			ast_cdr_busy(chan->cdr); \
-		numbusy++; \
-		break; \
-	case AST_CAUSE_CONGESTION: \
-		if (chan->cdr) \
-			ast_cdr_failed(chan->cdr); \
-		numcongestion++; \
-		break; \
-	case AST_CAUSE_UNREGISTERED: \
-		if (chan->cdr) \
-			ast_cdr_failed(chan->cdr); \
-		numnochan++; \
-		break; \
-	case AST_CAUSE_NORMAL_CLEARING: \
-		break; \
-	default: \
-		numnochan++; \
-		break; \
-	} \
-} while (0)
+/*
+ * argument to handle_cause() and other functions.
+ */
+struct cause_args {
+	struct ast_channel *chan;
+	int busy;
+	int congestion;
+	int nochan;
+};
+
+static void handle_cause(int cause, struct cause_args *num)
+{
+	struct ast_cdr *cdr = num->chan->cdr;
+
+	switch(cause) {
+	case AST_CAUSE_BUSY:
+		if (cdr)
+			ast_cdr_busy(cdr);
+		num->busy++;
+		break;
+
+	case AST_CAUSE_CONGESTION:
+		if (cdr)
+			ast_cdr_failed(cdr);
+		num->congestion++;
+		break;
+
+	case AST_CAUSE_UNREGISTERED:
+		if (cdr)
+			ast_cdr_failed(cdr);
+		num->nochan++;
+		break;
+
+	case AST_CAUSE_NORMAL_CLEARING:
+		break;
+
+	default:
+		num->nochan++;
+		break;
+	}
+}
 
 /* free the buffer if allocated, and set the pointer to the second arg */
 #define S_REPLACE(s, new_val)		\
@@ -402,12 +419,113 @@
 					src->name, dialstatus);
 }	
 
-static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
+/* helper function for wait_for_answer() */
+static void do_forward(struct dial_localuser *o,
+	struct cause_args *num, struct ast_flags *peerflags, int single)
 {
-	int numbusy = busystart;
-	int numcongestion = congestionstart;
-	int numnochan = nochanstart;
-	int prestart = busystart + congestionstart + nochanstart;
+	char tmpchan[256];
+	struct ast_channel *c = o->chan; /* the winner */
+	struct ast_channel *in = num->chan; /* the input channel */
+	char *stuff;
+	char *tech;
+	int cause;
+
+	ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
+	if ((stuff = strchr(tmpchan, '/'))) {
+		*stuff++ = '\0';
+		tech = tmpchan;
+	} else {
+		const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
+		snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
+		stuff = tmpchan;
+		tech = "Local";
+	}
+	/* 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);
+		/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
+		if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
+			c = o->chan = NULL;
+			cause = AST_CAUSE_BUSY;
+		} else {
+			/* Setup parameters */
+			c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
+			if (!c)
+				ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
+			else
+				ast_channel_inherit_variables(in, o->chan);
+		}
+	} else {
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
+		cause = AST_CAUSE_CONGESTION;
+		c = o->chan = NULL;
+	}
+	if (!c) {
+		ast_clear_flag(o, DIAL_STILLGOING);	
+		handle_cause(cause, num);
+	} else {
+		char *new_cid_num, *new_cid_name;
+		struct ast_channel *src;
+
+		ast_rtp_make_compatible(c, in, single);
+		if (ast_test_flag(o, OPT_FORCECLID)) {
+			new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
+			new_cid_name = NULL; /* XXX no name ? */
+			src = c;	/* XXX possible bug in previous code, which used 'winner' ? it may have changed */
+		} else {
+			new_cid_num = ast_strdup(in->cid.cid_num);
+			new_cid_name = ast_strdup(in->cid.cid_name);
+			src = in;
+		}
+		ast_string_field_set(c, accountcode, src->accountcode);
+		c->cdrflags = src->cdrflags;
+		S_REPLACE(c->cid.cid_num, new_cid_num);
+		S_REPLACE(c->cid.cid_name, new_cid_name);
+
+		if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
+			S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
+		}
+		S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
+		if (ast_call(c, tmpchan, 0)) {
+			ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
+			ast_clear_flag(o, DIAL_STILLGOING);	
+			ast_hangup(c);
+			c = o->chan = NULL;
+			num->nochan++;
+		} else {
+			senddialevent(in, c);
+			/* After calling, set callerid to extension */
+			if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
+				char cidname[AST_MAX_EXTENSION];
+				ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
+			}
+		}
+	}
+	/* Hangup the original channel now, in case we needed it */
+	ast_hangup(c);
+}
+
+/* argument used for some functions. */
+struct privacy_args {
+        int sentringing;
+        int privdb_val;
+        char privcid[256];
+        char privintro[1024];
+        char status[256];
+};
+
+static struct ast_channel *wait_for_answer(struct ast_channel *in,
+	struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags,
+	struct privacy_args *pa,
+	const struct cause_args *num_in, int priority_jump, int *result)
+{
+	struct cause_args num = *num_in;
+	int prestart = num.busy + num.congestion + num.nochan;
 	int orig = *to;
 	struct ast_channel *peer = NULL;
 	/* single is set if only one destination is enabled */
@@ -436,20 +554,20 @@
 			numlines++;
 		}
 		if (pos == 1) {	/* only the input channel is available */
-			if (numlines == (numbusy + numcongestion + numnochan)) {
+			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, numbusy, numcongestion, numnochan);
-				if (numbusy)
-					strcpy(status, "BUSY");	
-				else if (numcongestion)
-					strcpy(status, "CONGESTION");
-				else if (numnochan)
-					strcpy(status, "CHANUNAVAIL");
+					ast_verbose( VERBOSE_PREFIX_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)
+					strcpy(pa->status, "CONGESTION");
+				else if (num.nochan)
+					strcpy(pa->status, "CHANUNAVAIL");
 				if (ast_opt_priority_jumping || priority_jump)
 					ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
 			} 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, numbusy, numcongestion, numnochan);
+					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);
 			}
 			*to = 0;
 			return NULL;
@@ -479,91 +597,9 @@
 			}
 			if (c != winner)
 				continue;
+			/* here, o->chan == c == winner */
 			if (!ast_strlen_zero(c->call_forward)) {
-				char tmpchan[256];
-				char *stuff;
-				char *tech;
-				int cause;
-
-				ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
-				if ((stuff = strchr(tmpchan, '/'))) {
-					*stuff++ = '\0';
-					tech = tmpchan;
-				} else {
-					const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
-					snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
-					stuff = tmpchan;
-					tech = "Local";
-				}
-				/* 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);
-					/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
-					if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
-						c = o->chan = NULL;
-						cause = AST_CAUSE_BUSY;
-					} else {
-						/* Setup parameters */
-						c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
-						if (!c)
-							ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
-						else
-							ast_channel_inherit_variables(in, o->chan);
-					}
-				} else {
-					if (option_verbose > 2)
-						ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
-					cause = AST_CAUSE_CONGESTION;
-					c = o->chan = NULL;
-				}
-				if (!c) {
-					ast_clear_flag(o, DIAL_STILLGOING);	
-					HANDLE_CAUSE(cause, in);
-				} else {
-					ast_rtp_make_compatible(c, in, single);
-					if (c->cid.cid_num)
-						free(c->cid.cid_num);
-					c->cid.cid_num = NULL;
-					if (c->cid.cid_name)
-						free(c->cid.cid_name);
-					c->cid.cid_name = NULL;
-
-					if (ast_test_flag(o, OPT_FORCECLID)) {
-						c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
-						ast_string_field_set(c, accountcode, winner->accountcode);
-						c->cdrflags = winner->cdrflags;
-					} else {
-						c->cid.cid_num = ast_strdup(in->cid.cid_num);
-						c->cid.cid_name = ast_strdup(in->cid.cid_name);
-						ast_string_field_set(c, accountcode, in->accountcode);
-						c->cdrflags = in->cdrflags;
-					}
-
-					if (in->cid.cid_ani) {
-						S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
-					}
-					S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
-					if (ast_call(c, tmpchan, 0)) {
-						ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
-						ast_clear_flag(o, DIAL_STILLGOING);	
-						ast_hangup(c);
-						c = o->chan = NULL;
-						numnochan++;
-					} else {
-						senddialevent(in, c);
-						/* After calling, set callerid to extension */
-						if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
-							char cidname[AST_MAX_EXTENSION];
-							ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
-						}
-					}
-				}
-				/* Hangup the original channel now, in case we needed it */
-				ast_hangup(winner);
+				do_forward(o, &num, peerflags, single);
 				continue;
 			}
 			f = ast_read(winner);
@@ -572,7 +608,7 @@
 				ast_hangup(c);
 				c = o->chan = NULL;
 				ast_clear_flag(o, DIAL_STILLGOING);
-				HANDLE_CAUSE(in->hangupcause, in);
+				handle_cause(in->hangupcause, &num);
 				continue;
 			}
 			if (f->frametype == AST_FRAME_CONTROL) {
@@ -605,7 +641,7 @@
 					ast_hangup(c);
 					c = o->chan = NULL;
 					ast_clear_flag(o, DIAL_STILLGOING);	
-					HANDLE_CAUSE(AST_CAUSE_BUSY, in);
+					handle_cause(AST_CAUSE_BUSY, &num);
 					break;
 				case AST_CONTROL_CONGESTION:
 					if (option_verbose > 2)
@@ -614,7 +650,7 @@
 					ast_hangup(c);
 					c = o->chan = NULL;
 					ast_clear_flag(o, DIAL_STILLGOING);
-					HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
+					handle_cause(AST_CAUSE_CONGESTION, &num);
 					break;
 				case AST_CONTROL_RINGING:
 					if (option_verbose > 2)
@@ -622,9 +658,9 @@
 					/* Setup early media if appropriate */
 					if (single)
 						ast_channel_early_bridge(in, c);
-					if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
+					if (!(pa->sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
 						ast_indicate(in, AST_CONTROL_RINGING);
-						(*sentringing)++;
+						pa->sentringing++;
 					}
 					break;
 				case AST_CONTROL_PROGRESS:
@@ -668,7 +704,7 @@
 						if (option_verbose > 2)
 							ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
 						ast_indicate(in, -1);
-						(*sentringing) = 0;
+						pa->sentringing = 0;
 					}
 					break;
 				default:
@@ -704,13 +740,14 @@
 			if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
 				/* Got hung up */
 				*to = -1;
-				strcpy(status, "CANCEL");
+				strcpy(pa->status, "CANCEL");
 				if (f)
 					ast_frfree(f);
 				return NULL;
 			}
 
-			if (f && (f->frametype == AST_FRAME_DTMF)) {
+			/* now f is guaranteed non-NULL */
+			if (f->frametype == AST_FRAME_DTMF) {
 				if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
 					const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
 					if (onedigit_goto(in, context, (char) f->subclass, 1)) {
@@ -718,7 +755,7 @@
 							ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 						*to=0;
 						*result = f->subclass;
-						strcpy(status, "CANCEL");
+						strcpy(pa->status, "CANCEL");
 						ast_frfree(f);
 						return NULL;
 					}
@@ -729,14 +766,14 @@
 					if (option_verbose > 2)
 						ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 					*to=0;
-					strcpy(status, "CANCEL");
+					strcpy(pa->status, "CANCEL");
 					ast_frfree(f);
 					return NULL;
 				}
 			}
 
 			/* Forward HTML stuff */
-			if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
+			if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
 				if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
 					ast_log(LOG_WARNING, "Unable to send URL\n");
 			
@@ -782,37 +819,259 @@
 	return 0;
 }
 
+static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
+	char *parse, unsigned int *calldurationlimit)
+{
+	char *limit_str, *warning_str, *warnfreq_str;
+	const char *var;
+	int play_to_caller=0,play_to_callee=0;
+	int delta;
+
+	limit_str = strsep(&warnfreq_str, ":");
+	warning_str = strsep(&warnfreq_str, ":");
+	warnfreq_str = parse;
+
+	config->timelimit = atol(limit_str);
+	if (warning_str)
+		config->play_warning = atol(warning_str);
+	if (warnfreq_str)
+		config->warning_freq = atol(warnfreq_str);
+
+	if (!config->timelimit) {
+		ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
+		config->timelimit = config->play_warning = config->warning_freq = 0;
+		config->warning_sound = NULL;
+		return -1;	/* error */
+	} else if ( (delta = config->play_warning - config->timelimit) > 0) {
+		int w = config->warning_freq;
+
+		/* If the first warning is requested _after_ the entire call would end,
+		   and no warning frequency is requested, then turn off the warning. If
+		   a warning frequency is requested, reduce the 'first warning' time by
+		   that frequency until it falls within the call's total time limit.
+		   Graphically:
+				  timelim->|    delta        |<-playwarning
+			0__________________|_________________|
+					 | w  |    |    |    |
+
+		   so the number of intervals to cut is 1+(delta-1)/w
+		*/
+
+		if (w == 0) {
+			config->play_warning = 0;
+		} else {
+			config->play_warning -= w * ( 1 + (delta-1)/w );
+			if (config->play_warning < 1)
+				config->play_warning = config->warning_freq = 0;
+		}
+	}
+
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
+	play_to_caller = var ? ast_true(var) : 1;
+	
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
+	play_to_callee = var ? ast_true(var) : 0;
+	
+	if (!play_to_caller && !play_to_callee)
+		play_to_caller = 1;
+	
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
+	config->warning_sound = S_OR(var, "timeleft");
+
+	/* The code looking at config wants a NULL, not just "", to decide
+	 * that the message should not be played, so we replace "" with NULL.
+	 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
+	 * not found.
+	 */
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
+	config->end_sound = S_OR(var, NULL);
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
+	config->start_sound = S_OR(var, NULL);
+
+	/* undo effect of S(x) in case they are both used */
+	*calldurationlimit = 0;
+	/* 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",
+				*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, ""));
+	}
+        if (play_to_caller)
+                ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
+        if (play_to_callee)
+                ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
+	return 0;
+}
+
+static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
+    struct ast_flags *opts, char **opt_args, struct privacy_args *pa)
+{
+
+	int res2;
+	int loopcount = 0;
+
+	/* Get the user's intro, store it in priv-callerintros/$CID, 
+	   unless it is already there-- this should be done before the 
+	   call is actually dialed  */
+
+	/* all ring indications and moh for the caller has been halted as soon as the 
+	   target extension was picked up. We are going to have to kill some
+	   time and make the caller believe the peer hasn't picked up yet */
+
+	if (ast_test_flag(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
+		ast_indicate(chan, -1);
+		ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
+	} else if (ast_test_flag(opts, OPT_RINGBACK)) {
+		ast_indicate(chan, AST_CONTROL_RINGING);
+		pa->sentringing++;
+	}
+
+	/* Start autoservice on the other chan ?? */
+	res2 = ast_autoservice_start(chan);
+	/* Now Stream the File */
+	for (loopcount = 0; loopcount < 3; loopcount++) {
+		if (res2 && loopcount == 0)	/* error in ast_autoservice_start() */
+			break;
+		if (!res2)	/* on timeout, play the message again */
+			res2 = ast_play_and_wait(peer,"priv-callpending");
+		if (!valid_priv_reply(opts, res2))
+			res2 = 0;
+		/* priv-callpending script: 
+		   "I have a caller waiting, who introduces themselves as:"
+		*/
+		if (!res2)
+			res2 = ast_play_and_wait(peer, pa->privintro);
+		if (!valid_priv_reply(opts, res2))
+			res2 = 0;
+		/* now get input from the called party, as to their choice */
+		if( !res2 ) {
+			/* XXX can we have both, or they are mutually exclusive ? */
+			if( ast_test_flag(opts, OPT_PRIVACY) )
+				res2 = ast_play_and_wait(peer,"priv-callee-options");
+			if( ast_test_flag(opts, OPT_SCREENING) )
+				res2 = ast_play_and_wait(peer,"screen-callee-options");
+		}
+		/*! \page DialPrivacy Dial Privacy scripts
+		\par priv-callee-options script:
+			"Dial 1 if you wish this caller to reach you directly in the future,
+				and immediately connect to their incoming call
+			 Dial 2 if you wish to send this caller to voicemail now and 
+				forevermore.
+			 Dial 3 to send this caller to the torture menus, now and forevermore.
+			 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
+			 Dial 5 to allow this caller to come straight thru to you in the future,
+				but right now, just this once, send them to voicemail."
+		\par screen-callee-options script:
+			"Dial 1 if you wish to immediately connect to the incoming call
+			 Dial 2 if you wish to send this caller to voicemail.
+			 Dial 3 to send this caller to the torture menus.
+			 Dial 4 to send this caller to a simple "go away" menu.
+		*/
+		if (valid_priv_reply(opts, res2))
+			break;
+		/* invalid option */
+		res2 = ast_play_and_wait(peer, "vm-sorry");
+	}
+
+	if (ast_test_flag(opts, OPT_MUSICBACK)) {
+		ast_moh_stop(chan);
+	} else if (ast_test_flag(opts, OPT_RINGBACK)) {
+		ast_indicate(chan, -1);
+		pa->sentringing=0;
+	}
+	ast_autoservice_stop(chan);
+	if(ast_test_flag(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
+		/* map keypresses to various things, the index is res2 - '1' */
+		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",
+					     opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
+		ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
+	}
+	switch (res2) {
+	case '1':
+		break;
+	case '2':
+		ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
+		break;
+	case '3':
+		ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
+		break;
+	case '4':
+		ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
+		break;
+	case '5':
+		/* XXX should we set status to DENY ? */
+		if( ast_test_flag(opts, OPT_PRIVACY) )
+			break;
+		/* if not privacy, then 5 is the same as "default" case */
+	default:	/* bad input or -1 if failure to start autoservice */
+		/* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
+		/* well, there seems basically two choices. Just patch the caller thru immediately,
+			  or,... put 'em thru to voicemail. */
+		/* since the callee may have hung up, let's do the voicemail thing, no database decision */
+		ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
+		/* XXX should we set status to DENY ? */
+		/* XXX what about the privacy flags ? */
+		break;
+	}
+
+	if (res2 == '1') {	/* the only case where we actually connect */
+		/* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll 
+		   just clog things up, and it's not useful information, not being tied to a CID */
+		if( strncmp(pa->privcid,"NOCALLERID",10) == 0 || ast_test_flag(opts, OPT_SCREEN_NOINTRO) ) {
+			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);
+		}
+		return 0;	/* the good exit path */
+	} else {
+		ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
+		return -1;
+	}
+}
+
 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
 {
-	int res = -1;
+	int res = -1;	/* default: error */
 	struct ast_module_user *u;
-	char *rest, *cur;
-	struct dial_localuser *outgoing = NULL;
+	char *rest, *cur;	/* scan the list of destinations */
+	struct dial_localuser *outgoing = NULL;	/* list of destinations */
 	struct ast_channel *peer;
-	int to;
-	int numbusy = 0;
-	int numcongestion = 0;
-	int numnochan = 0;
+	int to;	/* timeout */
+	struct cause_args num = { chan, 0, 0, 0 };
 	int cause;
 	char numsubst[AST_MAX_EXTENSION];
 	char cidname[AST_MAX_EXTENSION];
-	int privdb_val = 0;
+
+	struct ast_bridge_config config;
 	unsigned int calldurationlimit = 0;
-	long timelimit = 0;
-	long play_warning = 0;
-	long warning_freq = 0;
-	const char *warning_sound = NULL;
-	const char *end_sound = NULL;
-	const char *start_sound = NULL;
 	char *dtmfcalled = NULL, *dtmfcalling = NULL;
-	char status[256];
-	int play_to_caller = 0, play_to_callee = 0;
+	struct privacy_args pa = {
+		.sentringing = 0,
+		.privdb_val = 0,
+	};
 	int sentringing = 0, moh = 0;
 	const char *outbound_group = NULL;
 	int result = 0;
 	time_t start_time;
-	char privintro[1024];
-	char privcid[256];
 	char *parse;
 	int opermode = 0;
 	AST_DECLARE_APP_ARGS(args,
@@ -829,11 +1088,13 @@
 		return -1;
 	}
 
-	u = ast_module_user_add(chan);
+	u = ast_module_user_add(chan);	/* XXX is this the right place ? */
 
 	parse = ast_strdupa(data);
 
 	AST_STANDARD_APP_ARGS(args, parse);
+
+	memset(&config,0,sizeof(struct ast_bridge_config));
 
 	if (!ast_strlen_zero(args.options) &&
 			ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
@@ -845,9 +1106,7 @@
 	}
 
 	if (ast_test_flag(&opts, OPT_OPERMODE)) {
-		if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
-			opermode = 1;
-		else opermode = atoi(opt_args[OPT_ARG_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);
 	}
@@ -868,77 +1127,8 @@
 	}
 
 	if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
-		char *limit_str, *warning_str, *warnfreq_str;
-		const char *var;
-
-		warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
-		limit_str = strsep(&warnfreq_str, ":");
-		warning_str = strsep(&warnfreq_str, ":");
-
-		timelimit = atol(limit_str);
-		if (warning_str)
-			play_warning = atol(warning_str);
-		if (warnfreq_str)
-			warning_freq = atol(warnfreq_str);
-
-		if (!timelimit) {
-			ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
+		if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
 			goto done;
-		} else if (play_warning > timelimit) {
-			/* If the first warning is requested _after_ the entire call would end,
-			   and no warning frequency is requested, then turn off the warning. If
-			   a warning frequency is requested, reduce the 'first warning' time by
-			   that frequency until it falls within the call's total time limit.
-			*/
-
-			if (!warning_freq) {
-				play_warning = 0;
-			} else {
-				/* XXX fix this!! */
-				while (play_warning > timelimit)
-					play_warning -= warning_freq;
-				if (play_warning < 1)
-					play_warning = warning_freq = 0;
-			}
-		}
-
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
-		play_to_caller = var ? ast_true(var) : 1;
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
-		play_to_callee = var ? ast_true(var) : 0;
-		
-		if (!play_to_caller && !play_to_callee)
-			play_to_caller = 1;
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
-		warning_sound = S_OR(var, "timeleft");
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
-		end_sound = S_OR(var, NULL);	/* XXX not much of a point in doing this! */
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
-		start_sound = S_OR(var, NULL);	/* XXX not much of a point in doing this! */
-
-		/* undo effect of S(x) in case they are both used */
-		calldurationlimit = 0;
-		/* more efficient to do it like S(x) does since no advanced opts */
-		if (!play_warning && !start_sound && !end_sound && timelimit) {
-			calldurationlimit = timelimit / 1000;
-			if (option_verbose > 2)
-				ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
-			timelimit = play_to_caller = play_to_callee = play_warning = 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", timelimit);
-			ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", 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", warning_freq);
-			ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", start_sound);
-			ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", warning_sound);
-			ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", end_sound);
-		}
 	}
 
 	if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
@@ -954,12 +1144,12 @@
 				if (option_verbose > 2)
 					ast_verbose(VERBOSE_PREFIX_3  "Privacy DB is '%s', clid is '%s'\n",
 						     opt_args[OPT_ARG_PRIVACY], l);
-				privdb_val = ast_privacy_check(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);
-				privdb_val = AST_PRIVACY_UNKNOWN;
+				pa.privdb_val = AST_PRIVACY_UNKNOWN;
 			}
 		} else {
 			char *tnam, *tn2;
@@ -975,59 +1165,59 @@
 
 			snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
 			l = callerid;
-			privdb_val = AST_PRIVACY_UNKNOWN;
+			pa.privdb_val = AST_PRIVACY_UNKNOWN;
 		}
 		
-		ast_copy_string(privcid,l,sizeof(privcid));
-
-		if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */  
+		ast_copy_string(pa.privcid,l,sizeof(pa.privcid));
+
+		if( strncmp(pa.privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */  
 			if (option_verbose > 2)
-				ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", privcid);
-			privdb_val = AST_PRIVACY_ALLOW;
-		}
-		else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
+				ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", pa.privcid);
+			pa.privdb_val = AST_PRIVACY_ALLOW;
+		}
+		else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(pa.privcid,"NOCALLERID",10) == 0 ) {
 			if (option_verbose > 2)
-				ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
+				ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa.privdb_val);
 		}
 		
-		if(privdb_val == AST_PRIVACY_DENY ) {
-			ast_copy_string(status, "NOANSWER", sizeof(status));
+		if(pa.privdb_val == AST_PRIVACY_DENY ) {
+			ast_copy_string(pa.status, "NOANSWER", sizeof(pa.status));
 			if (option_verbose > 2)
 				ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
 			res=0;
 			goto out;
 		}
-		else if(privdb_val == AST_PRIVACY_KILL ) {
-			ast_copy_string(status, "DONTCALL", sizeof(status));
+		else if(pa.privdb_val == AST_PRIVACY_KILL ) {
+			ast_copy_string(pa.status, "DONTCALL", sizeof(pa.status));
 			if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
 				ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
 			}
 			res = 0;
 			goto out; /* Is this right? */
 		}
-		else if(privdb_val == AST_PRIVACY_TORTURE ) {
-			ast_copy_string(status, "TORTURE", sizeof(status));
+		else if(pa.privdb_val == AST_PRIVACY_TORTURE ) {
+			ast_copy_string(pa.status, "TORTURE", sizeof(pa.status));
 			if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
 				ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
 			}
 			res = 0;
 			goto out; /* is this right??? */
 		}
-		else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
+		else if(pa.privdb_val == AST_PRIVACY_UNKNOWN ) {
 			/* Get the user's intro, store it in priv-callerintros/$CID, 
 			   unless it is already there-- this should be done before the 
 			   call is actually dialed  */
 
 			/* make sure the priv-callerintros dir actually exists */
-			snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
-			if (mkdir(privintro, 0755) && errno != EEXIST) {
+			snprintf(pa.privintro, sizeof(pa.privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
+			if (mkdir(pa.privintro, 0755) && errno != EEXIST) {
 				ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
 				res = -1;
 				goto out;
 			}
 
-			snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
-			if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
+			snprintf(pa.privintro,sizeof(pa.privintro), "priv-callerintros/%s", pa.privcid);
+			if( ast_fileexists(pa.privintro,NULL,NULL ) > 0 && strncmp(pa.privcid,"NOCALLERID",10) != 0) {
 				/* the DELUX version of this code would allow this caller the
 				   option to hear and retape their previously recorded intro.
 				*/
@@ -1041,16 +1231,16 @@
 				   "At the tone, please say your name:"
 
 				*/
-				res = ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
+				res = ast_play_and_record(chan, "priv-recordintro", pa.privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
 										/* don't think we'll need a lock removed, we took care of
-										   conflicts by naming the privintro file */
+										   conflicts by naming the pa.privintro file */
 				if (res == -1) {
 					/* Delete the file regardless since they hung up during recording */
-                                        ast_filedelete(privintro, NULL);
-                                        if( ast_fileexists(privintro,NULL,NULL ) > 0 )
-                                                ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
+                                        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", privintro);
+                                                ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa.privintro);
 					goto out;
 				}
                                 if( !ast_streamfile(chan, "vm-dialout", chan->language) )
@@ -1091,7 +1281,7 @@
 		if (!tmp->chan) {
 			/* If we can't, just go on to the next call */
 			ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
-			HANDLE_CAUSE(cause, chan);
+			handle_cause(cause, &num);
 			if (!rest)	/* we are on the last destination */
 				chan->hangupcause = cause;
 			continue;
@@ -1136,7 +1326,7 @@
 				cause = AST_CAUSE_CONGESTION;
 			}
 			if (!tmp->chan) {
-				HANDLE_CAUSE(cause, chan);
+				handle_cause(cause, &num);
 				continue;
 			}
 		}
@@ -1227,10 +1417,10 @@
 	}
 
 	if (!outgoing) {
-		strcpy(status, "CHANUNAVAIL");
+		strcpy(pa.status, "CHANUNAVAIL");
 	} else {
 		/* Our status will at least be NOANSWER */
-		strcpy(status, "NOANSWER");
+		strcpy(pa.status, "NOANSWER");
 		if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
 			moh = 1;
 			ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
@@ -1241,7 +1431,7 @@
 	}
 
 	time(&start_time);
-	peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
+	peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
 	
 	if (!peer) {
 		if (result) {
@@ -1255,8 +1445,9 @@
 	} else {
 		const char *number;
 		time_t end_time, answer_time = time(NULL);
-

[... 9621 lines stripped ...]


More information about the asterisk-commits mailing list