[asterisk-commits] oej: branch oej/moremanager r204010 - in /team/oej/moremanager: ./ apps/ buil...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jun 29 09:42:43 CDT 2009


Author: oej
Date: Mon Jun 29 09:42:27 2009
New Revision: 204010

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=204010
Log:
Resolving automerge conflicts

Modified:
    team/oej/moremanager/   (props changed)
    team/oej/moremanager/Makefile
    team/oej/moremanager/apps/app_chanspy.c
    team/oej/moremanager/apps/app_dial.c
    team/oej/moremanager/apps/app_followme.c
    team/oej/moremanager/apps/app_meetme.c
    team/oej/moremanager/apps/app_mixmonitor.c
    team/oej/moremanager/apps/app_queue.c
    team/oej/moremanager/apps/app_sendtext.c
    team/oej/moremanager/apps/app_voicemail.c
    team/oej/moremanager/build_tools/cflags-devmode.xml
    team/oej/moremanager/build_tools/make_version_h
    team/oej/moremanager/channels/Makefile
    team/oej/moremanager/channels/chan_agent.c
    team/oej/moremanager/channels/chan_dahdi.c
    team/oej/moremanager/channels/chan_h323.c
    team/oej/moremanager/channels/chan_iax2.c
    team/oej/moremanager/channels/chan_local.c
    team/oej/moremanager/channels/chan_misdn.c
    team/oej/moremanager/channels/chan_sip.c
    team/oej/moremanager/channels/h323/ast_h323.cxx
    team/oej/moremanager/channels/h323/chan_h323.h
    team/oej/moremanager/channels/iax2-parser.c
    team/oej/moremanager/channels/iax2-parser.h
    team/oej/moremanager/channels/misdn/isdn_lib.c
    team/oej/moremanager/channels/misdn_config.c
    team/oej/moremanager/configs/logger.conf.sample
    team/oej/moremanager/configure   (contents, props changed)
    team/oej/moremanager/configure.ac
    team/oej/moremanager/contrib/scripts/get_ilbc_source.sh
    team/oej/moremanager/contrib/scripts/realtime_pgsql.sql
    team/oej/moremanager/contrib/scripts/safe_asterisk
    team/oej/moremanager/contrib/scripts/sip-friends.sql
    team/oej/moremanager/doc/asterisk-conf.txt
    team/oej/moremanager/funcs/func_channel.c
    team/oej/moremanager/funcs/func_cut.c
    team/oej/moremanager/funcs/func_odbc.c
    team/oej/moremanager/funcs/func_strings.c
    team/oej/moremanager/include/asterisk.h
    team/oej/moremanager/include/asterisk/audiohook.h
    team/oej/moremanager/include/asterisk/autoconfig.h.in
    team/oej/moremanager/include/asterisk/cdr.h
    team/oej/moremanager/include/asterisk/channel.h
    team/oej/moremanager/include/asterisk/compat.h
    team/oej/moremanager/include/asterisk/frame.h
    team/oej/moremanager/include/asterisk/linkedlists.h
    team/oej/moremanager/include/asterisk/lock.h
    team/oej/moremanager/include/asterisk/rtp.h
    team/oej/moremanager/include/asterisk/utils.h
    team/oej/moremanager/main/asterisk.c
    team/oej/moremanager/main/astmm.c
    team/oej/moremanager/main/audiohook.c
    team/oej/moremanager/main/autoservice.c
    team/oej/moremanager/main/cdr.c
    team/oej/moremanager/main/channel.c
    team/oej/moremanager/main/cli.c
    team/oej/moremanager/main/config.c
    team/oej/moremanager/main/db1-ast/recno/rec_open.c
    team/oej/moremanager/main/file.c
    team/oej/moremanager/main/frame.c
    team/oej/moremanager/main/loader.c
    team/oej/moremanager/main/logger.c
    team/oej/moremanager/main/manager.c
    team/oej/moremanager/main/pbx.c
    team/oej/moremanager/main/rtp.c
    team/oej/moremanager/main/slinfactory.c
    team/oej/moremanager/pbx/ael/ael.tab.c
    team/oej/moremanager/pbx/ael/ael.y
    team/oej/moremanager/pbx/pbx_config.c
    team/oej/moremanager/pbx/pbx_spool.c
    team/oej/moremanager/res/res_convert.c
    team/oej/moremanager/res/res_features.c
    team/oej/moremanager/res/res_jabber.c
    team/oej/moremanager/res/res_musiconhold.c
    team/oej/moremanager/res/res_odbc.c
    team/oej/moremanager/res/res_smdi.c
    team/oej/moremanager/static-http/astman.js
    team/oej/moremanager/utils/muted.c

Propchange: team/oej/moremanager/
------------------------------------------------------------------------------
--- reviewboard:url (original)
+++ reviewboard:url Mon Jun 29 09:42:27 2009
@@ -1,1 +1,2 @@
-http://reviewboard.digium.com
+https://reviewboard.asterisk.org
+

Modified: team/oej/moremanager/Makefile
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/Makefile?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/Makefile (original)
+++ team/oej/moremanager/Makefile Mon Jun 29 09:42:27 2009
@@ -320,13 +320,13 @@
 	menuselect/menuselect --check-deps menuselect.makeopts $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS)
 
 $(MOD_SUBDIRS_EMBED_LDSCRIPT):
