[asterisk-commits] murf: branch group/CDRbatch r78298 - in /team/group/CDRbatch: ./ apps/ build_...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Aug 6 17:33:43 CDT 2007


Author: murf
Date: Mon Aug  6 17:33:42 2007
New Revision: 78298

URL: http://svn.digium.com/view/asterisk?view=rev&rev=78298
Log:
Merged revisions 77850,77893,77906,77961,78003,78038,78070,78110,78199,78230,78250,78267 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/team/group/CDRfix5

................
r77850 | murf | 2007-07-31 20:45:22 -0600 (Tue, 31 Jul 2007) | 99 lines

Merged revisions 77819-77821,77825,77828-77829,77833-77834,77838,77847 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r77819 | kpfleming | 2007-07-31 08:54:46 -0600 (Tue, 31 Jul 2007) | 3 lines

umm... let's build with --enable-dev-mode, mmkay?


................
r77820 | kpfleming | 2007-07-31 08:55:37 -0600 (Tue, 31 Jul 2007) | 2 lines

use a different method for overriding the send_digit_begin pointer, as the old one fails to compile on my 64-bit system with gcc-4.1 and --enable-dev-mode turned on

................
r77821 | kpfleming | 2007-07-31 09:01:27 -0600 (Tue, 31 Jul 2007) | 2 lines

there is no use in having functions that have no code in them, and hide the locking info when DEBUG_THREADS is enabled... i could have fixed this to be dependent on DEBUG_THREADS, but it would be just as easy for someone to add their test/debugging code to the macros as it would have been to the functions

................
r77825 | mmichelson | 2007-07-31 09:22:32 -0600 (Tue, 31 Jul 2007) | 14 lines

Merged revisions 77824 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r77824 | mmichelson | 2007-07-31 10:21:22 -0500 (Tue, 31 Jul 2007) | 6 lines

This patch makes Asterisk send 100 Trying provisional responses upon receipt of re-invites. This makes it so that if there are two or more Asterisk
servers between endpoints, the Asterisk servers will not keep retransmitting the re-invites.

