[svn-commits] oej: branch oej/astum r47879 - in /team/oej/astum: ./ apps/ build_tools/ cdr/...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Nov 21 04:04:18 MST 2006


Author: oej
Date: Tue Nov 21 05:04:17 2006
New Revision: 47879

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47879
Log:
Update branch

Removed:
    team/oej/astum/aclocal.m4
Modified:
    team/oej/astum/   (props changed)
    team/oej/astum/.cleancount
    team/oej/astum/CHANGES
    team/oej/astum/Makefile
    team/oej/astum/UPGRADE.txt
    team/oej/astum/acinclude.m4
    team/oej/astum/apps/app_amd.c
    team/oej/astum/apps/app_chanspy.c
    team/oej/astum/apps/app_db.c
    team/oej/astum/apps/app_dial.c
    team/oej/astum/apps/app_directed_pickup.c
    team/oej/astum/apps/app_directory.c
    team/oej/astum/apps/app_followme.c
    team/oej/astum/apps/app_meetme.c
    team/oej/astum/apps/app_osplookup.c
    team/oej/astum/apps/app_queue.c
    team/oej/astum/apps/app_read.c
    team/oej/astum/apps/app_sms.c
    team/oej/astum/apps/app_voicemail.c
    team/oej/astum/build_tools/prep_moduledeps
    team/oej/astum/cdr/cdr_pgsql.c
    team/oej/astum/channels/chan_agent.c
    team/oej/astum/channels/chan_alsa.c
    team/oej/astum/channels/chan_features.c
    team/oej/astum/channels/chan_gtalk.c
    team/oej/astum/channels/chan_h323.c
    team/oej/astum/channels/chan_iax2.c
    team/oej/astum/channels/chan_jingle.c
    team/oej/astum/channels/chan_local.c
    team/oej/astum/channels/chan_mgcp.c
    team/oej/astum/channels/chan_misdn.c
    team/oej/astum/channels/chan_nbs.c
    team/oej/astum/channels/chan_oss.c
    team/oej/astum/channels/chan_phone.c
    team/oej/astum/channels/chan_sip.c
    team/oej/astum/channels/chan_skinny.c
    team/oej/astum/channels/chan_vpb.cc
    team/oej/astum/channels/chan_zap.c
    team/oej/astum/channels/misdn/isdn_lib.c
    team/oej/astum/codecs/codec_zap.c
    team/oej/astum/configs/manager.conf.sample
    team/oej/astum/configs/musiconhold.conf.sample
    team/oej/astum/configs/queues.conf.sample
    team/oej/astum/configs/res_odbc.conf.sample
    team/oej/astum/configs/sip.conf.sample
    team/oej/astum/configs/voicemail.conf.sample
    team/oej/astum/configs/zapata.conf.sample
    team/oej/astum/configure
    team/oej/astum/configure.ac
    team/oej/astum/doc/ael.txt
    team/oej/astum/doc/billing.txt
    team/oej/astum/funcs/func_uri.c
    team/oej/astum/include/asterisk/app.h
    team/oej/astum/include/asterisk/astosp.h
    team/oej/astum/include/asterisk/channel.h
    team/oej/astum/include/asterisk/cli.h
    team/oej/astum/include/asterisk/file.h
    team/oej/astum/include/asterisk/frame.h
    team/oej/astum/include/asterisk/manager.h
    team/oej/astum/include/asterisk/stringfields.h
    team/oej/astum/include/asterisk/term.h
    team/oej/astum/main/app.c
    team/oej/astum/main/asterisk.c
    team/oej/astum/main/cdr.c
    team/oej/astum/main/channel.c
    team/oej/astum/main/cli.c
    team/oej/astum/main/config.c
    team/oej/astum/main/file.c
    team/oej/astum/main/frame.c
    team/oej/astum/main/logger.c
    team/oej/astum/main/manager.c
    team/oej/astum/main/pbx.c
    team/oej/astum/main/rtp.c
    team/oej/astum/main/term.c
    team/oej/astum/main/utils.c
    team/oej/astum/pbx/ael/ael-test/ref.ael-test3
    team/oej/astum/pbx/pbx_ael.c
    team/oej/astum/pbx/pbx_dundi.c
    team/oej/astum/res/res_agi.c
    team/oej/astum/res/res_features.c
    team/oej/astum/res/res_musiconhold.c
    team/oej/astum/res/res_odbc.c
    team/oej/astum/res/res_realtime.c
    team/oej/astum/utils/astman.c
    team/oej/astum/utils/check_expr.c
    team/oej/astum/utils/streamplayer.c