-	@echo "EMBED_LDSCRIPTS+="`$(SUBMAKE) -C $(@:-embed-ldscript=) SUBDIR=$(@:-embed-ldscript=) __embed_ldscript` >> makeopts.embed_rules
+	+ at echo "EMBED_LDSCRIPTS+="`$(SUBMAKE) -C $(@:-embed-ldscript=) SUBDIR=$(@:-embed-ldscript=) __embed_ldscript` >> makeopts.embed_rules
 
 $(MOD_SUBDIRS_EMBED_LDFLAGS):
-	@echo "EMBED_LDFLAGS+="`$(SUBMAKE) -C $(@:-embed-ldflags=) SUBDIR=$(@:-embed-ldflags=) __embed_ldflags` >> makeopts.embed_rules
+	+ at echo "EMBED_LDFLAGS+="`$(SUBMAKE) -C $(@:-embed-ldflags=) SUBDIR=$(@:-embed-ldflags=) __embed_ldflags` >> makeopts.embed_rules
 
 $(MOD_SUBDIRS_EMBED_LIBS):
-	@echo "EMBED_LIBS+="`$(SUBMAKE) -C $(@:-embed-libs=) SUBDIR=$(@:-embed-libs=) __embed_libs` >> makeopts.embed_rules
+	+ at echo "EMBED_LIBS+="`$(SUBMAKE) -C $(@:-embed-libs=) SUBDIR=$(@:-embed-libs=) __embed_libs` >> makeopts.embed_rules
 
 $(MOD_SUBDIRS_MENUSELECT_TREE):
 	@$(SUBMAKE) -C $(@:-menuselect-tree=) SUBDIR=$(@:-menuselect-tree=) moduleinfo
@@ -404,7 +404,7 @@
 	rm -f build_tools/menuselect-deps
 
 datafiles: _all
-	if [ x`$(ID) -un` = xroot ]; then CFLAGS="$(ASTCFLAGS)" sh build_tools/mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig; fi
+	if [ x`$(ID) -un` = xroot ]; then CFLAGS="$(ASTCFLAGS)" bash build_tools/mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig; fi
 # Should static HTTP be installed during make samples or even with its own target ala
 # webvoicemail?  There are portions here that *could* be customized but might also be
 # improved a lot.  I'll put it here for now.
@@ -676,7 +676,7 @@
 			$(INSTALL) -m 755 contrib/init.d/rc.suse.asterisk $(DESTDIR)/etc/init.d/asterisk; \
 			if [ -z "$(DESTDIR)" ]; then /sbin/chkconfig --add asterisk; fi; \
 		elif [ -f /etc/slackware-version ]; then \
-			echo "Slackware is not currently supported, although an init script does exist for it." \
+			echo "Slackware is not currently supported, although an init script does exist for it."; \
 		else \
 			echo "We could not install init scripts for your distribution."; \
 		fi \
@@ -757,8 +757,8 @@
 	@echo "<?xml version=\"1.0\"?>" > $@
 	@echo >> $@
 	@echo "<menu name=\"Asterisk Module and Build Option Selection\">" >> $@
-	@for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} moduleinfo >> $@; done
-	@for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} makeopts >> $@; done
+	+ at for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} moduleinfo >> $@; done
+	+ at for dir in $(sort $(filter-out main,$(MOD_SUBDIRS))); do $(SUBMAKE) -C $${dir} SUBDIR=$${dir} makeopts >> $@; done
 	@cat build_tools/cflags.xml >> $@
 	@if [ "${AST_DEVMODE}" = "yes" ]; then \
 		cat build_tools/cflags-devmode.xml >> $@; \

Modified: team/oej/moremanager/apps/app_chanspy.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_chanspy.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_chanspy.c (original)
+++ team/oej/moremanager/apps/app_chanspy.c Mon Jun 29 09:42:27 2009
@@ -171,7 +171,7 @@
 static int spy_generate(struct ast_channel *chan, void *data, int len, int samples) 
 {
 	struct chanspy_translation_helper *csth = data;
-	struct ast_frame *f;
+	struct ast_frame *f, *cur;
 
 	ast_audiohook_lock(&csth->spy_audiohook);
 	if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
@@ -186,14 +186,16 @@
 	if (!f)
 		return 0;
 		
-	if (ast_write(chan, f)) {
-		ast_frfree(f);
-		return -1;
-	}
-
-	if (csth->fd) {
-		if (write(csth->fd, f->data, f->datalen) < 0) {
-			ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
+	for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
+		if (ast_write(chan, cur)) {
+			ast_frfree(f);
+			return -1;
+		}
+
+		if (csth->fd) {
+			if (write(csth->fd, cur->data, cur->datalen) < 0) {
+				ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
+			}
 		}
 	}
 
@@ -214,6 +216,8 @@
 	struct ast_channel *peer;
 
 	ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, chan->name);
+
+	ast_set_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC | AST_AUDIOHOOK_SMALL_QUEUE);
 
 	res = ast_audiohook_attach(chan, audiohook);
 

Modified: team/oej/moremanager/apps/app_dial.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_dial.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_dial.c (original)
+++ team/oej/moremanager/apps/app_dial.c Mon Jun 29 09:42:27 2009
@@ -356,6 +356,10 @@
 			ast_cdr_failed(chan->cdr); \
 		numnochan++; \
 		break; \
