[svn-commits] oej: branch oej/videocaps r103782 - in /team/oej/videocaps: ./ apps/ build_to...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Feb 18 13:35:56 CST 2008


Author: oej
Date: Mon Feb 18 13:35:55 2008
New Revision: 103782

URL: http://svn.digium.com/view/asterisk?view=rev&rev=103782
Log:
Update, resolved conflict

Modified:
    team/oej/videocaps/   (props changed)
    team/oej/videocaps/CHANGES
    team/oej/videocaps/UPGRADE.txt
    team/oej/videocaps/apps/app_channelredirect.c
    team/oej/videocaps/apps/app_externalivr.c
    team/oej/videocaps/apps/app_queue.c
    team/oej/videocaps/apps/app_voicemail.c
    team/oej/videocaps/build_tools/cflags.xml
    team/oej/videocaps/channels/chan_iax2.c
    team/oej/videocaps/channels/chan_sip.c
    team/oej/videocaps/channels/chan_skinny.c
    team/oej/videocaps/channels/chan_zap.c
    team/oej/videocaps/channels/misdn/chan_misdn_config.h
    team/oej/videocaps/channels/misdn/ie.c
    team/oej/videocaps/channels/misdn/isdn_lib.c
    team/oej/videocaps/channels/misdn/isdn_lib.h
    team/oej/videocaps/channels/misdn/isdn_msg_parser.c
    team/oej/videocaps/channels/misdn/portinfo.c
    team/oej/videocaps/configs/queues.conf.sample
    team/oej/videocaps/configure
    team/oej/videocaps/configure.ac
    team/oej/videocaps/doc/tex/imapstorage.tex
    team/oej/videocaps/funcs/func_cdr.c
    team/oej/videocaps/funcs/func_channel.c
    team/oej/videocaps/include/asterisk/aes.h
    team/oej/videocaps/include/asterisk/autoconfig.h.in
    team/oej/videocaps/include/asterisk/channel.h
    team/oej/videocaps/include/asterisk/extconf.h
    team/oej/videocaps/include/asterisk/pbx.h
    team/oej/videocaps/include/asterisk/strings.h
    team/oej/videocaps/include/asterisk/time.h
    team/oej/videocaps/main/ast_expr2f.c
    team/oej/videocaps/main/channel.c
    team/oej/videocaps/main/cli.c
    team/oej/videocaps/main/config.c
    team/oej/videocaps/main/loader.c
    team/oej/videocaps/main/pbx.c
    team/oej/videocaps/main/rtp.c
    team/oej/videocaps/res/res_agi.c
    team/oej/videocaps/res/res_config_curl.c
    team/oej/videocaps/res/res_config_ldap.c
    team/oej/videocaps/res/res_musiconhold.c
    team/oej/videocaps/res/res_phoneprov.c
    team/oej/videocaps/utils/conf2ael.c

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

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

Propchange: team/oej/videocaps/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Feb 18 13:35:55 2008
@@ -1,1 +1,1 @@
-/trunk:1-103640
+/trunk:1-103781

Modified: team/oej/videocaps/CHANGES
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/CHANGES?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/CHANGES (original)
+++ team/oej/videocaps/CHANGES Mon Feb 18 13:35:55 2008
@@ -47,6 +47,7 @@
   * Added new action insert to add new variable to category at specified line.
   * Updated action newcat to allow new category to be inserted in file above another
     existing category.
+  * Added new event "JitterBufStats" in the IAX2 channel
 
 Dialplan functions
 ------------------
@@ -364,6 +365,7 @@
      direct options to the app.
   * AMD() has a new "maximum word length" option. "show application AMD" from the CLI
      for more details
+  * GotoIfTime() now may branch based on a "false" condition, like other Goto-related applications
 
 Music On Hold Changes
 ---------------------
@@ -512,3 +514,6 @@
      do not come from the remote party.
   * Added the 'n' option to the SpeechBackground application to tell it to not
      answer the channel if it has not already been answered.
+  * Added a compiler flag, CHANNEL_TRACE, which permits channel tracing to be
+     turned on, via the CHANNEL(trace) dialplan function.  Could be useful for
+     dialplan debugging.

Modified: team/oej/videocaps/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/UPGRADE.txt?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/UPGRADE.txt (original)
+++ team/oej/videocaps/UPGRADE.txt Mon Feb 18 13:35:55 2008
@@ -92,6 +92,11 @@
   you need to do so explicitly in your dialplan.
 * Privacy() no longer uses privacy.conf, so any options must be specified
   directly in the application arguments.
+* MusicOnHold application now has duration parameter which allows specifying
+  timeout in seconds.
+* WaitMusicOnHold application is now deprecated in favor of extended MusicOnHold.
+* SetMusicOnHold is now deprecated. You should use Set(CHANNEL(musicclass)=...)
+  instead.
 
 Dialplan Functions:
 
@@ -155,6 +160,9 @@
   lowcost and other is not acceptable now. Look into qos.tex for description of 
   this parameter.
 
+* queues.conf: the queue-lessthan sound file option is no longer available, and the
+  queue-round-seconds option no longer takes '1' as a valid parameter.
+
 Manager:
 
 * Manager has been upgraded to version 1.1 with a lot of changes. 