(closes issue #10274, reported by cstadlmann, patched by me with approval from file)


........

................
r77828 | kpfleming | 2007-07-31 09:54:29 -0600 (Tue, 31 Jul 2007) | 10 lines

Merged revisions 77827 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r77827 | kpfleming | 2007-07-31 10:53:42 -0500 (Tue, 31 Jul 2007) | 2 lines

DETECT_DEADLOCKS can't be enabled without DEBUG_THREADS or it does nothing

........

................
r77829 | murf | 2007-07-31 09:59:01 -0600 (Tue, 31 Jul 2007) | 1 line

thanks to Russel, for pointing out that the dialoglist_lock/unlock routines also need to be macros if DETECT_DEADLOCKS is set
................
r77833 | file | 2007-07-31 10:21:34 -0600 (Tue, 31 Jul 2007) | 10 lines

Merged revisions 77831 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r77831 | file | 2007-07-31 13:17:09 -0300 (Tue, 31 Jul 2007) | 2 lines

Add a flag to the speech API that allows an engine to set whether it received results or not.

........

................
r77834 | tilghman | 2007-07-31 10:44:25 -0600 (Tue, 31 Jul 2007) | 3 lines

Add func_lock, which creates dialplan mutexes, and note that the Macro apps are now deprecated.
(Closes issue #10264)

................
r77838 | tilghman | 2007-07-31 12:50:06 -0600 (Tue, 31 Jul 2007) | 2 lines

Add some documentation detailing an aspect of dialplan functions, as requested by Russell

................
r77847 | murf | 2007-07-31 15:33:37 -0600 (Tue, 31 Jul 2007) | 17 lines

Merged revisions 77844 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r77844 | murf | 2007-07-31 14:59:10 -0600 (Tue, 31 Jul 2007) | 9 lines

Merged revisions 77842 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r77842 | murf | 2007-07-31 13:19:35 -0600 (Tue, 31 Jul 2007) | 1 line

This probably isn't super-general, but it's a first stab at using kill -11 to generate a core file instead of gcore.
........

................

................

................
r77893 | murf | 2007-08-01 18:16:13 -0600 (Wed, 01 Aug 2007) | 1 line

As per suggestion of Tilghman, we split the read and write of CDR_CONTROL; begin automation of CDR output for non-answer cases
................
r77906 | automerge | 2007-08-02 09:39:28 -0600 (Thu, 02 Aug 2007) | 1 line

automerge commit
................
r77961 | automerge | 2007-08-02 13:51:54 -0600 (Thu, 02 Aug 2007) | 1 line

automerge commit
................
r78003 | automerge | 2007-08-02 17:36:08 -0600 (Thu, 02 Aug 2007) | 1 line

automerge commit
................
r78038 | automerge | 2007-08-03 01:35:47 -0600 (Fri, 03 Aug 2007) | 1 line

automerge commit
................
r78070 | automerge | 2007-08-03 11:35:27 -0600 (Fri, 03 Aug 2007) | 1 line

automerge commit
................
r78110 | automerge | 2007-08-03 14:35:41 -0600 (Fri, 03 Aug 2007) | 1 line

automerge commit
................
r78199 | automerge | 2007-08-06 12:28:47 -0600 (Mon, 06 Aug 2007) | 1 line

automerge commit
................
r78230 | automerge | 2007-08-06 14:26:05 -0600 (Mon, 06 Aug 2007) | 1 line

automerge commit
................
r78250 | automerge | 2007-08-06 15:27:29 -0600 (Mon, 06 Aug 2007) | 1 line

automerge commit
................
r78267 | murf | 2007-08-06 15:36:13 -0600 (Mon, 06 Aug 2007) | 1 line

Next installment on getting Asterisk to post unanswered, busy, failed calls
................

Added:
    team/group/CDRbatch/funcs/func_lock.c
      - copied unchanged from r78267, team/group/CDRfix5/funcs/func_lock.c
Modified:
    team/group/CDRbatch/   (props changed)
    team/group/CDRbatch/CHANGES
    team/group/CDRbatch/UPGRADE.txt
    team/group/CDRbatch/apps/app_dial.c
    team/group/CDRbatch/apps/app_exec.c
    team/group/CDRbatch/apps/app_externalivr.c
    team/group/CDRbatch/apps/app_forkcdr.c
    team/group/CDRbatch/apps/app_macro.c
    team/group/CDRbatch/apps/app_meetme.c
    team/group/CDRbatch/apps/app_osplookup.c
    team/group/CDRbatch/apps/app_queue.c
    team/group/CDRbatch/apps/app_senddtmf.c
    team/group/CDRbatch/apps/app_voicemail.c
    team/group/CDRbatch/apps/app_zapras.c
    team/group/CDRbatch/build_tools/cflags.xml
    team/group/CDRbatch/channels/chan_iax2.c
    team/group/CDRbatch/channels/chan_local.c
    team/group/CDRbatch/channels/chan_mgcp.c
    team/group/CDRbatch/channels/chan_sip.c
    team/group/CDRbatch/channels/chan_skinny.c
    team/group/CDRbatch/channels/chan_vpb.cc
    team/group/CDRbatch/configs/skinny.conf.sample
    team/group/CDRbatch/configure
    team/group/CDRbatch/configure.ac
    team/group/CDRbatch/contrib/scripts/ast_grab_core
    team/group/CDRbatch/doc/tex/queuelog.tex
    team/group/CDRbatch/funcs/func_cdr.c
    team/group/CDRbatch/include/asterisk/autoconfig.h.in
    team/group/CDRbatch/include/asterisk/cdr.h
    team/group/CDRbatch/include/asterisk/config.h
    team/group/CDRbatch/include/asterisk/fskmodem.h
    team/group/CDRbatch/include/asterisk/linkedlists.h
    team/group/CDRbatch/include/asterisk/lock.h
    team/group/CDRbatch/include/asterisk/speech.h
    team/group/CDRbatch/include/asterisk/threadstorage.h
    team/group/CDRbatch/main/astmm.c
    team/group/CDRbatch/main/autoservice.c
    team/group/CDRbatch/main/callerid.c
    team/group/CDRbatch/main/channel.c
    team/group/CDRbatch/main/cli.c
    team/group/CDRbatch/main/config.c
    team/group/CDRbatch/main/fskmodem.c
    team/group/CDRbatch/main/pbx.c
    team/group/CDRbatch/main/rtp.c
    team/group/CDRbatch/main/tdd.c
    team/group/CDRbatch/main/utils.c
    team/group/CDRbatch/pbx/pbx_dundi.c
    team/group/CDRbatch/res/res_agi.c
    team/group/CDRbatch/res/res_features.c
    team/group/CDRbatch/res/res_speech.c
    team/group/CDRbatch/utils/smsq.c

Propchange: team/group/CDRbatch/
------------------------------------------------------------------------------
    automerge = yes

Propchange: team/group/CDRbatch/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/group/CDRbatch/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/CDRbatch/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Aug  6 17:33:42 2007
@@ -1,1 +1,1 @@
-/team/group/CDRfix5:1-77836
+/team/group/CDRfix5:1-78278

Modified: team/group/CDRbatch/CHANGES
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/CHANGES?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/CHANGES (original)
+++ team/group/CDRbatch/CHANGES Mon Aug  6 17:33:42 2007
@@ -33,6 +33,10 @@
   * MailboxExists converted to dialplan function
   * A new option to Dial() for telling IP phones not to count the call
     as "missed" when dial times out and cancels.
+  * Added LOCK(), TRYLOCK(), and UNLOCK(), which provide a single level dialplan
+    mutex.  No deadlocks are possible, as LOCK() only allows a single lock to be
+    held for any given channel.  Also, locks are automatically freed when a
+    channel is hung up.
 
 CLI Changes
 -----------
@@ -256,3 +260,32 @@
   * The device state functionality in the Local channel driver has been updated
      to indicate INUSE or NOT_INUSE when a Local channel is being used as opposed
      to just UNKNOWN if the extension exists.
+
+CDR changes
+-----------
+
+  * If you had dialplan that in any way manipulated CDR's, the chances are
+    now good that you will have to rip it out and re-write it!
+  * ForkCDR still exists, but does nothing, and generates a warning. This
+    is not standard obsolescence; it is part of a bug fix that required
+    re-engineering of the system.
+  * By default, Asterisk will only generate a CDR if a bridge was executed.
+    So, no conversation between two endpoints, no CDR. Apps that execute
+    bridges: Dial and Meetme and queue, etc.
+  * the Function CDR_CONTROL() is available to build, set and generate
+    CDR's for non-bridging situations like app and agi calls.
+  * the CDR() function can still be used to set CDR fields before a bridge
+    is formed. It can also be used to set fields in CDRs created by CDR_CONTROL().
+  * Those apps that accepted an arg to update CDR, either still have them (for now),
+    or have had that option removed. The philosophy is a bit different now. A CDR is
+    attached to the channel at the creation of the channel. The channel CDR's start
+    time is set to the time the channel was created. You set up the channel CDR before 
+    executing an app that executes a bridge. The originating
+    channel's CDR is copied into a temporary bridge CDR. The bridge CDR's answer time
+    is set when the bridge begins, and the bridge CDR's end time is set when it closes. 
+    The bridge CDR is then posted to the backend. The channel cdr start time is updated 
+    to the end time of the bridge. Hangup routines are called, and then the channel 
+    is destroyed.
+
+
+    

Modified: team/group/CDRbatch/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/UPGRADE.txt?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/UPGRADE.txt (original)
+++ team/group/CDRbatch/UPGRADE.txt Mon Aug  6 17:33:42 2007
@@ -71,6 +71,11 @@
 * DISA()'s fifth argument is now an options argument.  If you have previously
   used 'NOANSWER' in this argument, you'll need to convert that to the new
   option 'n'.
+* Macro() is now deprecated.  If you need subroutines, you should use the
+  Gosub()/Return() applications.  To replace MacroExclusive(), we have
+  introduced dialplan functions LOCK(), TRYLOCK(), and UNLOCK().  You may use
+  these functions in any location where you desire to ensure that only one
+  channel is executing that path at any one time.
 
 CDR:
 

Modified: team/group/CDRbatch/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_dial.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_dial.c (original)
+++ team/group/CDRbatch/apps/app_dial.c Mon Aug  6 17:33:42 2007
@@ -1789,7 +1789,7 @@
 			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);
 		}