+	case AST_CAUSE_NO_ANSWER: \
+		if (chan->cdr) \
+			ast_cdr_noanswer(chan->cdr); \
+		break; \
 	case AST_CAUSE_NORMAL_CLEARING: \
 		break; \
 	default: \
@@ -500,6 +504,9 @@
 					tech = tmpchan;
 				} else {
 					const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
+					if (ast_strlen_zero(forward_context)) {
+						forward_context = NULL;
+					}
 					snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
 					stuff = tmpchan;
 					tech = "Local";

Modified: team/oej/moremanager/apps/app_followme.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_followme.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_followme.c (original)
+++ team/oej/moremanager/apps/app_followme.c Mon Jun 29 09:42:27 2009
@@ -874,22 +874,22 @@
 		status = 0;	
 		if (!AST_LIST_EMPTY(findme_user_list))
 			winner = wait_for_winner(findme_user_list, nm, caller, tpargs->namerecloc, &status, tpargs);
-		
-					
+
 		AST_LIST_TRAVERSE_SAFE_BEGIN(findme_user_list, fmuser, entry) {
 			if (!fmuser->cleared && fmuser->ochan != winner)
 				clear_caller(fmuser);
 			AST_LIST_REMOVE_CURRENT(findme_user_list, entry);
 			free(fmuser);
 		}
-		AST_LIST_TRAVERSE_SAFE_END
+		AST_LIST_TRAVERSE_SAFE_END;
+
 		fmuser = NULL;
 		tmpuser = NULL;
 		headuser = NULL;	
 		if (winner)
 			break;
 
-		if (!caller) {
+		if (!caller || ast_check_hangup(caller)) {
 			tpargs->status = 1;
 			free(findme_user_list);
 			return;	

Modified: team/oej/moremanager/apps/app_meetme.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_meetme.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_meetme.c (original)
+++ team/oej/moremanager/apps/app_meetme.c Mon Jun 29 09:42:27 2009
@@ -2343,9 +2343,19 @@
 							}
 						}
 						if (conf->transframe[index]) {
- 							if (conf->transframe[index]->frametype != AST_FRAME_NULL) {
-	 							if (can_write(chan, confflags) && ast_write(chan, conf->transframe[index]))
-									ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", chan->name);
+ 							if ((conf->transframe[index]->frametype != AST_FRAME_NULL) &&
+							    can_write(chan, confflags)) {
+								struct ast_frame *cur;
+								
+								/* the translator may have returned a list of frames, so
+								   write each one onto the channel
+								*/
+								for (cur = conf->transframe[index]; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
+									if (ast_write(chan, cur)) {
+										ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", chan->name);
+										break;
+									}
+								}
 							}
 						} else {
 							ast_mutex_unlock(&conf->listenlock);
@@ -2715,7 +2725,7 @@
 
 		empty = ast_test_flag(&confflags, CONFFLAG_EMPTY | CONFFLAG_EMPTYNOPIN);
 		empty_no_pin = ast_test_flag(&confflags, CONFFLAG_EMPTYNOPIN);
-		always_prompt = ast_test_flag(&confflags, CONFFLAG_ALWAYSPROMPT);
+		always_prompt = ast_test_flag(&confflags, CONFFLAG_ALWAYSPROMPT | CONFFLAG_DYNAMICPIN);
 	}
 
 	do {

Modified: team/oej/moremanager/apps/app_mixmonitor.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_mixmonitor.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_mixmonitor.c (original)
+++ team/oej/moremanager/apps/app_mixmonitor.c Mon Jun 29 09:42:27 2009
@@ -64,12 +64,17 @@
 "Records the audio on the current channel to the specified file.\n"
 "If the filename is an absolute path, uses that path, otherwise\n"
 "creates the file in the configured monitoring directory from\n"
-"asterisk.conf.\n\n"
+"asterisk.conf.  Use of StopMixMonitor is required to guarantee\n"
+"the audio file is available for processing during dialplan execution.\n\n"
 "Valid options:\n"
 " a      - Append to the file instead of overwriting it.\n"
 " b      - Only save audio to the file while the channel is bridged.\n"
 "          Note: Does not include conferences or sounds played to each bridged\n"
 "                party.\n"
+"          Note: If you utilize this option inside a Local channel, you must\n"
+"                 make sure the Local channel is not optimized away. To do this,\n"
+"                 be sure to call your Local channel with the '/n' option.\n"
+"                 For example: Dial(Local/start at mycontext/n)\n"
 " v(<x>) - Adjust the heard volume by a factor of <x> (range -4 to 4)\n"	
 " V(<x>) - Adjust the spoken volume by a factor of <x> (range -4 to 4)\n"	
 " W(<x>) - Adjust the both heard and spoken volumes by a factor of <x>\n"
@@ -84,8 +89,7 @@
 static const char *stop_synopsis = "Stop recording a call through MixMonitor";
 static const char *stop_desc = ""
 "  StopMixMonitor()\n\n"
-"Stops the audio recording that was started with a call to MixMonitor()\n"
-"on the current channel.\n"
+"Stop recording a call through MixMonitor, and free the recording's file handle.\n"
 "";
 
 struct module_symbols *me;
@@ -140,7 +144,25 @@
 	unsigned int destruction_ok;
 	ast_cond_t destruction_condition;
 	ast_mutex_t lock;
+
+	/* The filestream is held in the datastore so it can be stopped
+	 * immediately during stop_mixmonitor or channel destruction. */
+	int fs_quit;
+	struct ast_filestream *fs;
 };
+
+static void mixmonitor_ds_close_fs(struct mixmonitor_ds *mixmonitor_ds)
+{
+	ast_mutex_lock(&mixmonitor_ds->lock);
+	if (mixmonitor_ds->fs) {
+		ast_closestream(mixmonitor_ds->fs);
+		mixmonitor_ds->fs = NULL;
+		mixmonitor_ds->fs_quit = 1;
+		if (option_verbose > 1)
+			ast_verbose(VERBOSE_PREFIX_2 "MixMonitor close filestream\n");
+	}
+	ast_mutex_unlock(&mixmonitor_ds->lock);
+}
 
 static void mixmonitor_ds_destroy(void *data)
 {
@@ -186,27 +208,41 @@
 
 #define SAMPLES_PER_FRAME 160
 
+static void mixmonitor_free(struct mixmonitor *mixmonitor)
+{
+	if (mixmonitor) {
+		if (mixmonitor->mixmonitor_ds) {
+			ast_mutex_destroy(&mixmonitor->mixmonitor_ds->lock);
+			ast_cond_destroy(&mixmonitor->mixmonitor_ds->destruction_condition);
+			ast_free(mixmonitor->mixmonitor_ds);
+		}
+		ast_free(mixmonitor);
+	}
+}
+
 static void *mixmonitor_thread(void *obj) 
 {
 	struct mixmonitor *mixmonitor = obj;
-	struct ast_filestream *fs = NULL;
+	struct ast_filestream **fs = NULL;
 	unsigned int oflags;
 	char *ext;
 	int errflag = 0;
 
 	if (option_verbose > 1)
 		ast_verbose(VERBOSE_PREFIX_2 "Begin MixMonitor Recording %s\n", mixmonitor->name);
-	
+
 	ast_audiohook_lock(&mixmonitor->audiohook);
 
-	while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
+	fs = &mixmonitor->mixmonitor_ds->fs;
+
+	while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING && !mixmonitor->mixmonitor_ds->fs_quit) {
 		struct ast_frame *fr = NULL;
-		
+
 		ast_audiohook_trigger_wait(&mixmonitor->audiohook);
-		
+
 		if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING)
 			break;
-		
+
 		if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR)))
 			continue;
 