Modified: team/oej/videocaps/apps/app_channelredirect.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/apps/app_channelredirect.c?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/apps/app_channelredirect.c (original)
+++ team/oej/videocaps/apps/app_channelredirect.c Mon Feb 18 13:35:55 2008
@@ -72,7 +72,7 @@
 		return -1;
 	}
 
-	res = ast_parseable_goto(chan2, args.label);
+	res = ast_async_parseable_goto(chan2, args.label);
 
 	ast_channel_unlock(chan2);
 

Modified: team/oej/videocaps/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/apps/app_externalivr.c?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/apps/app_externalivr.c (original)
+++ team/oej/videocaps/apps/app_externalivr.c Mon Feb 18 13:35:55 2008
@@ -85,7 +85,11 @@
 	int sample_queue;
 };
 
-static void send_child_event(FILE *handle, const char event, const char *data,
+static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, 
+              int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, 
+              const char *args);
+
+static void send_eivr_event(FILE *handle, const char event, const char *data,
 	const struct ast_channel *chan)
 {
 	char tmp[256];
@@ -222,6 +226,63 @@
 	generate: gen_generate,
 };
 
+static void ast_eivr_getvariable(struct ast_channel *chan, char *data, char *outbuf, int outbuflen)
+{
+	/* original input data: "G,var1,var2," */
+	/* data passed as "data":  "var1,var2" */
+
+	char *inbuf, *variable;
+	const char *value;
+	int j;
+	struct ast_str *newstring = ast_str_alloca(outbuflen); 
+
+	outbuf[0] = '\0';
+
+	for (j = 1, inbuf = data; ; j++) {
+		variable = strsep(&inbuf, ",");
+		if (variable == NULL) {
+			int outstrlen = strlen(outbuf);
+			if(outstrlen && outbuf[outstrlen - 1] == ',') {
+				outbuf[outstrlen - 1] = 0;
+			}
+			break;
+		}
+		
+		value = pbx_builtin_getvar_helper(chan, variable);
+		if(!value)
+			value = "";
+		ast_str_append(&newstring, 0, "%s=%s,", variable, value);
+		ast_copy_string(outbuf, newstring->str, outbuflen);
+	}
+};
+
+static void ast_eivr_setvariable(struct ast_channel *chan, char *data)
+{
+	char buf[1024];
+	char *value;
+
+	char *inbuf, *variable;
+
+	int j;
+
+	for (j = 1, inbuf = data; ; j++, inbuf = NULL) {
+		variable = strsep(&inbuf, ",");
+		ast_chan_log(LOG_DEBUG, chan, "Setting up a variable: %s\n", variable);
+		if(variable) {
+			/* variable contains "varname=value" */
+			ast_copy_string(buf, variable, sizeof(buf));
+			value = strchr(buf, '=');
+			if(!value) 
+				value="";
+			else
+				*value++ = '\0';
+			pbx_builtin_setvar_helper(chan, buf, value);
+		}
+		else
+			break;
+	}
+};
+
 static struct playlist_entry *make_entry(const char *filename)
 {
 	struct playlist_entry *entry;
@@ -243,10 +304,7 @@
 	int res = -1;
 	int gen_active = 0;
 	int pid;
-	char *buf, *command;
-	FILE *child_commands = NULL;
-	FILE *child_errors = NULL;
-	FILE *child_events = NULL;
+	char *buf, *pipe_delim_argbuf, *pdargbuf_ptr;
 	struct ivr_localuser foo = {
 		.playlist = AST_LIST_HEAD_INIT_VALUE,
 		.finishlist = AST_LIST_HEAD_INIT_VALUE,
@@ -271,25 +329,26 @@
 	buf = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, buf);
 
+	/* copy args and replace commas with pipes */
+	pipe_delim_argbuf = ast_strdupa(data);
+	while((pdargbuf_ptr = strchr(pipe_delim_argbuf, ',')) != NULL)
+		pdargbuf_ptr[0] = '|';
+	
 	if (pipe(child_stdin)) {
 		ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno));
 		goto exit;
 	}
-
 	if (pipe(child_stdout)) {
 		ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child output: %s\n", strerror(errno));
 		goto exit;
 	}
-
 	if (pipe(child_stderr)) {
 		ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child errors: %s\n", strerror(errno));
 		goto exit;
 	}
-
 	if (chan->_state != AST_STATE_UP) {
 		ast_answer(chan);
 	}