@@ -1808,7 +1808,7 @@
 	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;

Modified: team/group/CDRbatch/apps/app_exec.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_exec.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_exec.c (original)
+++ team/group/CDRbatch/apps/app_exec.c Mon Aug  6 17:33:42 2007
@@ -160,38 +160,38 @@
 		AST_APP_ARG(remainder);
 	);
 	AST_DECLARE_APP_ARGS(apps,
-		AST_APP_ARG(true);
-		AST_APP_ARG(false);
+		AST_APP_ARG(t);
+		AST_APP_ARG(f);
 	);
 	char *parse = ast_strdupa(data);
 
 	AST_NONSTANDARD_APP_ARGS(expr, parse, '?');
 	AST_NONSTANDARD_APP_ARGS(apps, expr.remainder, ':');
 
-	if (apps.true && (truedata = strchr(apps.true, '('))) {
+	if (apps.t && (truedata = strchr(apps.t, '('))) {
 		*truedata++ = '\0';
 		if ((end = strrchr(truedata, ')')))
 			*end = '\0';
 	}
 
-	if (apps.false && (falsedata = strchr(apps.false, '('))) {
+	if (apps.f && (falsedata = strchr(apps.f, '('))) {
 		*falsedata++ = '\0';
 		if ((end = strrchr(falsedata, ')')))
 			*end = '\0';
 	}
 
 	if (pbx_checkcondition(expr.expr)) { 
-		if (!ast_strlen_zero(apps.true) && (app = pbx_findapp(apps.true))) {
+		if (!ast_strlen_zero(apps.t) && (app = pbx_findapp(apps.t))) {
 			res = pbx_exec(chan, app, S_OR(truedata, ""));
 		} else {
-			ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.true);
+			ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.t);
 			res = -1;
 		}
 	} else {
-		if (!ast_strlen_zero(apps.false) && (app = pbx_findapp(apps.false))) {
+		if (!ast_strlen_zero(apps.f) && (app = pbx_findapp(apps.f))) {
 			res = pbx_exec(chan, app, S_OR(falsedata, ""));
 		} else {
-			ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.false);
+			ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.f);
 			res = -1;
 		}
 	}