@@ -214,27 +250,31 @@
 		if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || (mixmonitor->mixmonitor_ds->chan && ast_bridged_channel(mixmonitor->mixmonitor_ds->chan))) {
 			ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
 			/* Initialize the file if not already done so */
-			if (!fs && !errflag) {
+			if (!*fs && !errflag && !mixmonitor->mixmonitor_ds->fs_quit) {
 				oflags = O_CREAT | O_WRONLY;
 				oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
-				
+
 				if ((ext = strrchr(mixmonitor->filename, '.')))
 					*(ext++) = '\0';
 				else
 					ext = "raw";
-				
-				if (!(fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0644))) {
+
+				if (!(*fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0644))) {
 					ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext);
 					errflag = 1;
 				}
 			}
 
-			/* Write out the frame */
-			if (fs)
-				ast_writestream(fs, fr);
-		} else {
-			ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
+			/* Write out the frame(s) */
+			if (*fs) {
+				struct ast_frame *cur;
+
+				for (cur = fr; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
+					ast_writestream(*fs, cur);
+				}
+			}
 		}
+		ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
 
 		/* All done! free it. */
 		ast_frame_free(fr, 0);
@@ -243,12 +283,8 @@
 	ast_audiohook_detach(&mixmonitor->audiohook);
 	ast_audiohook_unlock(&mixmonitor->audiohook);
 	ast_audiohook_destroy(&mixmonitor->audiohook);
-	
-	if (option_verbose > 1)
-		ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name);
-
-	if (fs)
-		ast_closestream(fs);
+
+	mixmonitor_ds_close_fs(mixmonitor->mixmonitor_ds);
 
 	if (mixmonitor->post_process) {
 		if (option_verbose > 2)
@@ -261,10 +297,11 @@
 		ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock);
 	}
 	ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
-	ast_mutex_destroy(&mixmonitor->mixmonitor_ds->lock);
-	ast_cond_destroy(&mixmonitor->mixmonitor_ds->destruction_condition);
-	ast_free(mixmonitor->mixmonitor_ds);
-	free(mixmonitor);
+
+	if (option_verbose > 1)
+		ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name);
+
+	mixmonitor_free(mixmonitor);
 
 	return NULL;
 }
@@ -282,6 +319,8 @@
 	ast_cond_init(&mixmonitor_ds->destruction_condition, NULL);
 
 	if (!(datastore = ast_channel_datastore_alloc(&mixmonitor_ds_info, NULL))) {
+		ast_mutex_destroy(&mixmonitor_ds->lock);
+		ast_cond_destroy(&mixmonitor_ds->destruction_condition);
 		ast_free(mixmonitor_ds);
 		return -1;
 	}
