[asterisk-commits] kpfleming: branch kpfleming/multimodule-build r103664 - in /team/kpfleming/mu...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Feb 13 16:02:19 CST 2008


Author: kpfleming
Date: Wed Feb 13 16:02:19 2008
New Revision: 103664

URL: http://svn.digium.com/view/asterisk?view=rev&rev=103664
Log:
update to current trunk

Modified:
    team/kpfleming/multimodule-build/   (props changed)
    team/kpfleming/multimodule-build/UPGRADE.txt
    team/kpfleming/multimodule-build/apps/app_externalivr.c
    team/kpfleming/multimodule-build/main/event.c
    team/kpfleming/multimodule-build/res/res_musiconhold.c

Propchange: team/kpfleming/multimodule-build/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/kpfleming/multimodule-build/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Feb 13 16:02:19 2008
@@ -1,1 +1,1 @@
-/trunk:1-103503
+/trunk:1-103663

Modified: team/kpfleming/multimodule-build/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/kpfleming/multimodule-build/UPGRADE.txt?view=diff&rev=103664&r1=103663&r2=103664
==============================================================================
--- team/kpfleming/multimodule-build/UPGRADE.txt (original)
+++ team/kpfleming/multimodule-build/UPGRADE.txt Wed Feb 13 16:02:19 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:
 

Modified: team/kpfleming/multimodule-build/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/multimodule-build/apps/app_externalivr.c?view=diff&rev=103664&r1=103663&r2=103664
==============================================================================
--- team/kpfleming/multimodule-build/apps/app_externalivr.c (original)
+++ team/kpfleming/multimodule-build/apps/app_externalivr.c Wed Feb 13 16:02:19 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,69 @@
 	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;
+	char *saveptr;
+	int j;
+
+	outbuf[0] = 0;
+
+	for (j = 1, inbuf = data; ; j++, inbuf = NULL) {
+		variable = strtok_r(inbuf, ",", &saveptr);
+		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 = "";
+		strncat(outbuf,variable,outbuflen);
+		strncat(outbuf,"=",outbuflen);
+		strncat(outbuf,value,outbuflen);
+		strncat(outbuf,",",outbuflen);
+	}
+};
+
+static void ast_eivr_setvariable(struct ast_channel *chan, char *data)
+{
+	char buf[1024];
+	char *value;
+
+	char *inbuf, *variable;
+
+	char *saveptr;
+	int j;
+
+	for(j=1, inbuf=data; ; j++, inbuf=NULL) {
+		variable = strtok_r(inbuf, ",", &saveptr);
+		ast_chan_log(LOG_DEBUG, chan, "Setting up a variable: %s\n", variable);
+		if(variable) {
+			//variable contains "varname=value"
+			strncpy(buf, variable, sizeof(buf));
+			value = strchr(buf, '=');
+			if(!value) 
+				value="";
+			else {
+				value[0] = 0;
+				value++;
+			}
+			pbx_builtin_setvar_helper(chan, buf, value);
+		}
+		else break;
+
+	}
+
+};
+
 static struct playlist_entry *make_entry(const char *filename)
 {
 	struct playlist_entry *entry;
@@ -243,10 +310,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 +335,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 +387,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 +394,262 @@
 		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/kpfleming/multimodule-build/main/event.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/multimodule-build/main/event.c?view=diff&rev=103664&r1=103663&r2=103664
==============================================================================
--- team/kpfleming/multimodule-build/main/event.c (original)
+++ team/kpfleming/multimodule-build/main/event.c Wed Feb 13 16:02:19 2008
@@ -383,7 +383,7 @@
 int ast_event_iterator_next(struct ast_event_iterator *iterator)
 {
 	iterator->ie = (struct ast_event_ie *) ( ((char *) iterator->ie) + sizeof(*iterator->ie) + ntohs(iterator->ie->ie_payload_len));
-	return ((iterator->event_len < (((char *) iterator->ie) - ((char *) iterator->event))) ? -1 : 0);
+	return ((iterator->event_len <= (((char *) iterator->ie) - ((char *) iterator->event))) ? -1 : 0);
 }
 
 enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator)

Modified: team/kpfleming/multimodule-build/res/res_musiconhold.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/multimodule-build/res/res_musiconhold.c?view=diff&rev=103664&r1=103663&r2=103664
==============================================================================
--- team/kpfleming/multimodule-build/res/res_musiconhold.c (original)
+++ team/kpfleming/multimodule-build/res/res_musiconhold.c Wed Feb 13 16:02:19 2008
@@ -52,6 +52,7 @@
 #include "asterisk/file.h"
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
+#include "asterisk/app.h"
 #include "asterisk/module.h"
 #include "asterisk/translate.h"
 #include "asterisk/say.h"
@@ -76,22 +77,33 @@
 static char *start_moh_syn = "Play Music On Hold";
 static char *stop_moh_syn = "Stop Playing Music On Hold";
 