Modified: team/group/CDRbatch/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_externalivr.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_externalivr.c (original)
+++ team/group/CDRbatch/apps/app_externalivr.c Mon Aug  6 17:33:42 2007
@@ -250,7 +250,6 @@
 	int res = -1;
 	int gen_active = 0;
 	int pid;
-	char *argv[32];
 	char *buf, *command;
 	FILE *child_commands = NULL;
 	FILE *child_errors = NULL;
@@ -325,8 +324,8 @@
 		dup2(child_stderr[1], STDERR_FILENO);
 		for (i = STDERR_FILENO + 1; i < 1024; i++)
 			close(i);
-		execv(argv[0], argv);
-		fprintf(stderr, "Failed to execute '%s': %s\n", argv[0], strerror(errno));
+		execv(args.cmd[0], args.cmd);
+		fprintf(stderr, "Failed to execute '%s': %s\n", args.cmd[0], strerror(errno));
 		_exit(1);
 	} else {
 		/* parent process */

Modified: team/group/CDRbatch/apps/app_forkcdr.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_forkcdr.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_forkcdr.c (original)
+++ team/group/CDRbatch/apps/app_forkcdr.c Mon Aug  6 17:33:42 2007
@@ -48,7 +48,8 @@
 static char *descrip = 
 "  ForkCDR([options]):  Causes the Call Data Record to fork an additional\n"
 	"cdr record starting from the time of the fork call\n"
-"If the option 'v' is passed all cdr variables will be passed along also.\n";
+"If the option 'v' is passed all cdr variables will be passed along also.\n"
+"NOTE: this app is no longer useful! Refer to the CDR_CONTROL function instead!\n";
 
 
 static int forkcdr_exec(struct ast_channel *chan, void *data)
@@ -63,7 +64,7 @@
 	if (!ast_strlen_zero(data))
 		ast_set2_flag(chan->cdr, strchr(data, 'v'), AST_CDR_FLAG_KEEP_VARS);
 	
-	ast_log(LOG_ERROR,"ForkCDR is obsolesced. It will probably not yield correct results any more. Use CDRstart(), CDRanswer(), and CDRclose() functions instead!\n");
+	ast_log(LOG_ERROR,"ForkCDR is obsolesced. It will probably not yield correct results any more. Use CDR_CONTROL(start/answer/close) function instead!\n");
 	
 
 	return res;

Modified: team/group/CDRbatch/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_macro.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_macro.c (original)
+++ team/group/CDRbatch/apps/app_macro.c Mon Aug  6 17:33:42 2007
@@ -385,7 +385,7 @@
 		}
 
 		/* don't stop executing extensions when we're in "h" */
-		if (chan->_softhangup && !inhangup) {
+		if (ast_check_hangup(chan) && !inhangup) {
 			ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority);
 			goto out;
 		}
@@ -434,7 +434,7 @@
   		/* If we're leaving the macro normally, restore original information */
 		chan->priority = oldpriority;
 		ast_copy_string(chan->context, oldcontext, sizeof(chan->context));
-		if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
+		if (!(ast_check_hangup(chan) & AST_SOFTHANGUP_ASYNCGOTO)) {
 			/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
 			const char *offsets;
 			ast_copy_string(chan->exten, oldexten, sizeof(chan->exten));

Modified: team/group/CDRbatch/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_meetme.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_meetme.c (original)
+++ team/group/CDRbatch/apps/app_meetme.c Mon Aug  6 17:33:42 2007
@@ -719,7 +719,7 @@
 	int len;
 	int res = -1;
 
-	if (!chan->_softhangup)
+	if (!ast_check_hangup(chan))
 		res = ast_autoservice_start(chan);
 
 	AST_LIST_LOCK(&confs);

Modified: team/group/CDRbatch/apps/app_osplookup.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_osplookup.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_osplookup.c (original)
+++ team/group/CDRbatch/apps/app_osplookup.c Mon Aug  6 17:33:42 2007
@@ -1734,7 +1734,7 @@
 	ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
 	ast_debug(1, "OSPFinish: end '%ld'\n", end);
 
-	release = chan->_softhangup ? 0 : 1;
+	release = ast_check_hangup(chan) ? 0 : 1;
 
 	if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
 		ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");

Modified: team/group/CDRbatch/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_queue.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_queue.c (original)
+++ team/group/CDRbatch/apps/app_queue.c Mon Aug  6 17:33:42 2007
@@ -1256,6 +1256,56 @@
 		AST_LIST_UNLOCK(&queues);
 	}
 	return q;