-
 	if (ast_activate_generator(chan, &gen, u) < 0) {
 		ast_chan_log(LOG_WARNING, chan, "Failed to activate generator\n");
 		goto exit;
@@ -322,17 +381,6 @@
 		_exit(1);
 	} else {
 		/* parent process */
-		int child_events_fd = child_stdin[1];
-		int child_commands_fd = child_stdout[0];
-		int child_errors_fd = child_stderr[0];
-		struct ast_frame *f;
-		int ms;
-		int exception;
-		int ready_fd;
-		int waitfds[2] = { child_errors_fd, child_commands_fd };
-		struct ast_channel *rchan;
-
-		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 
 		close(child_stdin[0]);
 		child_stdin[0] = 0;
@@ -340,227 +388,263 @@
 		child_stdout[1] = 0;
 		close(child_stderr[1]);
 		child_stderr[1] = 0;
-
-		if (!(child_events = fdopen(child_events_fd, "w"))) {
-			ast_chan_log(LOG_WARNING, chan, "Could not open stream for child events\n");
-			goto exit;
-		}
-
-		if (!(child_commands = fdopen(child_commands_fd, "r"))) {
-			ast_chan_log(LOG_WARNING, chan, "Could not open stream for child commands\n");
-			goto exit;
-		}
-
-		if (!(child_errors = fdopen(child_errors_fd, "r"))) {
-			ast_chan_log(LOG_WARNING, chan, "Could not open stream for child errors\n");
-			goto exit;
-		}
-
-		setvbuf(child_events, NULL, _IONBF, 0);
-		setvbuf(child_commands, NULL, _IONBF, 0);
-		setvbuf(child_errors, NULL, _IONBF, 0);
-
-		res = 0;
-
-		while (1) {
-			if (ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
-				ast_chan_log(LOG_NOTICE, chan, "Is a zombie\n");
-				res = -1;
-				break;
-			}
-
-			if (ast_check_hangup(chan)) {
-				ast_chan_log(LOG_NOTICE, chan, "Got check_hangup\n");
-				send_child_event(child_events, 'H', NULL, chan);
-				res = -1;
-				break;
-			}
-
-			ready_fd = 0;
-			ms = 100;
-			errno = 0;
-			exception = 0;
-
-			rchan = ast_waitfor_nandfds(&chan, 1, waitfds, 2, &exception, &ready_fd, &ms);
-
-			if (!AST_LIST_EMPTY(&u->finishlist)) {
-				AST_LIST_LOCK(&u->finishlist);
-				while ((entry = AST_LIST_REMOVE_HEAD(&u->finishlist, list))) {
-					send_child_event(child_events, 'F', entry->filename, chan);
-					ast_free(entry);
-				}
-				AST_LIST_UNLOCK(&u->finishlist);
-			}
-
-			if (rchan) {
-				/* the channel has something */
-				f = ast_read(chan);
-				if (!f) {
-					ast_chan_log(LOG_NOTICE, chan, "Returned no frame\n");
-					send_child_event(child_events, 'H', NULL, chan);
-					res = -1;
-					break;
-				}
-
-				if (f->frametype == AST_FRAME_DTMF) {
-					send_child_event(child_events, f->subclass, NULL, chan);
-					if (u->option_autoclear) {
-						if (!u->abort_current_sound && !u->playing_silence)
-							send_child_event(child_events, 'T', NULL, chan);
-						AST_LIST_LOCK(&u->playlist);
-						while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
-							send_child_event(child_events, 'D', entry->filename, chan);
-							ast_free(entry);
-						}
-						if (!u->playing_silence)
-							u->abort_current_sound = 1;
-						AST_LIST_UNLOCK(&u->playlist);
-					}
-				} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
-					ast_chan_log(LOG_NOTICE, chan, "Got AST_CONTROL_HANGUP\n");
-					send_child_event(child_events, 'H', NULL, chan);
-					ast_frfree(f);
-					res = -1;
-					break;
-				}
-				ast_frfree(f);
-			} else if (ready_fd == child_commands_fd) {
-				char input[1024];
-
-				if (exception || feof(child_commands)) {
-					ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
-					res = -1;
-					break;
-				}
-
-				if (!fgets(input, sizeof(input), child_commands))
-					continue;
-
-				command = ast_strip(input);
-
-				if (option_debug)
-					ast_chan_log(LOG_DEBUG, chan, "got command '%s'\n", input);
-
-				if (strlen(input) < 4)
-					continue;
-
-				if (input[0] == 'S') {
-					if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
-						ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
-						send_child_event(child_events, 'Z', NULL, chan);
-						strcpy(&input[2], "exception");
-					}
-					if (!u->abort_current_sound && !u->playing_silence)
-						send_child_event(child_events, 'T', NULL, chan);
-					AST_LIST_LOCK(&u->playlist);
-					while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
-						send_child_event(child_events, 'D', entry->filename, chan);
-						ast_free(entry);
-					}
-					if (!u->playing_silence)
-						u->abort_current_sound = 1;
-					entry = make_entry(&input[2]);
-					if (entry)
-						AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
-					AST_LIST_UNLOCK(&u->playlist);
-				} else if (input[0] == 'A') {
-					if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
-						ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
-						send_child_event(child_events, 'Z', NULL, chan);
-						strcpy(&input[2], "exception");
-					}
-					entry = make_entry(&input[2]);
-					if (entry) {
-						AST_LIST_LOCK(&u->playlist);
-						AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
-						AST_LIST_UNLOCK(&u->playlist);
-					}
-				} else if (input[0] == 'E') {
-					ast_chan_log(LOG_NOTICE, chan, "Exiting: %s\n", &input[2]);
-					send_child_event(child_events, 'E', NULL, chan);
-					res = 0;
-					break;
-				} else if (input[0] == 'H') {
-					ast_chan_log(LOG_NOTICE, chan, "Hanging up: %s\n", &input[2]);
-					send_child_event(child_events, 'H', NULL, chan);
-					res = -1;
-					break;
-				} else if (input[0] == 'O') {
-					if (!strcasecmp(&input[2], "autoclear"))
-						u->option_autoclear = 1;
-					else if (!strcasecmp(&input[2], "noautoclear"))
-						u->option_autoclear = 0;
-					else
-						ast_chan_log(LOG_WARNING, chan, "Unknown option requested '%s'\n", &input[2]);
-				} else if (input[0] == 'V') {
-					char *c;
-					c = strchr(&input[2], '=');
-					if (!c) {
-						send_child_event(child_events, 'Z', NULL, chan);
-					} else {
-						*c++ = '\0';
-						pbx_builtin_setvar_helper(chan, &input[2], c);
-					}
-				}
-			} else if (ready_fd == child_errors_fd) {
-				char input[1024];
-
-				if (exception || feof(child_errors)) {
-					ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
-					res = -1;
-					break;
-				}
-
-				if (fgets(input, sizeof(input), child_errors)) {
-					command = ast_strip(input);
-					ast_chan_log(LOG_NOTICE, chan, "stderr: %s\n", command);
-				}
-			} else if ((ready_fd < 0) && ms) {
-				if (errno == 0 || errno == EINTR)
-					continue;
-
-				ast_chan_log(LOG_WARNING, chan, "Wait failed (%s)\n", strerror(errno));
-				break;
-			}
-		}
-	}
-
- exit:
-	if (gen_active)
-		ast_deactivate_generator(chan);
-
-	if (child_events)
-		fclose(child_events);
-
-	if (child_commands)
-		fclose(child_commands);
-
-	if (child_errors)
-		fclose(child_errors);
-
-	if (child_stdin[0])
-		close(child_stdin[0]);
-
-	if (child_stdin[1])
-		close(child_stdin[1]);
-
-	if (child_stdout[0])
-		close(child_stdout[0]);
-
-	if (child_stdout[1])
-		close(child_stdout[1]);
-
-	if (child_stderr[0])
-		close(child_stderr[0]);
-
-	if (child_stderr[1])
-		close(child_stderr[1]);
-
-	while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
-		ast_free(entry);
-
-	return res;
-}
+		res = eivr_comm(chan, u, child_stdin[1], child_stdout[0], child_stderr[0], pipe_delim_argbuf);
+
+		exit:
+		if (gen_active)
+			ast_deactivate_generator(chan);
+
+		if (child_stdin[0])
+			close(child_stdin[0]);
+
+		if (child_stdin[1])
+			close(child_stdin[1]);
+
+		if (child_stdout[0])
+			close(child_stdout[0]);
+
+		if (child_stdout[1])
+			close(child_stdout[1]);
+
+		if (child_stderr[0])
+			close(child_stderr[0]);
+
+		if (child_stderr[1])
+			close(child_stderr[1]);
+
+		while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
+			ast_free(entry);
+
+		return res;
+	}
+}
+
+static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, 
+ 				int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, 
+ 				const char *args)
+{
+	struct playlist_entry *entry;
+	struct ast_frame *f;
+	int ms;
+ 	int exception;
+ 	int ready_fd;
+ 	int waitfds[2] = { eivr_commands_fd, eivr_errors_fd };
+ 	struct ast_channel *rchan;
+ 	char *command;
+ 	int res = -1;
+  
+ 	FILE *eivr_commands = NULL;
+ 	FILE *eivr_errors = NULL;
+ 	FILE *eivr_events = NULL;
+ 
+ 	if (!(eivr_events = fdopen(eivr_events_fd, "w"))) {
+ 		ast_chan_log(LOG_WARNING, chan, "Could not open stream to send events\n");
+ 		goto exit;
+ 	}
+ 	if (!(eivr_commands = fdopen(eivr_commands_fd, "r"))) {
+ 		ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive commands\n");
+ 		goto exit;
+ 	}
+ 	if(eivr_errors_fd) {  /*if opening a socket connection, error stream will not be used*/
+ 		if (!(eivr_errors = fdopen(eivr_errors_fd, "r"))) {
+ 			ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive errors\n");
+ 			goto exit;
+ 		}
+ 	}
+ 
+ 	setvbuf(eivr_events, NULL, _IONBF, 0);
+ 	setvbuf(eivr_commands, NULL, _IONBF, 0);
+ 	if(eivr_errors)
+		setvbuf(eivr_errors, NULL, _IONBF, 0);
+
+	res = 0;
+ 
+ 	while (1) {
+ 		if (ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
+ 			ast_chan_log(LOG_NOTICE, chan, "Is a zombie\n");
+ 			res = -1;
+ 			break;
+ 		}
+ 		if (ast_check_hangup(chan)) {
+ 			ast_chan_log(LOG_NOTICE, chan, "Got check_hangup\n");
+ 			send_eivr_event(eivr_events, 'H', NULL, chan);
+ 			res = -1;
+ 			break;
+ 		}
+ 
+ 		ready_fd = 0;
+ 		ms = 100;
+ 		errno = 0;
+ 		exception = 0;
+ 
+ 		rchan = ast_waitfor_nandfds(&chan, 1, waitfds, 2, &exception, &ready_fd, &ms);
+ 
+ 		if (!AST_LIST_EMPTY(&u->finishlist)) {
+ 			AST_LIST_LOCK(&u->finishlist);
+ 			while ((entry = AST_LIST_REMOVE_HEAD(&u->finishlist, list))) {
+ 				send_eivr_event(eivr_events, 'F', entry->filename, chan);
+ 				ast_free(entry);
+ 			}
+ 			AST_LIST_UNLOCK(&u->finishlist);
+ 		}
+ 
+ 		if (rchan) {
+ 			/* the channel has something */
+ 			f = ast_read(chan);
+ 			if (!f) {
+ 				ast_chan_log(LOG_NOTICE, chan, "Returned no frame\n");
+ 				send_eivr_event(eivr_events, 'H', NULL, chan);
+ 				res = -1;
+ 				break;
+ 			}
+ 			if (f->frametype == AST_FRAME_DTMF) {
+ 				send_eivr_event(eivr_events, f->subclass, NULL, chan);
+ 				if (u->option_autoclear) {
+  					if (!u->abort_current_sound && !u->playing_silence)
+ 						send_eivr_event(eivr_events, 'T', NULL, chan);
+  					AST_LIST_LOCK(&u->playlist);
+  					while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
+ 						send_eivr_event(eivr_events, 'D', entry->filename, chan);
+  						ast_free(entry);
+  					}
+  					if (!u->playing_silence)
+  						u->abort_current_sound = 1;
+  					AST_LIST_UNLOCK(&u->playlist);
+  				}
+ 			} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
+ 				ast_chan_log(LOG_NOTICE, chan, "Got AST_CONTROL_HANGUP\n");
+ 				send_eivr_event(eivr_events, 'H', NULL, chan);
+ 				ast_frfree(f);
+ 				res = -1;
+ 				break;
+ 			}
+ 			ast_frfree(f);
+ 		} else if (ready_fd == eivr_commands_fd) {
+ 			char input[1024];
+ 
+ 			if (exception || feof(eivr_commands)) {
+ 				ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
+ 				res = -1;
+  				break;
+  			}
+  
+ 			if (!fgets(input, sizeof(input), eivr_commands))
+ 				continue;
+ 
+ 			command = ast_strip(input);
+  
+ 			if (option_debug)
+ 				ast_chan_log(LOG_DEBUG, chan, "got command '%s'\n", input);
+  
+ 			if (strlen(input) < 4)
+ 				continue;
+  
+			if (input[0] == 'P') {
+ 				send_eivr_event(eivr_events, 'P', args, chan);
+ 
+ 			} else if (input[0] == 'S') {
+ 				if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
+ 					ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
+ 					send_eivr_event(eivr_events, 'Z', NULL, chan);
+ 					strcpy(&input[2], "exception");
+ 				}
+ 				if (!u->abort_current_sound && !u->playing_silence)
+ 					send_eivr_event(eivr_events, 'T', NULL, chan);
+ 				AST_LIST_LOCK(&u->playlist);
+ 				while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
+ 					send_eivr_event(eivr_events, 'D', entry->filename, chan);
+ 					ast_free(entry);
+ 				}
+ 				if (!u->playing_silence)
+ 					u->abort_current_sound = 1;
+ 				entry = make_entry(&input[2]);
+ 				if (entry)
+ 					AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
+ 				AST_LIST_UNLOCK(&u->playlist);
+ 			} else if (input[0] == 'A') {
+ 				if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
+ 					ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
+ 					send_eivr_event(eivr_events, 'Z', NULL, chan);
+ 					strcpy(&input[2], "exception");
+ 				}
+ 				entry = make_entry(&input[2]);
+ 				if (entry) {
+ 					AST_LIST_LOCK(&u->playlist);
+ 					AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
+ 					AST_LIST_UNLOCK(&u->playlist);
+ 				}
+ 			} else if (input[0] == 'G') {
+ 				/* A get variable message:  "G,variable1,variable2,..." */
+ 				char response[2048];
+
+ 				ast_chan_log(LOG_NOTICE, chan, "Getting a Variable out of the channel: %s\n", &input[2]);
+ 				ast_eivr_getvariable(chan, &input[2], response, sizeof(response));
+ 				send_eivr_event(eivr_events, 'G', response, chan);
+ 			} else if (input[0] == 'V') {
+ 				/* A set variable message:  "V,variablename=foo" */
+ 				ast_chan_log(LOG_NOTICE, chan, "Setting a Variable up: %s\n", &input[2]);
+ 				ast_eivr_setvariable(chan, &input[2]);
+ 			} else if (input[0] == 'L') {
+ 				ast_chan_log(LOG_NOTICE, chan, "Log message from EIVR: %s\n", &input[2]);
+ 			} else if (input[0] == 'X') {
+ 				ast_chan_log(LOG_NOTICE, chan, "Exiting ExternalIVR: %s\n", &input[2]);
+ 				/*! \todo add deprecation debug message for X command here */
+ 				res = 0;
+ 				break;
+			} else if (input[0] == 'E') {
+ 				ast_chan_log(LOG_NOTICE, chan, "Exiting: %s\n", &input[2]);
+ 				send_eivr_event(eivr_events, 'E', NULL, chan);
+ 				res = 0;
+ 				break;
+ 			} else if (input[0] == 'H') {
+ 				ast_chan_log(LOG_NOTICE, chan, "Hanging up: %s\n", &input[2]);
+ 				send_eivr_event(eivr_events, 'H', NULL, chan);
+ 				res = -1;
+ 				break;
+ 			} else if (input[0] == 'O') {
+ 				if (!strcasecmp(&input[2], "autoclear"))
+ 					u->option_autoclear = 1;
+ 				else if (!strcasecmp(&input[2], "noautoclear"))
+ 					u->option_autoclear = 0;
+ 				else
+ 					ast_chan_log(LOG_WARNING, chan, "Unknown option requested '%s'\n", &input[2]);
+ 			}
+ 		} else if (eivr_errors_fd && ready_fd == eivr_errors_fd) {
+ 			char input[1024];
+  
+ 			if (exception || feof(eivr_errors)) {
+ 				ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
+ 				res = -1;
+ 				break;
+ 			}
+ 			if (fgets(input, sizeof(input), eivr_errors)) {
+ 				command = ast_strip(input);
+ 				ast_chan_log(LOG_NOTICE, chan, "stderr: %s\n", command);
+ 			}
+ 		} else if ((ready_fd < 0) && ms) { 
+ 			if (errno == 0 || errno == EINTR)
+ 				continue;
+ 
+ 			ast_chan_log(LOG_WARNING, chan, "Wait failed (%s)\n", strerror(errno));
+ 			break;
+ 		}
+ 	}
+  
+ 
+exit:
+ 
+ 	if (eivr_events)
+ 		fclose(eivr_events);
+ 
+ 	if (eivr_commands)
+		fclose(eivr_commands);
+
+ 	if (eivr_errors)
+ 		fclose(eivr_errors);
+  
+  	return res;
+ 
+  }
 
 static int unload_module(void)
 {

Modified: team/oej/videocaps/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/apps/app_queue.c?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/apps/app_queue.c (original)
+++ team/oej/videocaps/apps/app_queue.c Mon Feb 18 13:35:55 2008
@@ -431,8 +431,8 @@
 		AST_STRING_FIELD(sound_holdtime);
 		/*! Sound file: "minutes." (def. queue-minutes) */
 		AST_STRING_FIELD(sound_minutes);
-		/*! Sound file: "less-than" (def. queue-lessthan) */
-		AST_STRING_FIELD(sound_lessthan);
+		/*! Sound file: "minute." (def. queue-minute) */
+		AST_STRING_FIELD(sound_minute);
 		/*! Sound file: "seconds." (def. queue-seconds) */
 		AST_STRING_FIELD(sound_seconds);
 		/*! Sound file: "Thank you for your patience." (def. queue-thankyou) */
@@ -939,9 +939,9 @@
 	ast_string_field_set(q, sound_calls, "queue-callswaiting");
 	ast_string_field_set(q, sound_holdtime, "queue-holdtime");
 	ast_string_field_set(q, sound_minutes, "queue-minutes");
+	ast_string_field_set(q, sound_minute, "queue-minute");
 	ast_string_field_set(q, sound_seconds, "queue-seconds");
 	ast_string_field_set(q, sound_thanks, "queue-thankyou");
-	ast_string_field_set(q, sound_lessthan, "queue-less-than");
 	ast_string_field_set(q, sound_reporthold, "queue-reporthold");
 
 	if ((q->sound_periodicannounce[0] = ast_str_create(32)))
@@ -1165,10 +1165,10 @@
 		ast_string_field_set(q, sound_holdtime, val);
 	} else if (!strcasecmp(param, "queue-minutes")) {
 		ast_string_field_set(q, sound_minutes, val);
+	} else if (!strcasecmp(param, "queue-minute")) {
+		ast_string_field_set(q, sound_minute, val);
 	} else if (!strcasecmp(param, "queue-seconds")) {
 		ast_string_field_set(q, sound_seconds, val);
-	} else if (!strcasecmp(param, "queue-lessthan")) {
-		ast_string_field_set(q, sound_lessthan, val);
 	} else if (!strcasecmp(param, "queue-thankyou")) {
 		ast_string_field_set(q, sound_thanks, val);
 	} else if (!strcasecmp(param, "queue-callerannounce")) {
@@ -1183,7 +1183,7 @@
 	} else if (!strcasecmp(param, "announce-round-seconds")) {
 		q->roundingseconds = atoi(val);
 		/* Rounding to any other values just doesn't make sense... */
-		if (!(q->roundingseconds == 0 || q->roundingseconds == 1 || q->roundingseconds == 5 || q->roundingseconds == 10
+		if (!(q->roundingseconds == 0 || q->roundingseconds == 5 || q->roundingseconds == 10
 			|| q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
 			if (linenum >= 0) {
 				ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
@@ -1791,7 +1791,7 @@
 		avgholdsecs = 0;
 	}
 
-	ast_verb(3, "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
+	ast_verb(3, "Hold time for %s is %d minute(s) %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
 
 	/* If the hold time is >1 min, if it's enabled, and if it's not
 	   supposed to be only once and we have already said it, say it */
@@ -1801,27 +1801,23 @@
 		if (res)
 			goto playout;
 
-		if (avgholdmins > 0) {
-			if (avgholdmins < 2) {
-				res = play_file(qe->chan, qe->parent->sound_lessthan);
-				if (res)
-					goto playout;
-
-				res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
+		if (avgholdmins > 1) {
+			res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
+			if (res)
+				goto playout;
+
+			if (avgholdmins == 1) {
+				res = play_file(qe->chan, qe->parent->sound_minute);
 				if (res)
 					goto playout;
 			} else {
-				res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
+				res = play_file(qe->chan, qe->parent->sound_minutes);
 				if (res)
 					goto playout;
 			}
-			
-			res = play_file(qe->chan, qe->parent->sound_minutes);
-			if (res)
-				goto playout;
-		}
-		if (avgholdsecs>0) {
-			res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
+		}
+		if (avgholdsecs > 1) {
+			res = ast_say_number(qe->chan, avgholdmins > 1 ? avgholdsecs : avgholdmins * 60 + avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
 			if (res)
 				goto playout;
 
@@ -2979,6 +2975,7 @@
  *
  * \param[in] qe the queue_ent structure which corresponds to the caller attempting to reach members
  * \param[in] options the options passed as the third parameter to the Queue() application
+ * \param[in] announceoverride filename to play to user when waiting 
  * \param[in] url the url passed as the fourth parameter to the Queue() application
  * \param[in,out] tries the number of times we have tried calling queue members
  * \param[out] noption set if the call to Queue() has the 'n' option set.
@@ -3262,16 +3259,22 @@
 				}
 				if (!res2 && qe->parent->reportholdtime) {
 					if (!play_file(peer, qe->parent->sound_reporthold)) {
-						int holdtime;
+						int holdtime, holdtimesecs;
 
 						time(&now);
 						holdtime = abs((now - qe->start) / 60);
-						if (holdtime < 2) {
-							play_file(peer, qe->parent->sound_lessthan);
-							ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
-						} else
+						holdtimesecs = abs((now - qe->start));
+						if (holdtime == 1) {
 							ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
-						play_file(peer, qe->parent->sound_minutes);
+							play_file(peer, qe->parent->sound_minute);
+						} else {
+							ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
+							play_file(peer, qe->parent->sound_minutes);
+						}
+						if (holdtimesecs > 1) {
+							ast_say_number(peer, holdtimesecs, AST_DIGIT_ANY, peer->language, NULL);
+							play_file(peer, qe->parent->sound_seconds);
+						}
 					}
 				}
 			}
@@ -4275,7 +4278,7 @@
  * 4. Attempt to call a queue member
  * 5. If 4. did not result in a bridged call, then check for between
  *    call options such as periodic announcements etc.
- * 6. Try 4 again uless some condition (such as an expiration time) causes us to 
+ * 6. Try 4 again unless some condition (such as an expiration time) causes us to 
  *    exit the queue.
  */
 static int queue_exec(struct ast_channel *chan, void *data)

Modified: team/oej/videocaps/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/apps/app_voicemail.c?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/apps/app_voicemail.c (original)
+++ team/oej/videocaps/apps/app_voicemail.c Mon Feb 18 13:35:55 2008
@@ -427,7 +427,6 @@
 #endif
 };
 
-
 #ifdef ODBC_STORAGE
 static char odbc_database[80];
 static char odbc_table[80];
@@ -662,7 +661,7 @@
 			signed char record_gain, struct vm_state *vms);
 static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain);
 static int vm_play_folder_name(struct ast_channel *chan, char *mbox);
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
+static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
 static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap);
 static void apply_options(struct ast_vm_user *vmu, const char *options);
 static int is_valid_dtmf(const char *key);
@@ -2841,7 +2840,7 @@
 		ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
 	}
 	ast_unlock_path(todir);
-	notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
+	notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
 	
 	return 0;
 }
@@ -3403,7 +3402,11 @@
 					}
 					/* Notification and disposal needs to happen after the copy, though. */
 					if (ast_fileexists(fn, NULL, NULL)) {
-						notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
+#ifdef IMAP_STORAGE
+						notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
+#else
+						notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
+#endif
 						DISPOSE(dir, msgnum);
 					}
 				}
@@ -4183,7 +4186,7 @@
 		AST_EVENT_IE_END);
 }
 
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
+static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
 {
 	char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
 	int newmsgs = 0, oldmsgs = 0;
@@ -4230,9 +4233,6 @@
 	if (ast_test_flag(vmu, VM_DELETE))
 		DELETE(todir, msgnum, fn);
 
-#ifdef IMAP_STORAGE
-	DELETE(todir, msgnum, fn);
-#endif
 	/* Leave voicemail for someone */
 	if (ast_app_has_voicemail(ext_context, NULL)) 
 		ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
@@ -4241,6 +4241,14 @@
 
 	manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
 	run_externnotify(vmu->context, vmu->mailbox);
+
+#ifdef IMAP_STORAGE
+	DELETE(todir, msgnum, fn);  /* Delete the file, but not the IMAP message */
+	if (ast_test_flag(vmu, VM_DELETE))  { /* Delete the IMAP message if delete = yes */
+		IMAP_DELETE(vms->curdir, vms->curmsg, vms->fn, vms);
+		vms->newmessages--;  /* Fix new message count */
+	}
+#endif
 	return 0;
 }
 
