[asterisk-commits] russell: branch russell/chan_refcount r104010 - in /team/russell/chan_refcoun...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 20 18:01:43 CST 2008
Author: russell
Date: Wed Feb 20 18:01:29 2008
New Revision: 104010
URL: http://svn.digium.com/view/asterisk?view=rev&rev=104010
Log:
resolve, reset
Modified:
team/russell/chan_refcount/ (props changed)
team/russell/chan_refcount/CHANGES
team/russell/chan_refcount/UPGRADE.txt
team/russell/chan_refcount/apps/app_authenticate.c
team/russell/chan_refcount/apps/app_channelredirect.c
team/russell/chan_refcount/apps/app_externalivr.c
team/russell/chan_refcount/apps/app_queue.c
team/russell/chan_refcount/apps/app_voicemail.c
team/russell/chan_refcount/build_tools/cflags.xml
team/russell/chan_refcount/channels/chan_h323.c
team/russell/chan_refcount/channels/chan_iax2.c
team/russell/chan_refcount/channels/chan_local.c
team/russell/chan_refcount/channels/chan_sip.c
team/russell/chan_refcount/channels/chan_skinny.c
team/russell/chan_refcount/channels/chan_zap.c
team/russell/chan_refcount/channels/h323/ast_h323.cxx
team/russell/chan_refcount/channels/misdn/chan_misdn_config.h
team/russell/chan_refcount/channels/misdn/ie.c
team/russell/chan_refcount/channels/misdn/isdn_lib.c
team/russell/chan_refcount/channels/misdn/isdn_lib.h
team/russell/chan_refcount/channels/misdn/isdn_msg_parser.c
team/russell/chan_refcount/channels/misdn/portinfo.c
team/russell/chan_refcount/configs/queues.conf.sample
team/russell/chan_refcount/configure
team/russell/chan_refcount/configure.ac
team/russell/chan_refcount/doc/tex/imapstorage.tex
team/russell/chan_refcount/funcs/func_cdr.c
team/russell/chan_refcount/funcs/func_channel.c
team/russell/chan_refcount/include/asterisk/aes.h
team/russell/chan_refcount/include/asterisk/autoconfig.h.in
team/russell/chan_refcount/include/asterisk/channel.h
team/russell/chan_refcount/include/asterisk/dsp.h
team/russell/chan_refcount/include/asterisk/extconf.h
team/russell/chan_refcount/include/asterisk/frame.h
team/russell/chan_refcount/include/asterisk/pbx.h
team/russell/chan_refcount/include/asterisk/sched.h
team/russell/chan_refcount/include/asterisk/strings.h
team/russell/chan_refcount/include/asterisk/time.h
team/russell/chan_refcount/main/app.c
team/russell/chan_refcount/main/ast_expr2f.c
team/russell/chan_refcount/main/asterisk.c
team/russell/chan_refcount/main/audiohook.c
team/russell/chan_refcount/main/channel.c
team/russell/chan_refcount/main/cli.c
team/russell/chan_refcount/main/config.c
team/russell/chan_refcount/main/dsp.c
team/russell/chan_refcount/main/file.c
team/russell/chan_refcount/main/frame.c
team/russell/chan_refcount/main/loader.c
team/russell/chan_refcount/main/pbx.c
team/russell/chan_refcount/main/rtp.c
team/russell/chan_refcount/main/say.c
team/russell/chan_refcount/main/stdtime/localtime.c
team/russell/chan_refcount/res/res_agi.c
team/russell/chan_refcount/res/res_config_curl.c
team/russell/chan_refcount/res/res_config_ldap.c
team/russell/chan_refcount/res/res_monitor.c
team/russell/chan_refcount/res/res_musiconhold.c
team/russell/chan_refcount/res/res_phoneprov.c
team/russell/chan_refcount/utils/conf2ael.c
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
automerge = *
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Feb 20 18:01:29 2008
@@ -1,1 +1,1 @@
-/trunk:1-103647
+/trunk:1-104009
Modified: team/russell/chan_refcount/CHANGES
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/CHANGES?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/CHANGES (original)
+++ team/russell/chan_refcount/CHANGES Wed Feb 20 18:01:29 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,10 @@
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
+ * The ChannelRedirect application no longer exits the dialplan if the given channel
+ does not exist. It will now set the CHANNELREDIRECT_STATUS variable to SUCCESS upon success
+ or NOCHANNEL if the given channel was not found.
Music On Hold Changes
---------------------
@@ -512,3 +517,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/russell/chan_refcount/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/UPGRADE.txt?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/UPGRADE.txt (original)
+++ team/russell/chan_refcount/UPGRADE.txt Wed Feb 20 18:01:29 2008
@@ -77,6 +77,9 @@
* ChanIsAvail() now has a 't' option, which allows the specified device
to be queried for state without consulting the channel drivers. This
performs mostly a 'ChanExists' sort of function.
+* ChannelRedirect() will not terminate the channel that fails to do a
+ channelredirect as it has done previously. Instead CHANNELREDIRECT_STATUS
+ will reflect if the attempt was successful of not.
* SetCallerPres() has been replaced with the CALLERPRES() dialplan function
and is now deprecated.
* DISA()'s fifth argument is now an options argument. If you have previously
@@ -92,6 +95,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 +163,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/russell/chan_refcount/apps/app_authenticate.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/apps/app_authenticate.c?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/apps/app_authenticate.c (original)
+++ team/russell/chan_refcount/apps/app_authenticate.c Wed Feb 20 18:01:29 2008
@@ -159,8 +159,8 @@
continue;
len = strlen(buf) - 1;
- if (buf[len - 1] == '\n')
- buf[len - 1] = '\0';
+ if (buf[len] == '\n')
+ buf[len] = '\0';
if (ast_test_flag(&flags, OPT_MULTIPLE)) {
md5secret = buf;
Modified: team/russell/chan_refcount/apps/app_channelredirect.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/apps/app_channelredirect.c?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/apps/app_channelredirect.c (original)
+++ team/russell/chan_refcount/apps/app_channelredirect.c Wed Feb 20 18:01:29 2008
@@ -39,8 +39,10 @@
static char *synopsis = "Redirects given channel to a dialplan target.";
static char *descrip =
"ChannelRedirect(channel,[[context,]extension,]priority)\n"
-" Sends the specified channel to the specified extension priority\n";
-
+" Sends the specified channel to the specified extension priority\n"
+"This application sets the following channel variables upon completion:\n"
+" CHANNELREDIRECT_STATUS - Are set to the result of the redirection\n"
+" either NOCHANNEL or SUCCESS\n";
static int asyncgoto_exec(struct ast_channel *chan, void *data)
{
@@ -69,11 +71,12 @@
chan2 = ast_channel_get_by_name(args.channel);
if (!chan2) {
ast_log(LOG_WARNING, "No such channel: %s\n", args.channel);
- return -1;
+ pbx_builtin_setvar_helper(chan, "CHANNELREDIRECT_STATUS", "NOCHANNEL");
+ return 0;
}
- res = ast_parseable_goto(chan2, args.label);
-
+ res = ast_async_parseable_goto(chan2, args.label);
+ pbx_builtin_setvar_helper(chan, "CHANNELREDIRECT_STATUS", "SUCCESS");
ast_channel_unref(chan2);
return res;
Modified: team/russell/chan_refcount/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/apps/app_externalivr.c?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/apps/app_externalivr.c (original)
+++ team/russell/chan_refcount/apps/app_externalivr.c Wed Feb 20 18:01:29 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/russell/chan_refcount/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/apps/app_queue.c?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/apps/app_queue.c (original)
+++ team/russell/chan_refcount/apps/app_queue.c Wed Feb 20 18:01:29 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)
@@ -4685,6 +4688,7 @@
struct call_queue *q, tmpq = {
.name = data,
};
+ struct ast_variable *var = NULL;
buf[0] = '\0';
@@ -4698,6 +4702,13 @@
count = q->count;
ao2_unlock(q);
queue_unref(q);
+ } else if ((var = ast_load_realtime("queues", "name", data, NULL))) {
+ /* if the queue is realtime but was not found in memory, this
+ * means that the queue had been deleted from memory since it was
+ * "dead." This means it has a 0 waiting count
+ */
+ count = 0;
+ ast_variables_destroy(var);
} else
ast_log(LOG_WARNING, "queue %s was not found\n", data);
Modified: team/russell/chan_refcount/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/apps/app_voicemail.c?view=diff&rev=104010&r1=104009&r2=104010
==============================================================================
--- team/russell/chan_refcount/apps/app_voicemail.c (original)
+++ team/russell/chan_refcount/apps/app_voicemail.c Wed Feb 20 18:01:29 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);
@@ -2828,7 +2827,7 @@
ast_copy_string(fromdir, dir, sizeof(fromdir));
make_file(frompath, sizeof(frompath), fromdir, msgnum);
- make_dir(todir, sizeof(todir), recip->context, recip->mailbox, frombox);
+ make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
if (vm_lock_path(todir))
return ERROR_LOCK_PATH;
@@ -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);
}
}
@@ -3471,11 +3474,20 @@
/* simple. huh? */
long res;
char sequence[10];
+ char mailbox[256];
/* if save to Old folder, just leave in INBOX */
if (box == 1) return 10;
/* get the real IMAP message number for this message */
snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
+ /* Create the folder if it don't exist */
+ imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */
+ ast_debug(5, "Checking if folder exists: %s\n",mailbox);
+ if (mail_create(vms->mailstream, mailbox) == NIL)
+ ast_debug(5, "Folder exists.\n");
+ else
+ ast_log(LOG_NOTICE, "Folder %s created!\n",mbox(box));
+
ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(box));
res = mail_copy(vms->mailstream, sequence, (char *)mbox(box));
if (res == 1) return 0;
@@ -4183,7 +4195,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 +4242,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 +4250,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);
[... 6716 lines stripped ...]
More information about the asterisk-commits
mailing list