Propchange: team/oej/astum/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/oej/astum/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/oej/astum/
------------------------------------------------------------------------------
--- svn:externals (original)
+++ svn:externals Tue Nov 21 05:04:17 2006
@@ -1,1 +1,1 @@
-menuselect	http://svn.digium.com/svn/menuselect/branches/1.0
+menuselect	https://origsvn.digium.com/svn/menuselect/branches/1.0

Propchange: team/oej/astum/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Nov 21 05:04:17 2006
@@ -22,3 +22,4 @@
 menuselect-tree
 autom4te.cache
 makeopts.embed_rules
+aclocal.m4

Propchange: team/oej/astum/
------------------------------------------------------------------------------
--- svnmerge-blocked (original)
+++ svnmerge-blocked Tue Nov 21 05:04:17 2006
@@ -1,1 +1,1 @@
-/branches/1.2:46361
+/branches/1.2:47648

Propchange: team/oej/astum/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Nov 21 05:04:17 2006
@@ -1,1 +1,1 @@
-/trunk:1-47166
+/trunk:1-47876

Modified: team/oej/astum/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/astum/.cleancount?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/.cleancount (original)
+++ team/oej/astum/.cleancount Tue Nov 21 05:04:17 2006
@@ -1,1 +1,1 @@
-25
+26

Modified: team/oej/astum/CHANGES
URL: http://svn.digium.com/view/asterisk/team/oej/astum/CHANGES?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/CHANGES (original)
+++ team/oej/astum/CHANGES Tue Nov 21 05:04:17 2006
@@ -58,3 +58,6 @@
   * Added QUEUE_VARIABLES function to set queue variables added setqueuevar and 
     setqueueentryvar options for each queue, see queues.conf.sample for details.
   * Brazilian Portuguese (pt-BR) in VM, and say.c was added via patch from cfassoni.
+  * CID matching information is now shown when doing 'dialplan show'.
+  * app_queue now has a 'loose' option which is almost exactly like 'strict' except it
+     does not count paused queue members as unavailable.

Modified: team/oej/astum/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/astum/Makefile?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/Makefile (original)
+++ team/oej/astum/Makefile Tue Nov 21 05:04:17 2006
@@ -683,6 +683,8 @@
 	rm -rf $(DESTDIR)$(ASTETCDIR)
 	rm -rf $(DESTDIR)$(ASTLOGDIR)
 
+menuconfig: menuselect
+
 menuselect: menuselect/menuselect menuselect-tree
 	- at menuselect/menuselect $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) menuselect.makeopts && (echo "menuselect changes saved!"; rm -f channels/h323/Makefile.ast main/asterisk) || echo "menuselect changes NOT saved!"
 

Modified: team/oej/astum/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/astum/UPGRADE.txt?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/UPGRADE.txt (original)
+++ team/oej/astum/UPGRADE.txt Tue Nov 21 05:04:17 2006
@@ -3,6 +3,17 @@
 
 Manager:
 
-* The CallerID fields across manager events have now been made more
+* The CallerID fields across Manager events have now been made more
   consistent. CallerID Number will be sent as CallerIDNum and CallerID
   Name will be sent as CallerIDName wherever used.
+
+AEL:
+
+* Macros are now implemented underneath with the Gosub() application.
+  Heaven Help You if you wrote code depending on any aspect of this!
+  Previous to 1.6, macros were implemented with the Macro() app, which
+  provided a nice feature of auto-returning. The compiler will do its
+  best to insert a Return() app call at the end of your macro if you did
+  not include it, but really, you should make sure that all execution
+  paths within your macros end in "return;".
+

Modified: team/oej/astum/acinclude.m4
URL: http://svn.digium.com/view/asterisk/team/oej/astum/acinclude.m4?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/acinclude.m4 (original)
+++ team/oej/astum/acinclude.m4 Tue Nov 21 05:04:17 2006
@@ -567,3 +567,140 @@
       [ac_cv_func_fork_works=no],
       [ac_cv_func_fork_works=cross])])]
 )# _AST_FUNC_FORK