@@ -4414,12 +4422,6 @@
 		long duration = 0;
 		char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
 		struct vm_state vmstmp;
-#ifdef IMAP_STORAGE
-		char *myserveremail = serveremail;
-		char buf[1024] = "";
-		int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
-#endif
-
 		memcpy(&vmstmp, vms, sizeof(vmstmp));
 
 		make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
@@ -4435,8 +4437,9 @@
 		if (!cmd) {
 			AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
 #ifdef IMAP_STORAGE
-				char *myserveremail;
+				char *myserveremail = serveremail;
 				int attach_user_voicemail;
+				char buf[1024] = "";
 
  				/* Need to get message content */
 	 			ast_debug(3, "Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n", vms->curmsg, vms->msgArray[vms->curmsg]);

Modified: team/oej/videocaps/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/build_tools/cflags.xml?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/build_tools/cflags.xml (original)
+++ team/oej/videocaps/build_tools/cflags.xml Mon Feb 18 13:35:55 2008
@@ -59,4 +59,6 @@
 		<member name="BUSYDETECT_DEBUG" displayname="Enable additional busy detection debugging">
 			<defaultenabled>no</defaultenabled>
 		</member>
+		<member name="CHANNEL_TRACE" displayname="Enable CHANNEL(trace) function">
+		</member>
 	</category>

Modified: team/oej/videocaps/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/channels/chan_iax2.c?view=diff&rev=103782&r1=103781&r2=103782
==============================================================================
--- team/oej/videocaps/channels/chan_iax2.c (original)
+++ team/oej/videocaps/channels/chan_iax2.c Mon Feb 18 13:35:55 2008
@@ -2784,7 +2784,9 @@
 	int type, len;
 	int ret;
 	int needfree = 0;
-
+	struct ast_channel *owner = NULL;
+	struct ast_channel *bridge = NULL;
+	
 	/* Attempt to recover wrapped timestamps */
 	unwrap_timestamp(fr);
 
@@ -2815,11 +2817,12 @@
 		return -1;
 	}
 