+}
+
+static void update_realtime_members(struct call_queue *q)
+{
+	struct ast_config *member_config = NULL;
+	struct member *m, *prev_m, *next_m;
+	char *interface = NULL;
+
+	member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
+	if (!member_config) {
+		/*This queue doesn't have realtime members*/
+		ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
+		return;
+	}
+
+	ast_mutex_lock(&q->lock);
+	
+	/* Temporarily set non-dynamic members dead so we can detect deleted ones.*/ 
+	for (m = q->members; m; m = m->next) {
+		if (!m->dynamic)
+			m->dead = 1;
+	}
+
+	while ((interface = ast_category_browse(member_config, interface))) {
+		rt_handle_member_record(q, interface,
+			S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
+			ast_variable_retrieve(member_config, interface, "penalty"),
+			ast_variable_retrieve(member_config, interface, "paused"));
+	}
+
+	/* Delete all realtime members that have been deleted in DB. */
+	m = q->members;
+	prev_m = NULL;
+	while (m) {
+		next_m = m->next;
+		if (m->dead) {
+			if (prev_m) {
+				prev_m->next = next_m;
+			} else {
+				q->members = next_m;
+			}
+			remove_from_interfaces(m->interface);
+			q->membercount--;
+			free(m);
+		} else {
+			prev_m = m;
+		}
+		m = next_m;
+	}
+	ast_mutex_unlock(&q->lock);
 }
 
 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
@@ -2410,7 +2460,7 @@
 {
 	struct member *cur;
 	struct callattempt *outgoing = NULL; /* the list of calls we are building */
-	int to;
+	int to, orig;
 	char oldexten[AST_MAX_EXTENSION]="";
 	char oldcontext[AST_MAX_CONTEXT]="";
 	char queuename[256]="";
@@ -2444,6 +2494,7 @@
 	char vars[2048];
 	int forwardsallowed = 1;
 	int callcompletedinsl;
+	int noption = 0;
 
 	memset(&bridge_config, 0, sizeof(bridge_config));
 	time(&now);
@@ -2476,11 +2527,15 @@
 				(*go_on)++;
 			else
 				*go_on = qe->parent->membercount;
+			noption = 1;
 			break;
 		case 'i':
 			forwardsallowed = 0;
 			break;
 		}
+
+	if(!noption)
+		*go_on = -1;
 
 	/* Hold the lock while we setup the outgoing calls */
 	if (use_weight)
@@ -2528,6 +2583,7 @@
 		to = (qe->expire - now) * 1000;
 	else
 		to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
+	orig = to;
 	ring_one(qe, outgoing, &numbusies);
 	ast_mutex_unlock(&qe->parent->lock);
 	if (use_weight)
@@ -2596,7 +2652,7 @@
 				}
 			}
 			res2 |= ast_autoservice_stop(qe->chan);
-			if (peer->_softhangup) {
+			if (ast_check_hangup(peer)) {
 				/* Agent must have hung up */
 				ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
@@ -2863,7 +2919,8 @@
 			} else
 				ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
 		}
-		ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s", (long) time(NULL) - qe->start, peer->uniqueid);
+		ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld", (long) time(NULL) - qe->start, peer->uniqueid,
+													(long)(orig - to > 0 ? (orig - to) / 1000 : 0));
 		if (qe->parent->eventwhencalled)
 			manager_event(EVENT_FLAG_AGENT, "AgentConnect",
 					"Queue: %s\r\n"
@@ -2873,9 +2930,10 @@
 					"MemberName: %s\r\n"
 					"Holdtime: %ld\r\n"
 					"BridgedChannel: %s\r\n"
+					"Ringtime: %ld\r\n"
 					"%s",
 					queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
-					(long) time(NULL) - qe->start, peer->uniqueid,
+					(long) time(NULL) - qe->start, peer->uniqueid, (long)(orig - to > 0 ? (orig - to) / 1000 : 0),
 					qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
 		ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
 		ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
@@ -2888,7 +2946,7 @@
 				qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
 				(long) (time(NULL) - callstart));
 			send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