@@ -333,6 +372,7 @@
 	/* Copy over flags and channel name */
 	mixmonitor->flags = flags;
 	if (setup_mixmonitor_ds(mixmonitor, chan)) {
+		mixmonitor_free(mixmonitor);
 		return;
 	}
 	mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
@@ -458,6 +498,13 @@
 static int stop_mixmonitor_exec(struct ast_channel *chan, void *data)
 {
 	struct ast_module_user *u;
+	struct ast_datastore *datastore = NULL;
+
+	/* closing the filestream here guarantees the file is avaliable to the dialplan
+	 * after calling StopMixMonitor */
+	if ((datastore = ast_channel_datastore_find(chan, &mixmonitor_ds_info, NULL))) {
+		mixmonitor_ds_close_fs(datastore->data);
+	}
 
 	u = ast_module_user_add(chan);
 

Modified: team/oej/moremanager/apps/app_queue.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_queue.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_queue.c (original)
+++ team/oej/moremanager/apps/app_queue.c Mon Jun 29 09:42:27 2009
@@ -594,15 +594,15 @@
 	struct member *cur;
 	struct ao2_iterator mem_iter;
 	struct call_queue *q;
+	char tmp_interface[80];
 
 	AST_LIST_LOCK(&queues);
 	AST_LIST_TRAVERSE(&queues, q, list) {
 		ast_mutex_lock(&q->lock);
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((cur = ao2_iterator_next(&mem_iter))) {
-			char *tmp_interface;
 			char *slash_pos;
-			tmp_interface = ast_strdupa(cur->state_interface);
+			ast_copy_string(tmp_interface, cur->state_interface, sizeof(tmp_interface));
 			if ((slash_pos = strchr(tmp_interface, '/')))
 				if ((slash_pos = strchr(slash_pos + 1, '/')))
 					*slash_pos = '\0';
@@ -647,6 +647,7 @@
 	struct member_interface *curint;
 	char *loc;
 	char *technology;
+	char interface[80];
 
 	technology = ast_strdupa(sc->dev);
 	loc = strchr(technology, '/');
@@ -658,9 +659,8 @@
 
 	AST_LIST_LOCK(&interfaces);
 	AST_LIST_TRAVERSE(&interfaces, curint, list) {
-		char *interface;
 		char *slash_pos;
-		interface = ast_strdupa(curint->interface);
+		ast_copy_string(interface, curint->interface, sizeof(interface));
 		if ((slash_pos = strchr(interface, '/')))
 			if ((slash_pos = strchr(slash_pos + 1, '/')))
 				*slash_pos = '\0';
@@ -1963,6 +1963,21 @@
 		ast_copy_string(tmp->chan->exten, macroexten, sizeof(tmp->chan->exten));
 	else
 		ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
+	if (ast_cdr_isset_unanswered()) {
+		/* they want to see the unanswered dial attempts! */
+		/* set up the CDR fields on all the CDRs to give sensical information */
+		ast_cdr_setdestchan(tmp->chan->cdr, tmp->chan->name);
+		strcpy(tmp->chan->cdr->clid, qe->chan->cdr->clid);
+		strcpy(tmp->chan->cdr->channel, qe->chan->cdr->channel);
+		strcpy(tmp->chan->cdr->src, qe->chan->cdr->src);
+		strcpy(tmp->chan->cdr->dst, qe->chan->exten);
+		strcpy(tmp->chan->cdr->dcontext, qe->chan->context);
+		strcpy(tmp->chan->cdr->lastapp, qe->chan->cdr->lastapp);
+		strcpy(tmp->chan->cdr->lastdata, qe->chan->cdr->lastdata);
+		tmp->chan->cdr->amaflags = qe->chan->cdr->amaflags;
+		strcpy(tmp->chan->cdr->accountcode, qe->chan->cdr->accountcode);
+		strcpy(tmp->chan->cdr->userfield, qe->chan->cdr->userfield);
+	}
 	ast_channel_unlock(qe->chan);
 
 	/* Place the call, but don't wait on the answer */
@@ -2967,6 +2982,20 @@
 		}
 		if (option_debug && res == -1)
 			ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name);
+		if (ast_cdr_isset_unanswered()) {
+			/* channel contains the name of one of the outgoing channels
+			   in its CDR; zero out this CDR to avoid a dual-posting */
+			struct callattempt *o;
+			for (o = outgoing; o; o = o->q_next) {
+				if (!o->chan) {
+					continue;
+				}
+				if (strcmp(o->chan->cdr->dstchannel, qe->chan->cdr->dstchannel) == 0) {
+					ast_set_flag(o->chan->cdr, AST_CDR_FLAG_POST_DISABLED);
+					break;
+				}
+			}
+		}
 	} else { /* peer is valid */
 		/* Ah ha!  Someone answered within the desired timeframe.  Of course after this
 		   we will always return with -1 so that it is hung up properly after the
@@ -3036,6 +3065,7 @@
 				ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
 				record_abandoned(qe);
+				ast_cdr_noanswer(qe->chan->cdr);
 				ast_hangup(peer);
 				ao2_ref(member, -1);
 				return -1;
@@ -3052,6 +3082,7 @@
 			ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
 			ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
 			record_abandoned(qe);
+			ast_cdr_failed(qe->chan->cdr);
 			ast_hangup(peer);
 			ao2_ref(member, -1);
 			return -1;
@@ -4002,6 +4033,7 @@
 			/* Leave if we have exceeded our queuetimeout */
 			if (qe.expire && (time(NULL) >= qe.expire)) {
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_TIMEOUT;
 				res = 0;
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
@@ -4020,6 +4052,7 @@
 			/* Leave if we have exceeded our queuetimeout */
 			if (qe.expire && (time(NULL) >= qe.expire)) {
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_TIMEOUT;
 				res = 0;
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
@@ -4033,6 +4066,7 @@
 			/* Leave if we have exceeded our queuetimeout */
 			if (qe.expire && (time(NULL) >= qe.expire)) {
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_TIMEOUT;
 				res = 0;
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
@@ -4051,6 +4085,7 @@
 					ast_verbose(VERBOSE_PREFIX_3 "Exiting on time-out cycle\n");
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_TIMEOUT;
 				res = 0;
 				break;
@@ -4059,6 +4094,7 @@
 			/* leave the queue if no agents, if enabled */
 			if (qe.parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_LEAVEEMPTY;
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe.pos, qe.opos, (long)(time(NULL) - qe.start));
 				res = 0;
@@ -4068,6 +4104,7 @@
 			/* leave the queue if no reachable agents, if enabled */
 			if ((qe.parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_LEAVEUNAVAIL;
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe.pos, qe.opos, (long)(time(NULL) - qe.start));
 				res = 0;
@@ -4077,6 +4114,7 @@
 			/* Leave if we have exceeded our queuetimeout */
 			if (qe.expire && (time(NULL) >= qe.expire)) {
 				record_abandoned(&qe);
+				ast_cdr_noanswer(qe.chan->cdr);
 				reason = QUEUE_TIMEOUT;
 				res = 0;
 				ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
@@ -4108,6 +4146,7 @@
 			if (res < 0) {
 				if (!qe.handled) {
 					record_abandoned(&qe);
+					ast_cdr_noanswer(qe.chan->cdr);
 					ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON",
 						"%d|%d|%ld", qe.pos, qe.opos,
 						(long) time(NULL) - qe.start);
@@ -4911,13 +4950,15 @@
 	char *queuename, *interface, *membername = NULL, *state_interface = NULL;
 	int penalty;
 
-	if ((argc != 6) && (argc != 8) && (argc != 10)) {
+	if ((argc != 6) && (argc != 8) && (argc != 10) && (argc != 12)) {
 		return RESULT_SHOWUSAGE;
 	} else if (strcmp(argv[4], "to")) {
 		return RESULT_SHOWUSAGE;
 	} else if ((argc == 8) && strcmp(argv[6], "penalty")) {
 		return RESULT_SHOWUSAGE;
 	} else if ((argc == 10) && strcmp(argv[8], "as")) {
+		return RESULT_SHOWUSAGE;
+	} else if ((argc == 12) && strcmp(argv[10], "state_interface")) {
 		return RESULT_SHOWUSAGE;
 	}
 

Modified: team/oej/moremanager/apps/app_sendtext.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_sendtext.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_sendtext.c (original)
+++ team/oej/moremanager/apps/app_sendtext.c Mon Jun 29 09:42:27 2009
@@ -78,7 +78,9 @@
 		
 	u = ast_module_user_add(chan);	
 
-	if (ast_strlen_zero(data)) {
+	/* NOT ast_strlen_zero, because some protocols (e.g. SIP) MUST be able to
+	 * send a zero-length message. */
+	if (!data) {
 		ast_log(LOG_WARNING, "SendText requires an argument (text[|options])\n");
 		ast_module_user_remove(u);
 		return -1;

Modified: team/oej/moremanager/apps/app_voicemail.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/apps/app_voicemail.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/apps/app_voicemail.c (original)
+++ team/oej/moremanager/apps/app_voicemail.c Mon Jun 29 09:42:27 2009
@@ -439,7 +439,7 @@
 
 static char ext_pass_cmd[128];
 
-int my_umask;
+static int my_umask;
 
 #if ODBC_STORAGE
 #define tdesc "Comedian Mail (Voicemail System) with ODBC Storage"
@@ -1904,6 +1904,7 @@
 {
 	struct vm_state *vms_p;
 
+	pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 	if ((vms_p = pthread_getspecific(ts_vmstate.key)) && !strcmp(vms_p->imapuser, vmu->imapuser) && !strcmp(vms_p->username, vmu->mailbox)) {
 		return vms_p;
 	}
@@ -1931,6 +1932,7 @@
 
 	if (interactive) {
 		struct vm_state *vms;
+		pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 		vms = pthread_getspecific(ts_vmstate.key);
 		return vms;
 	}
@@ -1972,6 +1974,7 @@
 
 	if (interactive) {
 		struct vm_state *vms;
+		pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 		vms = pthread_getspecific(ts_vmstate.key);
 		return vms;
 	}
@@ -3965,7 +3968,7 @@
 	char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
 	char callerid[256];
 	FILE *txt;
-	char date[256];
+	char date[50];
 	int txtdes;
 	int res = 0;
 	int msgnum;
@@ -3978,15 +3981,18 @@
 	char fn[PATH_MAX];
 	char prefile[PATH_MAX] = "";
 	char tempfile[PATH_MAX] = "";
-	char ext_context[256] = "";
+	char ext_context[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2] = "";
 	char fmt[80];
 	char *context;
 	char ecodes[16] = "#";
-	char tmp[1024] = "", *tmpptr;
+	char tmp[1324] = "", *tmpptr;
 	struct ast_vm_user *vmu;
 	struct ast_vm_user svm;
 	const char *category = NULL;
 
+	if (strlen(ext) > sizeof(tmp) - 1) {
+		ast_log(LOG_WARNING, "List of extensions is too long (>%ld).  Truncating.\n", (long) sizeof(tmp) - 1);
+	}
 	ast_copy_string(tmp, ext, sizeof(tmp));
 	ext = tmp;
 	context = strchr(tmp, '@');
@@ -5580,7 +5586,8 @@
 	vms->starting = 0; 
 	make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
 	adsi_message(chan, vms);
-	if (!strcasecmp(chan->language, "he")) {	/* HEBREW FORMAT */
+	
+	if (!strcasecmp(chan->language, "he")) {			/* HEBREW FORMAT */
 		/*
 		 * The syntax in hebrew for counting the number of message is up side down
 		 * in comparison to english.
@@ -5600,47 +5607,56 @@
 					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
 				}
 			}
-		}
-	} else {
+		}		
+
+	} else if (!strcasecmp(chan->language, "pl")) {		/* POLISH FORMAT */
+		if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+			int ten, one;
+			char nextmsg[256];
+			ten = (vms->curmsg + 1) / 10;
+			one = (vms->curmsg + 1) % 10;
+				
+			if (vms->curmsg < 20) {
+				snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
+				res = wait_file2(chan, vms, nextmsg);
+			} else {
+				snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
+				res = wait_file2(chan, vms, nextmsg);
+				if (one > 0) {
+					if (!res) {
+						snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
+						res = wait_file2(chan, vms, nextmsg);
+					}
+				}
+			}
+		}
+		if (!res)
+			res = wait_file2(chan, vms, "vm-message");			
+
+	} else if (!strcasecmp(chan->language, "se")) {		/* SWEDISH FORMAT */
 		if (!vms->curmsg)
 			res = wait_file2(chan, vms, "vm-first");	/* "First" */
 		else if (vms->curmsg == vms->lastmsg)
-			res = wait_file2(chan, vms, "vm-last");		/* "last" */
-	}
-	if (!res) {
-		/* POLISH syntax */
-		if (!strcasecmp(chan->language, "pl")) { 
-			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
-				int ten, one;
-				char nextmsg[256];
-				ten = (vms->curmsg + 1) / 10;
-				one = (vms->curmsg + 1) % 10;
-				
-				if (vms->curmsg < 20) {
-					snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
-					res = wait_file2(chan, vms, nextmsg);
-				} else {
-					snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
-					res = wait_file2(chan, vms, nextmsg);
-					if (one > 0) {
-						if (!res) {
-							snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
-							res = wait_file2(chan, vms, nextmsg);
-						}
-					}
-				}
-			}
+			res = wait_file2(chan, vms, "vm-last");		/* "last" */		
+		res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
+		if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
 			if (!res)
-				res = wait_file2(chan, vms, "vm-message");
-		} else {
-			if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
-				res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
-			else /* DEFAULT syntax */
-				res = wait_file2(chan, vms, "vm-message");
-			if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
-				if (!res)
-					res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
-			}
+				res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
+		}
+		/* We know that the difference between English and Swedish
+		 * is very small, however, we differ the two for standartization
+		 * purposes, and possible changes to either of these in the 
+		 * future
+		 */
+	} else {
+		if (!vms->curmsg)								/* Default syntax */
+			res = wait_file2(chan, vms, "vm-first");	/* "First" */
+		else if (vms->curmsg == vms->lastmsg)
+			res = wait_file2(chan, vms, "vm-last");		/* "last" */		
+		res = wait_file2(chan, vms, "vm-message");
+		if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+			if (!res)
+				res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
 		}
 	}
 
@@ -7428,6 +7444,10 @@
 	/* If ADSI is supported, setup login screen */
 	adsi_begin(chan, &useadsi);
 
+	if (!valid) {
+		goto out;
+	}
+
 #ifdef IMAP_STORAGE
 	pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 	pthread_setspecific(ts_vmstate.key, &vms);
@@ -7439,9 +7459,6 @@
 	vmstate_insert(&vms);
 	init_vm_state(&vms);
 #endif
-	if (!valid)
-		goto out;
-
 	if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
 		/* TODO: Handle memory allocation failure */
 	}
@@ -7856,7 +7873,9 @@
 	}
 	/*  before we delete the state, we should copy pertinent info
 	 *  back to the persistent model */
-	vmstate_delete(&vms);
+	if (vmu) {
+		vmstate_delete(&vms);
+	}
 #endif
 	if (vmu)
 		free_user(vmu);
@@ -8846,13 +8865,26 @@
 {
 	int res;
 	char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
+	char *smdi_loaded = ast_module_helper("", "res_smdi.so", 0, 0, 0, 0);
 	free(adsi_loaded);
+	free(smdi_loaded);
+
 	if (!adsi_loaded) {
 		/* If embedded, res_adsi may be known as "res_adsi" not "res_adsi.so" */
 		adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
 		ast_free(adsi_loaded);
 		if (!adsi_loaded) {
 			ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
+			return AST_MODULE_LOAD_DECLINE;
+		}
+	}
+
+	if (!smdi_loaded) {
+		/* If embedded, res_smdi may be known as "res_smdi" not "res_smdi.so" */
+		smdi_loaded = ast_module_helper("", "res_smdi", 0, 0, 0, 0);
+		ast_free(smdi_loaded);
+		if (!smdi_loaded) {
+			ast_log(LOG_ERROR, "app_voicemail.so depends upon res_smdi.so\n");
 			return AST_MODULE_LOAD_DECLINE;
 		}
 	}

Modified: team/oej/moremanager/build_tools/cflags-devmode.xml
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/build_tools/cflags-devmode.xml?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/build_tools/cflags-devmode.xml (original)
+++ team/oej/moremanager/build_tools/cflags-devmode.xml Mon Jun 29 09:42:27 2009
@@ -12,6 +12,4 @@
 		</member>
 		<member name="MTX_PROFILE" displayname="Enable Code Profiling Using TSC Counters">
 		</member>
-		<member name="TRACE_FRAMES" displayname="Trace Frame Allocations">
-		</member>
 	</category>

Modified: team/oej/moremanager/build_tools/make_version_h
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/build_tools/make_version_h?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/build_tools/make_version_h (original)
+++ team/oej/moremanager/build_tools/make_version_h Mon Jun 29 09:42:27 2009
@@ -1,5 +1,5 @@
 #!/bin/sh
-if [ ! -f ../.flavor ]; then
+if [ ! -f .flavor ]; then
     cat << END
 /*
  * version.h 
@@ -10,8 +10,8 @@
 
 END
 else
-    aadkver=`cat ../.version`
-    aadkflavor=`cat ../.flavor`
+    aadkver=`cat .version`
+    aadkflavor=`cat .flavor`
     cat << END
 /*
  * version.h 

Modified: team/oej/moremanager/channels/Makefile
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/channels/Makefile?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/channels/Makefile (original)
+++ team/oej/moremanager/channels/Makefile Mon Jun 29 09:42:27 2009
@@ -102,6 +102,8 @@
 
 $(if $(filter chan_iax2,$(EMBEDDED_MODS)),modules.link,chan_iax2.so): iax2-parser.o iax2-provision.o
 
+$(if $(filter chan_h323,$(EMBEDDED_MODS)),modules.link,chan_h323.so): h323/libchanh323.a
+
 ifeq ($(OSARCH),linux-gnu)
 chan_h323.so: chan_h323.o h323/libchanh323.a h323/Makefile.ast
 	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"

Modified: team/oej/moremanager/channels/chan_agent.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/moremanager/channels/chan_agent.c?view=diff&rev=204010&r1=204009&r2=204010
==============================================================================
--- team/oej/moremanager/channels/chan_agent.c (original)
+++ team/oej/moremanager/channels/chan_agent.c Mon Jun 29 09:42:27 2009
@@ -261,6 +261,7 @@
 static void set_agentbycallerid(const char *callerid, const char *agent);
 static struct ast_channel* agent_get_base_channel(struct ast_channel *chan);
 static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base);
+static int agent_logoff(const char *agent, int soft);
 
 /*! \brief Channel interface description for PBX integration */
 static const struct ast_channel_tech agent_tech = {
@@ -493,8 +494,12 @@
 	struct ast_frame *f = NULL;
 	static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
 	const char *status;
-	ast_mutex_lock(&p->lock); 
+	int cur_time = time(NULL);
+	ast_mutex_lock(&p->lock);
 	CHECK_FORMATS(ast, p);
+	if (!p->start) {
+		p->start = cur_time;
+	}
 	if (p->chan) {
 		ast_copy_flags(p->chan, ast, AST_FLAG_EXCEPTION);
 		p->chan->fdno = (ast->fdno == AST_AGENT_FD) ? AST_TIMING_FD : ast->fdno;
@@ -511,19 +516,16 @@
 				if (p->chan)
 					ast_log(LOG_DEBUG, "Bridge on '%s' being cleared (2)\n", p->chan->name);
 				if (p->owner->_state != AST_STATE_UP) {
-					int howlong = time(NULL) - p->start;
-					if (p->autologoff && howlong > p->autologoff) {
-						long logintime = time(NULL) - p->loginstart;
+					int howlong = cur_time - p->start;
+					if (p->autologoff && howlong >= p->autologoff) {
 						p->loginstart = 0;
 							ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
-						agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Autologoff");
-						if (persistent_agents)
-							dump_agents();
+						agent_logoff_maintenance(p, p->loginchan, (cur_time = p->loginstart), ast->uniqueid, "Autologoff");
 					}
 				}
 				status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
 				if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
-					long logintime = time(NULL) - p->loginstart;
+					long logintime = cur_time - p->loginstart;
 					p->loginstart = 0;
 					ast_log(LOG_NOTICE, "Agent read: '%s' is not available now, auto logoff\n", p->name);
 					agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail");
@@ -537,29 +539,38 @@

[... 6822 lines stripped ...]



More information about the asterisk-commits mailing list