[asterisk-commits] oej: branch group/pinequeue r297487 - in /team/group/pinequeue: apps/ configs...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Dec 2 15:46:49 CST 2010
Author: oej
Date: Thu Dec 2 15:46:42 2010
New Revision: 297487
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=297487
Log:
- Removing bad attempt to play files in background thread
Might need more cleaning up
- Adding generator-assisted playing inspired from app_externalivr
- Adding configuration setting to enable/disable background prompts
- Cleaning up quite a lot, more cleaning needed
This code actually plays prompts until an agent becomes available
if background_prompts is enabled. When the agent is available,
any prompt will be interrupted and the call will be connected.
Modified:
team/group/pinequeue/apps/app_queue.c
team/group/pinequeue/configs/queues.conf.sample
team/group/pinequeue/include/asterisk/channel.h
team/group/pinequeue/main/file.c
Modified: team/group/pinequeue/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinequeue/apps/app_queue.c?view=diff&rev=297487&r1=297486&r2=297487
==============================================================================
--- team/group/pinequeue/apps/app_queue.c (original)
+++ team/group/pinequeue/apps/app_queue.c Thu Dec 2 15:46:42 2010
@@ -294,6 +294,9 @@
/*! \brief queues.conf [general] option */
static int shared_lastcall = 0;
+
+/*! \brief Play prompts without interrupts (foreground) */
+static int background_prompts = 0;
/*! \brief Subscription to device state change events */
static struct ast_event_sub *device_state_sub;
@@ -1798,7 +1801,6 @@
return res;
}
-void ast_queue_sound_finished_handler(void *data);
extern const struct ast_datastore_info queue_ds_sound_ending;
void destroy_streamfile_info(struct ast_queue_streamfile_info *playdata);
@@ -2559,10 +2561,13 @@
#endif
while (*to && !peer) {
+
int numlines, retry, pos = 1;
struct ast_channel *watchers[AST_MAX_WATCHERS];
watchers[0] = in;
start = NULL;
+
+ play_file(qe->chan, NULL, 0, qe->moh);
for (retry = 0; retry < 2; retry++) {
numlines = 0;
@@ -2599,9 +2604,7 @@
}
/* Poll for events from both the incoming channel as well as any outgoing channels */
- ast_log(LOG_ERROR,"About to do ast_waitfor_n()\n");
winner = ast_waitfor_n(watchers, pos, to);
- ast_log(LOG_ERROR,"Returned from ast_waitfor_n() winner=%p\n",winner);
/* Service all of the outgoing channels */
for (o = start; o; o = o->call_next) {
@@ -2966,15 +2969,12 @@
}
/* Wait a second before checking again */
- ast_log(LOG_ERROR,"About to Wait for digit(%d ms)\n", RECHECK * 1000);
if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
- ast_log(LOG_ERROR,"Returned (%d) from waitfordigit\n", res);
if (res > 0 && !valid_exit(qe, res))
res = 0;
else
break;
}
- ast_log(LOG_ERROR,"Returned (%d) from waitfordigit\n", res);
/* If we have timed out, break out */
if (qe->expire && (time(NULL) >= qe->expire)) {
@@ -3587,54 +3587,39 @@
int res2;
res2 = ast_autoservice_start(qe->chan);
- ast_log(LOG_ERROR,"Autoservice started on chan %s\n",qe->chan->name);
/* instead of starting autoservice and jacking this thread to push sound to the
peer channel, let's set up a background player to the peer channel and
get on with life in this thread. */
-
-/*
- datastore = ast_channel_datastore_alloc(&queue_ds_sound_ending, NULL);
-
- aqsi->endHandler = ast_queue_peer_sound_finished_handler;
- aqsi->qe = &qe;
- aqsi->chan = chan;
- aqsi->ringing = ringing;
- aqsi->now_playing = 0;
- strcpy(aqsi->moh, qe.moh);
- AST_LIST_HEAD_INIT(&aqsi->flist);
- datastore->data = aqsi;
-
- ast_channel_datastore_add(chan, datastore);
-*/
- if (qe->parent->memberdelay) {
- ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
- res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
- }
- if (!res2 && announce) {
- play_file(peer, announce, ringing, qe->moh);;
- }
- if (!res2 && qe->parent->reportholdtime) {
- int res3;
- res3 = play_file(peer, qe->parent->sound_reporthold, ringing, qe->moh);
- if (!res3) {
- int holdtime, holdtimesecs;
-
- time(&now);
- holdtime = abs((now - qe->start) / 60);
- holdtimesecs = abs((now - qe->start) % 60);
- if (holdtime > 0) {
- ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
- play_file(peer, qe->parent->sound_minutes, ringing, qe->moh);
- }
- if (holdtimesecs > 1) {
- ast_say_number(peer, holdtimesecs, AST_DIGIT_ANY, peer->language, NULL);
- play_file(peer, qe->parent->sound_seconds, ringing, qe->moh);
- }
+ if (qe->parent->memberdelay) {
+ ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
+ res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
+ }
+ if (!res2 && announce) {
+ play_file(peer, announce, ringing, qe->moh);;
+ }
+ if (!res2 && qe->parent->reportholdtime) {
+ int res3;
+ res3 = play_file(peer, qe->parent->sound_reporthold, ringing, qe->moh);
+ if (!res3) {
+ int holdtime, holdtimesecs;
+
+ time(&now);
+ holdtime = abs((now - qe->start) / 60);
+ holdtimesecs = abs((now - qe->start) % 60);
+ if (holdtime > 0) {
+ ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
+ play_file(peer, qe->parent->sound_minutes, ringing, qe->moh);
+ }
+ if (holdtimesecs > 1) {
+ ast_say_number(peer, holdtimesecs, AST_DIGIT_ANY, peer->language, NULL);
+ play_file(peer, qe->parent->sound_seconds, ringing, qe->moh);
}
}
- ast_log(LOG_ERROR,"Autoservice stopped on chan %s\n", qe->chan->name);
+ }
res2 |= ast_autoservice_stop(qe->chan);
+
+
if (ast_check_hangup(peer)) {
/* Agent must have hung up */
ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
@@ -3665,10 +3650,8 @@
}
/* Stop music on hold */
if (ringing) {
- ast_log(LOG_ERROR,"Stopping indicate\n");
ast_indicate(qe->chan,-1);
} else {
- ast_log(LOG_ERROR,"Stopping MOH on chan %s\n", qe->chan->name);
ast_moh_stop(qe->chan);
}
/* If appropriate, log that we have a destination channel */
@@ -3849,7 +3832,6 @@
if (!ast_strlen_zero(macroexec)) {
ast_debug(1, "app_queue: macro=%s.\n", macroexec);
- ast_log(LOG_ERROR,"Autoservice started on chan %s\n", qe->chan->name);
res = ast_autoservice_start(qe->chan);
if (res) {
ast_log(LOG_ERROR, "Unable to start autoservice on calling channel %s\n", qe->chan->name);
@@ -3867,7 +3849,6 @@
res = -1;
}
- ast_log(LOG_ERROR,"Autoservice stopped on chan %s\n", qe->chan->name);
if (ast_autoservice_stop(qe->chan) < 0) {
ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
res = -1;
@@ -3886,7 +3867,6 @@
if (!ast_strlen_zero(gosubexec)) {
if (option_debug)
ast_log(LOG_DEBUG, "app_queue: gosub=%s.\n", gosubexec);
- ast_log(LOG_ERROR,"Autoservice started on chan %s\n", qe->chan->name);
res = ast_autoservice_start(qe->chan);
if (res) {
ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
@@ -3936,7 +3916,6 @@
res = -1;
}
- ast_log(LOG_ERROR,"Autoservice stopped on chan %s\n", qe->chan->name);
if (ast_autoservice_stop(qe->chan) < 0) {
ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
res = -1;
@@ -4039,9 +4018,7 @@
int retrywait = qe->parent->retry * 1000;
int res;
- ast_log(LOG_ERROR,"About to call ast_waitfordigit(%d)\n", retrywait);
res = ast_waitfordigit(qe->chan, retrywait);
- ast_log(LOG_ERROR,"ast_waitfordigit returns %d\n", res);
if (res > 0 && !valid_exit(qe, res))
res = 0;
@@ -4733,133 +4710,196 @@
AST_LIST_UNLOCK(&rule_lists);
}
-#ifdef NOT_NEEDED_ANY_MORE
-/* declared in channel.h now -- keeping for ref until done here */
-
-struct ast_queue_streamfile_name {
- char *filename;
- AST_LIST_ENTRY(ast_queue_streamfile_name) list;
+/*! \brief Data structure for \ref play_file() channel frame generator */
+struct gen_state {
+ struct ast_channel *chan;
+ struct ast_filestream *stream;
+ int sample_queue;
+ char filename[512];
+ struct ast_queue_streamfile_info *aqsi;
};
-struct ast_queue_streamfile_info {
- void (*endHandler)(void *data); /* a func ptr to the handler that will do what needs doing when the streaming of a soundfile is finished */
- AST_LIST_HEAD(,ast_queue_streamfile_name) flist; /* a list of other sound files that need to be played in sequence */
- struct ast_channel *chan;
- struct queue_ent *qe;
- int ringing;
- char moh[80];
- int now_playing; /* just in case */
+
+/*! \brief Allocate generator data structures if needed
+
+We don't really do anything here since we get the needed data as params.
+*/
+static void *gen_alloc(struct ast_channel *chan, void *params)
+{
+ struct gen_state *state = params;
+
+ if (option_debug > 3) {
+ ast_log(LOG_DEBUG, "--- Allocating generator for %s\n", chan->name);
+ }
+ return state;
+}
+
+/*! \brief Close file stream used by generator */
+static void gen_closestream(struct gen_state *state)
+{
+ if (!state->stream)
+ return;
+
+ ast_closestream(state->stream);
+ state->chan->stream = NULL;
+ state->stream = NULL;
+ state->aqsi->now_playing = 0; /* Important flag to indicate we are no longer playing on this channel */
+}
+
+/*! \brief Release generator on channel */
+static void gen_release(struct ast_channel *chan, void *data)
+{
+ struct gen_state *state = data;
+ gen_closestream(state);
+ ast_free(data);
+}
+
+
+/*! \brief Read frames from file stream and return them to the generator \ref gen_generate() */
+static struct ast_frame *gen_readframe(struct gen_state *state)
+{
+ struct ast_frame *f = NULL;
+ if (state && state->chan) {
+ if (option_debug > 4) {
+ ast_log(LOG_DEBUG, "... Generating frames for %s\n", state->chan->name);
+ }
+ } else {
+ ast_log(LOG_ERROR, "... no channel to generate frames for!\n");
+ return f;
+ }
+ if (ast_strlen_zero(state->filename)) {
+ ast_log(LOG_ERROR, ".... no file to read from?? Generator for %s\n", state->chan->name);
+ return f;
+ }
+
+ if (!state->stream) {
+ if (!(state->stream = ast_openstream_full(state->chan, state->filename, state->chan->language, 1))) {
+ ast_log(LOG_WARNING, "File '%s' could not be opened: %s\n", state->filename, strerror(errno));
+ return f;
+ }
+
+ }
+ f = ast_readframe(state->stream);
+
+ return f;
+}
+
+/*! \brief The actual generator that reads frames and sends them to the channel
+ While letting the queue app do it's thing.
+ */
+static int gen_generate(struct ast_channel *chan, void *data, int len, int samples)
+{
+ struct gen_state *state = data;
+ struct ast_frame *f = NULL;
+ int res = 0;
+
+ if (!state) {
+ ast_log(LOG_ERROR, "---- Do not have a current state data structure\n");
+ return -1;
+ }
+ if (!state->chan) {
+ ast_log(LOG_ERROR, "... no channel to generate frames for!\n");
+ return -1;
+ }
+
+ state->sample_queue += samples;
+
+ while (state->sample_queue > 0) {
+ if (!(f = gen_readframe(state)))
+ return -1;
+
+ res = ast_write(chan, f);
+ ast_frfree(f);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Failed to write frame: %s\n", strerror(errno));
+ return -1;
+ }
+ state->sample_queue -= f->samples;
+ }
+
+ return res;
+}
+
+/*! \brief Generator initialization structure for play_file */
+static struct ast_generator play_file_gen =
+{
+ alloc: gen_alloc, /*! \ref gen_alloc() */
+ release: gen_release, /*! \ref gen_release() */
+ generate: gen_generate, /*! \ref gen_generate() */
};
-/* moved to file.c -- a more global position, and that's were it is used besides here. (and in say.c) */
-const struct ast_datastore_info queue_ds_sound_ending = { /* this belongs in a place where it is globally available */
- .type = "queue_sound_ending"
-};
-
-#endif
-
-
-void ast_queue_sound_finished_handler(void *data)
-{
- struct ast_queue_streamfile_info *playdata = (struct ast_queue_streamfile_info *)data;
- struct ast_queue_streamfile_name *fn;
- struct ast_channel *chan = playdata->chan;
- int ringing = playdata->ringing;
- int res;
- char *moh = playdata->moh;
- /* int now_playing = playdata->now_playing; */
-
-
- /* we've been streaming a file out to the channel, and it just turned up a null,
- which we are assuming will be EOF. Well, at this point, normally, the
- a wait on the stream would return, and we'd do the normal thing: stopstream,
- maybe an autoservice_stop, and go back to MOH or signalling */
-
- /* Why are we doing this? Because we don't want to stop processing the queue
- while we wait for a sound file to finish playing. No Wait() is allowed here.
- So, instead of calling ast_stream_and_wait(), we just call ast_streamfile,
- and handle the EOF asynchronously via ast_autoservice_*().
-
- */
- ast_log(LOG_WARNING,"----SOUND_FINISHED_HANDLER CALLED! chan=%s\n", chan->name);
- ast_log(LOG_ERROR,"StopStream on chan %s\n", chan->name);
- ast_stopstream(chan);
- ast_log(LOG_ERROR,"AutoServiceStop %s\n", chan->name);
- ast_autoservice_stop(chan);
- /* if there are any files in flist, now is the time to start playing them! */
- AST_LIST_LOCK(&playdata->flist);
- while (!AST_LIST_EMPTY(&playdata->flist)) {
-
- fn = AST_LIST_REMOVE_HEAD(&playdata->flist, list);
-
- ast_log(LOG_ERROR,"Start streaming file %s on chan %s\n", fn->filename, chan->name);
- res = ast_streamfile(chan, fn->filename, chan->language);
- if (res) {
- /* perhaps this file was not found, whatever...
- */
- ast_free(fn->filename);
- ast_free(fn);
- continue;
- }
-
- ast_autoservice_start(chan);
- ast_log(LOG_ERROR,"AutoServiceStart on chan %s\n", chan->name);
-
- ast_free(fn->filename);
- ast_free(fn);
- AST_LIST_UNLOCK(&playdata->flist);
- return;
- }
-
- playdata->now_playing = 0;
- AST_LIST_UNLOCK(&playdata->flist);
-
- /* Resume Music on Hold if the caller is going to stay in the queue */
- if (!playdata->valid_exit) { /* don't start up moh if we are on our way out */
- if (ringing) {
- ast_log(LOG_ERROR,"Starting indicate CONTROL_RINGING on chan %s\n", chan->name);
- ast_indicate(chan, AST_CONTROL_RINGING);
- } else {
- ast_log(LOG_ERROR,"Starting MOH on chan %s\n", chan->name);
- ast_moh_start(chan, moh, NULL);
- /* ast_waitfor(chan, 1); */
- }
- }
-}
-
-
-/* to enable playing of a string of files, one after the other, and not have to wait
+
+/*! \brief Play queue updates in the background, being able to interrupt if an
+ agent becomes available.
+
+ To enable playing of a string of files, one after the other, and not have to wait
around for each one to finish before playing the next, instead we put them into
a list, which we insert at the tail.
- The file-finished handler will, upon a file compltion, check to see if annything
- is in that list, and remove from the head and begin the playback.
-
Make sure to get things rolling with a plain play_file(), then use this
to queue up the others in sequence
+
+ When called without a filename, we check if we have a list of files in the
+ playlist. If so we start playing again.
*/
-
static int play_file(struct ast_channel *chan, const char *filename, int ringing, char *moh)
{
int res;
struct ast_datastore *datastore;
struct ast_queue_streamfile_info *aqsi = NULL;
- /* No need to lock the channels because they are already locked in ast_do_masquerade */
-
+ struct gen_state *generatordata;
+ struct ast_queue_streamfile_name *sfn = NULL;
+ char playfilename[512];
+
+ if (!background_prompts) {
+ /* Play prompts like before, with no interruption */
+ ast_stopstream(chan);
+ res = ast_streamfile(chan, filename, chan->language);
+ if (!res) {
+ res = ast_waitstream(chan, AST_DIGIT_ANY);
+ }
+ ast_stopstream(chan);
+ return res;
+ }
+
/* look up the datastore and the play_finished struct, and set appropriate values */
if ((datastore = ast_channel_datastore_find(chan, &queue_ds_sound_ending, NULL))) {
aqsi = datastore->data;
if (aqsi) { /* copy this stuff into place */
aqsi->ringing = ringing;
- if (moh)
+ if (moh) {
strcpy(aqsi->moh, moh);
+ }
}
} else {
ast_log(LOG_ERROR, "Can't find the queue_ds_sound_ending datastore! on chan %s\n", chan->name);
return 1; /* Why continue, if I can't access the datastore & list? */
}
- if (ast_strlen_zero(filename)) {
- return 1;
+ /* If we are not playing - see if we can play the next file in the playlist */
+ if (aqsi->now_playing == 0) {
+ if (ast_strlen_zero(filename)) {
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "No filename and not playing - selecting next file in playlist\n");
+ }
+ /* take the first one if we have a playlist */
+ while (res && !AST_LIST_EMPTY(&aqsi->flist)) {
+ sfn = AST_LIST_REMOVE_HEAD(&aqsi->flist, list);
+ ast_copy_string(playfilename, sfn->filename, sizeof(playfilename));
+ free(sfn);
+ }
+ if (!sfn) {
+ return -1;
+ }
+ } else {
+ ast_copy_string(playfilename, filename, sizeof(playfilename));
+ }
+ } else {
+ if (option_debug > 2 ) {
+ ast_log(LOG_DEBUG, "No filename and currently playing\n");
+ }
+ if (ast_strlen_zero(filename)) {
+ return -1;
+ }
}
AST_LIST_LOCK(&aqsi->flist);
@@ -4867,43 +4907,53 @@
if (aqsi->now_playing) {
struct ast_queue_streamfile_name *fn = ast_calloc(1, sizeof(*fn));
fn->filename = ast_strdup(filename);
- ast_log(LOG_ERROR,"queued sound file %s for playing on chan %s\n", filename, chan->name);
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, " queued sound file %s for playing on chan %s\n", filename, chan->name);
+ }
/* link the struct into the current ast_queue_streamfile_info struct */
- AST_LIST_INSERT_TAIL(&aqsi->flist, fn, list); /* in this case, nothing else to do,
- just insert the new file at the end of the list */
+ AST_LIST_INSERT_TAIL(&aqsi->flist, fn, list);
+ /* in this case, nothing else to do, just insert the new file at the end of the list */
} else {
+ /* Start playing */
+
/* Stop the music on hold so we can play our own file */
if (ringing) {
- ast_log(LOG_ERROR, "Stopping Indicate\n");
+ if (option_debug > 1) {
+ ast_log(LOG_DEBUG, "Stopping Indication on %s\n", chan->name);
+ }
ast_indicate(chan,-1);
} else {
- ast_log(LOG_ERROR, "Stopping MOH on chan %s\n", chan->name);
+ if (option_debug > 1) {
+ ast_log(LOG_DEBUG, "Stopping MOH on chan %s\n", chan->name);
+ }
ast_moh_stop(chan);
}
- ast_log(LOG_ERROR, "Stopping Streaming on chan %s\n", chan->name);
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "Stopping Streaming on chan %s\n", chan->name);
+ }
ast_stopstream(chan);
- ast_log(LOG_ERROR, "Autoservice stop on chan %s\n", chan->name);
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "Autoservice stop on chan %s\n", chan->name);
+ }
ast_autoservice_stop(chan);
-
- ast_log(LOG_ERROR, "Starting to stream %s on chan %s\n", filename, chan->name);
- res = ast_streamfile(chan, filename, aqsi->chan->language); /* begin the streaming */
-
- while (res && !AST_LIST_EMPTY(&aqsi->flist)) {
- /* really, how could this even be possible?
- just in case.... */
- struct ast_queue_streamfile_name *fn;
-
- fn = AST_LIST_REMOVE_HEAD(&aqsi->flist, list);
-
- ast_log(LOG_ERROR,"Start streaming file %s on chan %s\n", fn->filename, chan->name);
- res = ast_streamfile(chan, fn->filename, chan->language);
- }
-
-
- if (res) {
+
+ /* Create generator to start playing audio without waiting */
+ generatordata = ast_calloc(1, sizeof(struct gen_state));
+ if (!generatordata) {
+ ast_log(LOG_ERROR, "Can't allocate generator input\n");
+ return 1;
+ }
+ ast_copy_string(generatordata->filename, playfilename, sizeof(generatordata->filename));
+ generatordata->chan = chan;
+ generatordata->aqsi = aqsi;
+
+
+ /* Starting new generator on channel. */
+ if (ast_activate_generator(chan, &play_file_gen, generatordata)) {
+ ast_log(LOG_ERROR, "Not playing requested prompt %s. Generator failed on %s.\n", playfilename, chan->name);
/* oops, the current file has problems */
/* restore the moh */
if (ringing) {
@@ -4917,19 +4967,15 @@
return 1;
}
aqsi->now_playing = 1; /* We have begun playback */
- ast_log(LOG_ERROR,"Autoservice start\n");
- ast_autoservice_start(chan); /* this will let the sound file play in a different thread */
-
}
AST_LIST_UNLOCK(&aqsi->flist);
- ast_log(LOG_ERROR,"ast_waitfor(1) called\n");
ast_waitfor(chan, 1);
return 0; /* non-zero most likely means the file doesn't exist */
}
-/* This routine proabably will only need to be called at module unload time */
+/*! \brief This routine propably will only need to be called at module unload time */
void destroy_streamfile_info(struct ast_queue_streamfile_info *playdata)
{
struct ast_queue_streamfile_name *fn;
@@ -5076,7 +5122,6 @@
datastore = ast_channel_datastore_alloc(&queue_ds_sound_ending, NULL);
- aqsi->endHandler = ast_queue_sound_finished_handler;
aqsi->qe = &qe;
aqsi->chan = chan;
aqsi->ringing = ringing;
@@ -5125,6 +5170,8 @@
break;
}
+ ast_log(LOG_DEBUG, "--- We should be here, really...\n");
+ play_file(qe.chan, NULL, ringing, qe.moh); /* OEJ - Trigger next prompt */
if (makeannouncement) {
/* Make a position announcement, if enabled */
if (qe.parent->announcefrequency)
@@ -5759,6 +5806,9 @@
update_cdr = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "updatecdr")))
update_cdr = ast_true(general_val);
+ background_prompts = 0;
+ if ((general_val = ast_variable_retrieve(cfg, "general", "background_prompts")))
+ background_prompts = ast_true(general_val);
shared_lastcall = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "shared_lastcall")))
shared_lastcall = ast_true(general_val);
Modified: team/group/pinequeue/configs/queues.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/group/pinequeue/configs/queues.conf.sample?view=diff&rev=297487&r1=297486&r2=297487
==============================================================================
--- team/group/pinequeue/configs/queues.conf.sample (original)
+++ team/group/pinequeue/configs/queues.conf.sample Thu Dec 2 15:46:42 2010
@@ -67,6 +67,14 @@
;
shared_lastcall=no
;
+; Prompts played to the caller by default is played in the foreground,
+; which means that even if a queue member becomes available, the
+; prompt will be played fully. Enabling 'background_prompts' will
+; make sure that prompts are interruptible. If a queue member becomes
+; available, the prompt will be interrupted.
+;
+background_prompts=no
+;
;[markq]
;
; A sample call queue
Modified: team/group/pinequeue/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinequeue/include/asterisk/channel.h?view=diff&rev=297487&r1=297486&r2=297487
==============================================================================
--- team/group/pinequeue/include/asterisk/channel.h (original)
+++ team/group/pinequeue/include/asterisk/channel.h Thu Dec 2 15:46:42 2010
@@ -1749,17 +1749,17 @@
AST_LIST_ENTRY(ast_group_info) group_list;
};
-/* for the sake of asynchronous filestream playing, used (at least at first) in app_queue,
-we include this definition here so both app_queue and file.c can see it. it will be contained
-in a channel datastore */
-
+/*! \brief Asynchronous filestream playing playlist
+
+Used (at least at first) in app_queue - in the ast_queue_streamfile_info channel datastore
+*/
struct ast_queue_streamfile_name {
char *filename;
AST_LIST_ENTRY(ast_queue_streamfile_name) list;
};
+/*! \brief Information data about background playing of prompts */
struct ast_queue_streamfile_info {
- void (*endHandler)(void *data); /* a func ptr to the handler that will do what needs doing when the streaming of a soundfile is finished */
void (*digitHandler)(void *data, char digit); /* a func ptr to the handler that will do what needs doing when the streaming of a soundfile is finished */
struct queue_ent *qe;
AST_LIST_HEAD(,ast_queue_streamfile_name) flist; /* a list of other sound files that need to be played in sequence */
Modified: team/group/pinequeue/main/file.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinequeue/main/file.c?view=diff&rev=297487&r1=297486&r2=297487
==============================================================================
--- team/group/pinequeue/main/file.c (original)
+++ team/group/pinequeue/main/file.c Thu Dec 2 15:46:42 2010
@@ -702,16 +702,6 @@
}
if (!(fr = s->fmt->read(s, whennext))) {
- struct ast_datastore *datastore;
- /* here is the ideal spot to put code to take an action
- when we have reached the end of the file */
- /* look up the datastore and the play_finished struct, and set appropriate values */
- if ((datastore = ast_channel_datastore_find(s->owner, &queue_ds_sound_ending, NULL))) {
- struct ast_queue_streamfile_info *aqsi = datastore->data; /* what a waste! I have to dive into the data to know where to pass it.*/
- if (aqsi) {
- (*aqsi->endHandler)(datastore->data);
- }
- }
return NULL;
}
@@ -755,7 +745,6 @@
}
fr = read_frame(s, &whennext);
- ast_log(LOG_ERROR, "Read a frame on channel %s\n", s->owner->name);
if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
if (fr) {
@@ -764,7 +753,6 @@
}
goto return_failure;
}
- ast_log(LOG_ERROR, "and wrote it, too!\n");
if (fr) {
ast_frfree(fr);
@@ -782,11 +770,9 @@
factor = ((float) rate) / ((float) 8000.0);
dahdi_timer_samples = (int) ( ((float) dahdi_timer_samples) / factor );
}
- ast_log(LOG_ERROR,"About to call ast_settimeout with %d for ast_fsread_audio\n", dahdi_timer_samples);
ast_settimeout(s->owner, dahdi_timer_samples, ast_fsread_audio, s);
} else {
#endif
- ast_log(LOG_ERROR,"About to call ast_sched_add with %d for ast_fsread_audio\n", whennext / (ast_format_rate(s->fmt->format) / 1000));
s->owner->streamid = ast_sched_add(s->owner->sched,
whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
#ifdef HAVE_DAHDI
@@ -798,9 +784,12 @@
return FSREAD_SUCCESS_SCHED;
return_failure:
+ if (option_debug > 1) {
+ ast_log(LOG_DEBUG, "DEBUG: return_failure called. Giving up. !\n");
+ }
+
s->owner->streamid = -1;
#ifdef HAVE_DAHDI
- ast_log(LOG_ERROR, "Calling ast_settimeout(%s, 0, NULL, NULL);\n", s->owner->name);
ast_settimeout(s->owner, 0, NULL, NULL);
#endif
return FSREAD_FAILURE;
More information about the asterisk-commits
mailing list