-		} else if (qe->chan->_softhangup) {
+		} else if (ast_check_hangup(qe->chan)) {
 			ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
 				(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
 			send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
@@ -3623,6 +3681,9 @@
 				ast_queue_log(qe.parent->name, qe.chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld", qe.pos, qe.opos, (long) time(NULL) - qe.start);
 				break;
 			}
+
+			/* If using dynamic realtime members, we should regenerate the member list for this queue */
+			update_realtime_members(qe.parent);
 
 			/* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
 			res = wait_a_bit(&qe);

Modified: team/group/CDRbatch/apps/app_senddtmf.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_senddtmf.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_senddtmf.c (original)
+++ team/group/CDRbatch/apps/app_senddtmf.c Mon Aug  6 17:33:42 2007
@@ -66,7 +66,7 @@
 		AST_APP_ARG(timeout);
 	);
 
-	if (ast_strlen_zero(data)) {
+	if (ast_strlen_zero(vdata)) {
 		ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
 		return 0;
 	}

Modified: team/group/CDRbatch/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_voicemail.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_voicemail.c (original)
+++ team/group/CDRbatch/apps/app_voicemail.c Mon Aug  6 17:33:42 2007
@@ -1790,6 +1790,7 @@
 
 #endif
 
+#ifndef ODBC_STORAGE
 static int vm_delete(char *file)
 {
 	char *txt;
@@ -1807,6 +1808,7 @@
 	unlink(txt);
 	return ast_filedelete(file, NULL);
 }
+#endif
 
 static int inbuf(struct baseio *bio, FILE *fi)
 {
@@ -2082,7 +2084,7 @@
 		fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
 	else
 		fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
-	fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, getpid(), host);
+	fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
 	if(imap) {
 		/* additional information needed for IMAP searching */
 		fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
@@ -2108,7 +2110,7 @@
 	fprintf(p, "MIME-Version: 1.0" ENDL);
 	if (attach_user_voicemail) {
 		/* Something unique. */
-		snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, getpid(), (unsigned int)ast_random());
+		snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
 
 		fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
 		fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
@@ -4152,8 +4154,14 @@
 		if (!attach_user_voicemail)
 			attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
 
+		if (attach_user_voicemail)
+			RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
+
 		/*XXX possible imap issue, should category be NULL XXX*/
 		sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
+
+		if (attach_user_voicemail)
+			DISPOSE(todir, msgnum);
 	}
 
 	if (!ast_strlen_zero(vmu->pager))

Modified: team/group/CDRbatch/apps/app_zapras.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/apps/app_zapras.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/apps/app_zapras.c (original)
+++ team/group/CDRbatch/apps/app_zapras.c Mon Aug  6 17:33:42 2007
@@ -161,7 +161,7 @@
 			res = wait4(pid, &status, WNOHANG, NULL);
 			if (!res) {
 				/* Check for hangup */
-				if (chan->_softhangup && !signalled) {
+				if (ast_check_hangup(chan) && !signalled) {
 					ast_debug(1, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
 					kill(pid, SIGTERM);
 					signalled=1;

Modified: team/group/CDRbatch/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/build_tools/cflags.xml?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/build_tools/cflags.xml (original)
+++ team/group/CDRbatch/build_tools/cflags.xml Mon Aug  6 17:33:42 2007
@@ -8,6 +8,7 @@
 		<member name="DEBUG_THREADLOCALS" displayname="Enable Thread-Local-Storage Debugging">
 		</member>
 		<member name="DETECT_DEADLOCKS" displayname="Detect Deadlocks">
+			<depend>DEBUG_THREADS</depend>
 		</member>
 		<member name="DO_CRASH" displayname="Crash on fatal errors">
 		</member>

Modified: team/group/CDRbatch/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/channels/chan_iax2.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/channels/chan_iax2.c (original)
+++ team/group/CDRbatch/channels/chan_iax2.c Mon Aug  6 17:33:42 2007
@@ -745,6 +745,7 @@
 	time_t checktime;
 	ast_mutex_t lock;
 	ast_cond_t cond;
+	unsigned int ready_for_signal:1;
 	/*! if this thread is processing a full frame,
 	  some information about that frame will be stored
 	  here, so we can avoid dispatching any more full
@@ -988,6 +989,9 @@
 	ast_free(oldlist);
 }
 
+/* WARNING: insert_idle_thread should only ever be called within the
+ * context of an iax2_process_thread() thread.
+ */
 static void insert_idle_thread(struct iax2_thread *thread)
 {
 	if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
@@ -1013,8 +1017,10 @@
 	AST_LIST_UNLOCK(&idle_list);
 
 	/* If we popped a thread off the idle list, just return it */
-	if (thread)
+	if (thread) {
+		memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
 		return thread;
+	}
 
 	/* Pop the head of the dynamic list off */
 	AST_LIST_LOCK(&dynamic_list);
@@ -1022,8 +1028,10 @@
 	AST_LIST_UNLOCK(&dynamic_list);
 
 	/* If we popped a thread off the dynamic list, just return it */
-	if (thread)
+	if (thread) {
+		memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
 		return thread;
+	}
 
 	/* If we can't create a new dynamic thread for any reason, return no thread at all */
 	if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
@@ -1042,13 +1050,16 @@
 		ast_cond_destroy(&thread->cond);
 		ast_mutex_destroy(&thread->lock);
 		ast_free(thread);
-		thread = NULL;
+		return NULL;
 	}
 
 	/* this thread is not processing a full frame (since it is idle),
 	   so ensure that the field for the full frame call number is empty */
-	if (thread)
-		memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
+	memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
+
+	/* Wait for the thread to be ready before returning it to the caller */
+	while (!thread->ready_for_signal)
+		usleep(1);
 
 	return thread;
 }
@@ -1511,7 +1522,7 @@
 {
 	/* Close firmware */
 	if (cur->fwh) {
-		munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
+		munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
 	}
 	close(cur->fd);
 	ast_free(cur);
@@ -1607,7 +1618,7 @@
 		close(fd);
 		return -1;
 	}
-	fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
+	fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
 	if (fwh == (void *) -1) {
 		ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
 		close(fd);
@@ -1618,7 +1629,7 @@
 	MD5Final(sum, &md5);
 	if (memcmp(sum, fwh->chksum, sizeof(sum))) {
 		ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
-		munmap(fwh, stbuf.st_size);
+		munmap((void*)fwh, stbuf.st_size);
 		close(fd);
 		return -1;
 	}
@@ -1631,7 +1642,7 @@
 				break;
 			/* This version is no newer than what we have.  Don't worry about it.
 			   We'll consider it a proper load anyhow though */
-			munmap(fwh, stbuf.st_size);
+			munmap((void*)fwh, stbuf.st_size);
 			close(fd);
 			return 0;
 		}
@@ -1644,7 +1655,7 @@
 	
 	if (cur) {
 		if (cur->fwh)
-			munmap(cur->fwh, cur->mmaplen);
+			munmap((void*)cur->fwh, cur->mmaplen);
 		if (cur->fd > -1)
 			close(cur->fd);
 		cur->fwh = fwh;
@@ -3470,23 +3481,24 @@
 
 	ast_mutex_lock(&iaxsl[callno]);
 	pvt = iaxs[callno];
-	if (!strcasecmp(pvt->mohinterpret, "passthrough")) {
-		res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
-		ast_mutex_unlock(&iaxsl[callno]);
-		return res;
-	}
 
 	switch (condition) {
 	case AST_CONTROL_HOLD:
-		ast_moh_start(c, data, pvt->mohinterpret);
+		if (strcasecmp(pvt->mohinterpret, "passthrough")) {
+			ast_moh_start(c, data, pvt->mohinterpret);
+			goto done;
+		}
 		break;
 	case AST_CONTROL_UNHOLD:
-		ast_moh_stop(c);
-		break;
-	default:
-		res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
-	}
-
+		if (strcasecmp(pvt->mohinterpret, "passthrough")) {
+			ast_moh_stop(c);
+			goto done;
+		}
+	}
+
+	res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
+
+done:
 	ast_mutex_unlock(&iaxsl[callno]);
 
 	return res;
@@ -6262,7 +6274,8 @@
 	AST_LIST_TRAVERSE(&frame_queue, f, list) {
 		/* Send a copy immediately */
 		if ((f->callno == callno) && iaxs[f->callno] &&
-			((unsigned char ) (f->oseqno - last) < 128)) {
+			((unsigned char ) (f->oseqno - last) < 128) &&
+			(f->retries >= 0)) {
 			send_packet(f);
 		}
 	}
@@ -6713,11 +6726,13 @@
 		if (errno != ECONNREFUSED && errno != EAGAIN)
 			ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
 		handle_error();
-		insert_idle_thread(thread);
+		thread->iostate = IAX_IOSTATE_IDLE;
+		signal_condition(&thread->lock, &thread->cond);
 		return 1;
 	}
 	if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
-		insert_idle_thread(thread);
+		thread->iostate = IAX_IOSTATE_IDLE;
+		signal_condition(&thread->lock, &thread->cond);
 		return 1;
 	}
 	
@@ -6740,7 +6755,8 @@
 			   so queue it up for processing later. */
 			defer_full_frame(thread, cur);
 			AST_LIST_UNLOCK(&active_list);
-			insert_idle_thread(thread);
+			thread->iostate = IAX_IOSTATE_IDLE;
+			signal_condition(&thread->lock, &thread->cond);
 			return 1;
 		} else {
 			/* this thread is going to process this frame, so mark it */
@@ -8369,27 +8385,61 @@
 		/* Wait for something to signal us to be awake */
 		ast_mutex_lock(&thread->lock);
 
+		/* Flag that we're ready to accept signals */
+		thread->ready_for_signal = 1;
+		
 		/* Put into idle list if applicable */
 		if (put_into_idle)
 			insert_idle_thread(thread);
 
 		if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
+			struct iax2_thread *t = NULL;
 			/* Wait to be signalled or time out */
 			tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
 			ts.tv_sec = tv.tv_sec;
 			ts.tv_nsec = tv.tv_usec * 1000;
 			if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
-				ast_mutex_unlock(&thread->lock);
+				/* This thread was never put back into the available dynamic
+				 * thread list, so just go away. */
+				if (!put_into_idle) {
+					ast_mutex_unlock(&thread->lock);
+					break;
+				}
 				AST_LIST_LOCK(&dynamic_list);
-				AST_LIST_REMOVE(&dynamic_list, thread, list);
+				/* Account for the case where this thread is acquired *right* after a timeout */
+				if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
+					ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
 				AST_LIST_UNLOCK(&dynamic_list);
-				ast_atomic_dec_and_test(&iaxdynamicthreadcount);
-				break;		/* exiting the main loop */
+				if (t) {
+					/* This dynamic thread timed out waiting for a task and was
+					 * not acquired immediately after the timeout, 
+					 * so it's time to go away. */
+					ast_mutex_unlock(&thread->lock);
+					break;
+				}
+				/* Someone grabbed our thread *right* after we timed out.
+				 * Wait for them to set us up with something to do and signal
+				 * us to continue. */
+				tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
+				ts.tv_sec = tv.tv_sec;
+				ts.tv_nsec = tv.tv_usec * 1000;
+				if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
+				{
+					ast_mutex_unlock(&thread->lock);
+					break;
+				}
 			}
 		} else {
 			ast_cond_wait(&thread->cond, &thread->lock);
 		}