+	if ((owner = iaxs[fr->callno]->owner))
+		bridge = ast_bridged_channel(owner);
+
 	/* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
 	 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
-	if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
-	    iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
-	    (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
+	if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
 		jb_frame frame;
 
 		/* deliver any frames in the jb */
@@ -7298,6 +7301,61 @@
 	}
 
 	ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
+}
+
+static void log_jitterstats(unsigned short callno)
+{
+	int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
+	jb_info jbinfo;
+
+	ast_mutex_lock(&iaxsl[callno]);
+	if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
+		if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
+			jb_getinfo(iaxs[callno]->jb, &jbinfo);
+			localjitter = jbinfo.jitter;
+			localdelay = jbinfo.current - jbinfo.min;
+			locallost = jbinfo.frames_lost;
+			locallosspct = jbinfo.losspct/1000;
+			localdropped = jbinfo.frames_dropped;
+			localooo = jbinfo.frames_ooo;
+			localpackets = jbinfo.frames_in;
+		}
+		ast_verb(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
+			iaxs[callno]->owner->name,
+			iaxs[callno]->pingtime,
+			localjitter,
+			localdelay,
+			locallost,
+			locallosspct,
+			localdropped,
+			localooo,
+			localpackets,
+			iaxs[callno]->remote_rr.jitter,
+			iaxs[callno]->remote_rr.delay,
+			iaxs[callno]->remote_rr.losscnt,
+			iaxs[callno]->remote_rr.losspct/1000,
+			iaxs[callno]->remote_rr.dropped,
+			iaxs[callno]->remote_rr.ooo,
+			iaxs[callno]->remote_rr.packets);
+		manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\t\nLocalTotalLost: %d LocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
+			iaxs[callno]->owner->name,
+			iaxs[callno]->pingtime,
+			localjitter,
+			localdelay,
+			locallost,
+			locallosspct,
+			localdropped,
+			localooo,
+			localpackets,
+			iaxs[callno]->remote_rr.jitter,
+			iaxs[callno]->remote_rr.delay,
+			iaxs[callno]->remote_rr.losscnt,
+			iaxs[callno]->remote_rr.losspct/1000,
+			iaxs[callno]->remote_rr.dropped,
+			iaxs[callno]->remote_rr.ooo,
+			iaxs[callno]->remote_rr.packets);
+	}
+	ast_mutex_unlock(&iaxsl[callno]);
 }
 
 static int socket_process(struct iax2_thread *thread);
@@ -8463,6 +8521,9 @@
 				iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
 				/* save RR info */
 				save_rr(fr, &ies);
+
+				/* Good time to write jb stats for this call */
+				log_jitterstats(fr->callno);
 
 				if (iaxs[fr->callno]->peerpoke) {
 					peer = iaxs[fr->callno]->peerpoke;

Modified: team/oej/videocaps/channels/chan_sip.c

[... 2476 lines stripped ...]



More information about the svn-commits mailing list