-static char *play_moh_desc = "  MusicOnHold(class):\n"
+static char *play_moh_desc = "  MusicOnHold(class[,duration]):\n"
 "Plays hold music specified by class.  If omitted, the default\n"
-"music source for the channel will be used. Set the default \n"
-"class with the SetMusicOnHold() application.\n"
-"Returns -1 on hangup.\n"
-"Never returns otherwise.\n";
+"music source for the channel will be used. Change the default \n"
+"class with Set(CHANNEL(musicclass)=...).\n"
+"If duration is given, hold music will be played specified number\n"
+"of seconds. If duration is ommited, music plays indefinitely.\n"
+"Returns 0 when done, -1 on hangup.\n";
 
 static char *wait_moh_desc = "  WaitMusicOnHold(delay):\n"
+"\n"
+"  !!! DEPRECATED. Use MusicOnHold instead !!!\n"
+"\n"
 "Plays hold music specified number of seconds.  Returns 0 when\n"
 "done, or -1 on hangup.  If no hold music is available, the delay will\n"
-"still occur with no sound.\n";
+"still occur with no sound.\n"
+"\n"
+"  !!! DEPRECATED. Use MusicOnHold instead !!!\n";
 
 static char *set_moh_desc = "  SetMusicOnHold(class):\n"
+"\n"
+"  !!! DEPRECATED. USe Set(CHANNEL(musicclass)=...) instead !!!\n"
+"\n"
 "Sets the default class for music on hold for a given channel.  When\n"
 "music on hold is activated, this class will be used to select which\n"
-"music is played.\n";
+"music is played.\n"
+"\n"
+"  !!! DEPRECATED. USe Set(CHANNEL(musicclass)=...) instead !!!\n";
 
 static char *start_moh_desc = "  StartMusicOnHold(class):\n"
 "Starts playing music on hold, uses default music class for channel.\n"
@@ -610,18 +622,54 @@
 
 static int play_moh_exec(struct ast_channel *chan, void *data)
 {
-	if (ast_moh_start(chan, data, NULL)) {
-		ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name);
+	char *parse;
+	char *class;
+	int timeout = -1;
+	int res;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(class);
+		AST_APP_ARG(duration);
+	);
+
+	parse = ast_strdupa(data);
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (!ast_strlen_zero(args.duration)) {
+		if (sscanf(args.duration, "%d", &timeout) == 1) {
+			timeout *= 1000;
+		} else {
+			ast_log(LOG_WARNING, "Invalid MusicOnHold duration '%s'. Will wait indefinitely.\n", args.duration);
+		}
+	}
+
+	class = S_OR(args.class, NULL);
+	if (ast_moh_start(chan, class, NULL)) {
+		ast_log(LOG_WARNING, "Unable to start music on hold class '%s' on channel %s\n", class, chan->name);
 		return 0;
 	}
-	while (!ast_safe_sleep(chan, 10000));
+
+	if (timeout > 0)
+		res = ast_safe_sleep(chan, timeout);
+	else {
+		while (!(res = ast_safe_sleep(chan, 10000)));
+	}
+
 	ast_moh_stop(chan);
-	return -1;
+
+	return res;
 }
 
 static int wait_moh_exec(struct ast_channel *chan, void *data)
 {
+	static int deprecation_warning = 0;
 	int res;
+
+	if (!deprecation_warning) {
+		deprecation_warning = 1;
+		ast_log(LOG_WARNING, "WaitMusicOnHold application is deprecated and will be removed. Use MusicOnHold with duration parameter instead\n");
+	}
+
 	if (!data || !atoi(data)) {
 		ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n");
 		return -1;
@@ -637,6 +685,13 @@
 
 static int set_moh_exec(struct ast_channel *chan, void *data)
 {
+	static int deprecation_warning = 0;
+
+	if (!deprecation_warning) {
+		deprecation_warning = 1;
+		ast_log(LOG_WARNING, "SetMusicOnHold application is deprecated and will be removed. Use Set(CHANNEL(musicclass)=...) instead\n");
+	}
+
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "SetMusicOnHold requires an argument (class)\n");
 		return -1;
@@ -647,11 +702,19 @@
 
 static int start_moh_exec(struct ast_channel *chan, void *data)
 {
-	char *class = NULL;
-	if (data && strlen(data))
-		class = data;
+	char *parse;
+	char *class;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(class);
+	);
+
+	parse = ast_strdupa(data);
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	class = S_OR(args.class, NULL);
 	if (ast_moh_start(chan, class, NULL)) 
-		ast_log(LOG_NOTICE, "Unable to start music on hold class '%s' on channel %s\n", class ? class : "default", chan->name);
+		ast_log(LOG_WARNING, "Unable to start music on hold class '%s' on channel %s\n", class, chan->name);
 
 	return 0;
 }




More information about the asterisk-commits mailing list