+
+		/* Go back into our respective list */
+		put_into_idle = 1;
+
 		ast_mutex_unlock(&thread->lock);
+
+		if (thread->iostate == IAX_IOSTATE_IDLE)
+			continue;
 
 		/* Add ourselves to the active list now */
 		AST_LIST_LOCK(&active_list);
@@ -8426,9 +8476,6 @@
 
 		/* Make sure another frame didn't sneak in there after we thought we were done. */
 		handle_deferred_full_frames(thread);
-
-		/* Go back into our respective list */
-		put_into_idle = 1;
 	}
 
 	/* I am exiting here on my own volition, I need to clean up my own data structures

Modified: team/group/CDRbatch/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/channels/chan_local.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/channels/chan_local.c (original)
+++ team/group/CDRbatch/channels/chan_local.c Mon Aug  6 17:33:42 2007
@@ -246,9 +246,9 @@
 		   we can't get everything.  Remember, we'll get another
 		   chance in just a little bit */
 		if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
-			if (!p->chan->_bridge->_softhangup) {
+			if (!ast_check_hangup(p->chan->_bridge)) {
 				if (!ast_mutex_trylock(&p->owner->lock)) {
-					if (!p->owner->_softhangup) {
+					if (!ast_check_hangup(p->owner)) {
 						ast_channel_masquerade(p->owner, p->chan->_bridge);
 						ast_set_flag(p, LOCAL_ALREADY_MASQED);
 					}
@@ -265,9 +265,9 @@
 	} else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
 		/* Masquerade bridged channel into chan */
 		if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
-			if (!p->owner->_bridge->_softhangup) {
+			if (!ast_check_hangup(p->owner->_bridge)) {
 				if (!ast_mutex_trylock(&p->chan->lock)) {
-					if (!p->chan->_softhangup) {
+					if (!ast_check_hangup(p->chan)) {
 						ast_channel_masquerade(p->chan, p->owner->_bridge);
 						ast_set_flag(p, LOCAL_ALREADY_MASQED);
 					}

Modified: team/group/CDRbatch/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/group/CDRbatch/channels/chan_mgcp.c?view=diff&rev=78298&r1=78297&r2=78298
==============================================================================
--- team/group/CDRbatch/channels/chan_mgcp.c (original)
+++ team/group/CDRbatch/channels/chan_mgcp.c Mon Aug  6 17:33:42 2007
@@ -2061,7 +2061,7 @@
 		ast_verbose("We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
 	}
 	snprintf(v, sizeof(v), "v=0\r\n");
-	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(dest.sin_addr));
+	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
 	snprintf(s, sizeof(s), "s=session\r\n");
 	snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
 	snprintf(t, sizeof(t), "t=0 0\r\n");

Modified: team/group/CDRbatch/channels/chan_sip.c

[... 3767 lines stripped ...]



More information about the asterisk-commits mailing list