+
+# AST_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AST_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+    [AC_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])
+AC_REQUIRE([AST_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AST_PROG_LD_GNU
+])# AST_PROG_LD
+
+
+# AST_PROG_LD_GNU
+# --------------
+AC_DEFUN([AST_PROG_LD_GNU],
+[AC_REQUIRE([AST_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AST_PROG_LD_GNU
+
+# AST_PROG_EGREP
+# -------------
+m4_ifndef([AST_PROG_EGREP], [AC_DEFUN([AST_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])]) # AST_PROG_EGREP
+
+# AST_PROG_SED
+# -----------
+# Check for a fully functional sed program that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+AC_DEFUN([AST_PROG_SED],
+[AC_CACHE_CHECK([for a sed that does not truncate output], ac_cv_path_SED,
+    [dnl ac_script should not contain more than 99 commands (for HP-UX sed),
+     dnl but more than about 7000 bytes, to catch a limit in Solaris 8 /usr/ucb/sed.
+     ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" | sed 99q >conftest.sed
+     $as_unset ac_script || ac_script=
+     _AC_PATH_PROG_FEATURE_CHECK(SED, [sed gsed],
+	[_AC_FEATURE_CHECK_LENGTH([ac_path_SED], [ac_cv_path_SED],
+		["$ac_path_SED" -f conftest.sed])])])
+ SED="$ac_cv_path_SED"
+ AC_SUBST([SED])dnl
+ rm -f conftest.sed
+])# AST_PROG_SED
+

Modified: team/oej/astum/apps/app_amd.c
URL: http://svn.digium.com/view/asterisk/team/oej/astum/apps/app_amd.c?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/apps/app_amd.c (original)
+++ team/oej/astum/apps/app_amd.c Tue Nov 21 05:04:17 2006
@@ -151,8 +151,8 @@
 			maximumNumberOfWords = atoi(args.argMaximumNumberOfWords);
 		if (!ast_strlen_zero(args.argSilenceThreshold))
 			silenceThreshold = atoi(args.argSilenceThreshold);
-	} else
-		ast_log(LOG_NOTICE, "AMD using the default parameters.\n");
+	} else if (option_debug)
+		ast_log(LOG_DEBUG, "AMD using the default parameters.\n");
 
 	/* Now we're ready to roll! */
 	if (option_verbose > 2)

Modified: team/oej/astum/apps/app_chanspy.c
URL: http://svn.digium.com/view/asterisk/team/oej/astum/apps/app_chanspy.c?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/apps/app_chanspy.c (original)
+++ team/oej/astum/apps/app_chanspy.c Tue Nov 21 05:04:17 2006
@@ -658,7 +658,8 @@
 
 	if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
 		context = argv[0];
-		exten = strsep(&context, "@");
+		if (!ast_strlen_zero(argv[0]))
+			exten = strsep(&context, "@");
 		if (ast_strlen_zero(context))
 			context = ast_strdupa(chan->context);
 		if (argc > 1)

Modified: team/oej/astum/apps/app_db.c
URL: http://svn.digium.com/view/asterisk/team/oej/astum/apps/app_db.c?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/apps/app_db.c (original)
+++ team/oej/astum/apps/app_db.c Tue Nov 21 05:04:17 2006
@@ -50,7 +50,7 @@
 
 /*! \todo XXX Remove this application after 1.4 is relased */
 static char *d_descrip =
-"  DBdel(family/key): This applicaiton will delete a key from the Asterisk\n"
+"  DBdel(family/key): This application will delete a key from the Asterisk\n"
 "database.\n"
 "  This application has been DEPRECATED in favor of the DB_DELETE function.\n";
 

Modified: team/oej/astum/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/astum/apps/app_dial.c?view=diff&rev=47879&r1=47878&r2=47879
==============================================================================
--- team/oej/astum/apps/app_dial.c (original)
+++ team/oej/astum/apps/app_dial.c Tue Nov 21 05:04:17 2006
@@ -67,7 +67,7 @@
 
 static char *descrip =
 "  Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
-"This applicaiton will place calls to one or more specified channels. As soon\n"
+"This application will place calls to one or more specified channels. As soon\n"
 "as one of the requested channels answers, the originating channel will be\n"
 "answered, if it has not already been answered. These two channels will then\n"
 "be active in a bridged call. All other channels that were requested will then\n"
@@ -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;
@@ -472,98 +590,16 @@
 						       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
 						       OPT_CALLEE_PARK | OPT_CALLER_PARK |
 						       DIAL_NOFORWARDHTML);
-					ast_copy_string(c->context, "", sizeof(c->context));
+					ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
 					ast_copy_string(c->exten, "", sizeof(c->exten));
 				}
 				continue;
 			}
 			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) {
@@ -589,7 +625,7 @@
 							       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
 							       OPT_CALLEE_PARK | OPT_CALLER_PARK |
 							       DIAL_NOFORWARDHTML);
-						ast_copy_string(c->context, "", sizeof(c->context));
+						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);
@@ -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,260 @@
 	return 0;
 }
 
+static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
+	char *parse, unsigned int *calldurationlimit)
+{
+	char *stringp = ast_strdupa(parse);
+	char *limit_str, *warning_str, *warnfreq_str;
+	const char *var;
+	int play_to_caller=0,play_to_callee=0;
+	int delta;
+
+	limit_str = strsep(&stringp, ":");
+	warning_str = strsep(&stringp, ":");
+	warnfreq_str = strsep(&stringp, ":");
+
+	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;

[... 18341 lines stripped ...]


More information about the svn-commits mailing list