[asterisk-commits] murf: branch murf/pinequeue r279343 - in /team/murf/pinequeue: apps/ include/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Jul 24 17:01:32 CDT 2010


Author: murf
Date: Sat Jul 24 17:01:30 2010
New Revision: 279343

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=279343
Log:

This is the first round of fixes for one of the problems mentioned in 
bug 17055, that wasn't split off into another bug report, namely,
that "also while the announce is being played the call can not be answered by an agent"

What is happening is that each sound file is played in the current thread, and a XXX_wait()
call (usually ast_waitstream()) is made, to process the sound into the channel. The result is that app_queue is 
frozen until the sound is finished playing. This can get cumbersome!

I changed it so no wait() calls are made. I use a channel datastore to sort of 
mark the channel that it's in this special mode. THe datastore has a struct that
contains all the data we could desire, including the pointer to an eof-handler on the
filestream. That's the key, enabling a handler to be run when a sound file is finished.

The tricky part about the eof-handler for filestreams, is where to call it! I found about
the only practical spot, in main/file.c, in the func read_frame. Luckily, it's up one
level from all the format read funcs, and gets a null from those funcs when they hit eof.

So, we do the ast_streamfile() call, and fire off ast_autoservice_start() to push the audio
out in a different thread. When the file finishes, the handler is fired up to shut off 
autoservice, start music on hold, or whatever else would need to be done sound-wise at that point.

So, basically, if MOH is turned on, app_queue is fundamentally an MOH player, with interruptions
to play sound files. 

To really complicate the affair, it plays sequences of files including doing ast_say_number() calls.
I queue the other files up in the datastore in a list, and use the add_playfile func in app_queue to
do this.

But for the say_number stuff, I needed to insinuate this capability into the wait_file func, and to do that,
I had to remove all the waitstream calls, and make the whole say.c use the same basic func to play (and maybe wait for) all files.
Really, this should have been done a while ago. It was the same two or three sets of code repeated over a hundred
times, with several bugs introduced. I'd like to think the new wait_file func (and wait_file_full) reduce the size
of the file and make it more stable. I've marked a set of waitstream calls that are called between say_number calls,
because really, they should not be necessary. And, here and there, folks forgot to call waitstrem after ast_streamfile, which
should have ended up skipping the playing of that file. This kind of thing is fixed. say.c should no longer use
ast_waitstream, ast_waitstream_full, ast_streafile, or ast_play_and_wait, but rather, just wait_file or wait_file_full,
and those guys get to use the lower level calls.

In app_queue, the play_file func will interrupt any other playing files, including moh. The handler should get MOH going
again after the file finishes playing.

the add_playfile func will add the file to the list in the datastore. The eof-handler will begin the streaming of the 
first file in the list (if there), and remove it from the list. All the say_number calls will generally just end up
doing add_playfile calls for reading off the number.

I can't guarantee that this stuff compiles, but even if it does, I *can* guarantee that it won't work. For now.
I still have to refactor the sound related code that is done after the files are played, and make sure those
operations will be done in the eof-handler.  All and all, it's almost done.

  

Modified:
    team/murf/pinequeue/apps/app_queue.c
    team/murf/pinequeue/include/asterisk/channel.h
    team/murf/pinequeue/main/file.c
    team/murf/pinequeue/main/say.c

Modified: team/murf/pinequeue/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/murf/pinequeue/apps/app_queue.c?view=diff&rev=279343&r1=279342&r2=279343
==============================================================================
--- team/murf/pinequeue/apps/app_queue.c (original)
+++ team/murf/pinequeue/apps/app_queue.c Sat Jul 24 17:01:30 2010
@@ -1797,23 +1797,47 @@
 	return res;
 }
 
-static int play_file(struct ast_channel *chan, const char *filename)
+int add_playfile(struct ast_channel *chan, const char *name);
+void ast_queue_sound_finished_handler(struct ast_channel *chan, int ringing, char *moh, int now_playing, void *data);
+extern const struct ast_datastore_info queue_ds_sound_ending;
+void destroy_streamfile_info(struct ast_queue_streamfile_info *playdata);
+
+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 */
+	
+	/* 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) {
+			aqsi->now_playing = 1;
+			aqsi->ringing = ringing;
+			if (moh)
+				strcpy(aqsi->moh, moh);
+		}
+	} else {
+		ast_log(LOG_WARNING, "Can't find the queue_ds_sound_ending datastore!\n");
+	}
 
 	if (ast_strlen_zero(filename)) {
 		return 0;
 	}
 
+	/*
+	Rule: the code that calls this routine should set the datastore vars chan, ringing, and moh before calling this! */
+
 	ast_stopstream(chan);
 
-	res = ast_streamfile(chan, filename, chan->language);
-	if (!res)
-		res = ast_waitstream(chan, AST_DIGIT_ANY);
-
-	ast_stopstream(chan);
-
-	return res;
+
+	res = ast_streamfile(chan, filename, chan->language); /* begin the streaming */
+
+	if (res && aqsi)
+		aqsi->now_playing = 0; /* well, if a file was playing, we killed it. */
+
+	return res; /* non-zero most likely means the file doesn't exist */
 }
 
 /*!
@@ -1877,19 +1901,19 @@
 	if (qe->parent->announceposition) {
 		/* Say we're next, if we are */
 		if (qe->pos == 1) {
-			res = play_file(qe->chan, qe->parent->sound_next);
+			res = play_file(qe->chan, qe->parent->sound_next, ringing, NULL);
 			if (res)
 				goto playout;
 			else
 				goto posout;
 		} else {
-			res = play_file(qe->chan, qe->parent->sound_thereare);
+			res = add_playfile(qe->chan, qe->parent->sound_thereare);
 			if (res)
 				goto playout;
 			res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, NULL); /* Needs gender */
 			if (res)
 				goto playout;
-			res = play_file(qe->chan, qe->parent->sound_calls);
+			res = add_playfile(qe->chan, qe->parent->sound_calls);
 			if (res)
 				goto playout;
 		}
@@ -1912,7 +1936,7 @@
     if ((avgholdmins+avgholdsecs) > 0 && qe->parent->announceholdtime &&
         ((qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE && !qe->last_pos) ||
         !(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE))) {
-		res = play_file(qe->chan, qe->parent->sound_holdtime);
+		res = play_file(qe->chan, qe->parent->sound_holdtime,ringing,NULL);
 		if (res)
 			goto playout;
 
@@ -1922,11 +1946,11 @@
 				goto playout;
 
 			if (avgholdmins == 1) {
-				res = play_file(qe->chan, qe->parent->sound_minute);
+				res = add_playfile(qe->chan, qe->parent->sound_minute);
 				if (res)
 					goto playout;
 			} else {
-				res = play_file(qe->chan, qe->parent->sound_minutes);
+				res = add_playfile(qe->chan, qe->parent->sound_minutes);
 				if (res)
 					goto playout;
 			}
@@ -1936,7 +1960,7 @@
 			if (res)
 				goto playout;
 
-			res = play_file(qe->chan, qe->parent->sound_seconds);
+			res = add_playfile(qe->chan, qe->parent->sound_seconds);
 			if (res)
 				goto playout;
 		}
@@ -1950,7 +1974,7 @@
 			qe->chan->name, qe->parent->name, qe->pos);
 	}
 	if (say_thanks) {
-		res = play_file(qe->chan, qe->parent->sound_thanks);
+		res = add_playfile(qe->chan, qe->parent->sound_thanks);
 	}
 
 playout:
@@ -2498,7 +2522,7 @@
 	}
 	
 	/* play the announcement */
-	res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str);
+	res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str, ringing, qe->moh);
 
 	if (res > 0 && !valid_exit(qe, res))
 		res = 0;
@@ -3183,6 +3207,7 @@
 	.destroy = queue_transfer_destroy,
 };
 
+
 /*! \brief Log an attended transfer when a queue caller channel is masqueraded
  *
  * When a caller is masqueraded, we want to log a transfer. Fixup time is the closest we can come to when
@@ -3621,10 +3646,15 @@
 					res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
 				}
 				if (!res2 && announce) {
-					play_file(peer, announce);
+					play_file(peer, announce, ringing, qe->moh);;
 				}
 				if (!res2 && qe->parent->reportholdtime) {
-					if (!play_file(peer, qe->parent->sound_reporthold)) {
+					int res3;
+					if (announce)
+						res3 = add_playfile(peer, qe->parent->sound_reporthold);
+					else
+						res3 = play_file(peer, qe->parent->sound_reporthold, ringing, qe->moh);
+					if (!res3) {
 						int holdtime, holdtimesecs;
 
 						time(&now);
@@ -3632,11 +3662,11 @@
 						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);
+							add_playfile(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);
+							add_playfile(peer, qe->parent->sound_seconds);
 						}
 					}
 				}
@@ -3692,7 +3722,7 @@
 
 		/* Play announcement to the caller telling it's his turn if defined */
 		if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
-			if (play_file(qe->chan, qe->parent->sound_callerannounce))
+			if (play_file(qe->chan, qe->parent->sound_callerannounce,ringing,qe->moh))
 				ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
 		}
 
@@ -4731,6 +4761,129 @@
 	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;
+};
+
+struct ast_queue_streamfile_info {
+	void (*endHandler)(struct ast_channel *chan, int ringing, char *moh, int now_playing, 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;
+	int ringing;
+	char moh[80];
+	int now_playing;
+};
+/* moved to file.c -- a more global position, and that's were it is used besides here. */
+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(struct ast_channel *chan, int ringing, char *moh, int now_playing, void *data)
+{
+	struct ast_queue_streamfile_info *playdata = (struct ast_queue_streamfile_info *)data;
+	struct ast_queue_streamfile_name *fn;
+
+	/* 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_stopstream(chan);
+	ast_autoservice_stop(chan);
+	/* if there are any files in flist, now is the time to start playing them! */
+	AST_LIST_LOCK(&playdata->flist);
+	if (!AST_LIST_EMPTY(&playdata->flist)) {
+		fn = AST_LIST_REMOVE_HEAD(&playdata->flist, list);
+
+		playdata->now_playing = 1;
+		ast_streamfile(chan, fn->filename, chan->language);
+		ast_autoservice_start(chan);
+		
+		ast_free(fn->filename);
+		ast_free(fn);
+		AST_LIST_UNLOCK(&playdata->flist);
+		return;
+	} else {
+		playdata->now_playing = 0;
+	}
+	AST_LIST_UNLOCK(&playdata->flist);
+	
+        /* Resume Music on Hold if the caller is going to stay in the queue */
+        if (ringing)
+                ast_indicate(chan, AST_CONTROL_RINGING);
+        else
+                ast_moh_start(chan, moh, NULL);
+}
+
+
+/* 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 completion, 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 
+*/
+
+int add_playfile(struct ast_channel *chan, const char *name)
+{
+	struct ast_datastore *datastore;
+
+	/* No need to lock the channels because they are already locked in ast_do_masquerade */
+	
+	/* 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))) {
+		struct ast_queue_streamfile_info *aqsi = datastore->data;
+		if (aqsi) {
+			struct ast_queue_streamfile_name *fn = ast_calloc(1, sizeof(*fn));
+			aqsi->now_playing = 1;
+			fn->filename = ast_strdup(name);
+
+			/* link the struct into the current ast_queue_streamfile_info struct */
+			AST_LIST_LOCK(&aqsi->flist);
+			AST_LIST_INSERT_TAIL(&aqsi->flist, fn, list);
+			AST_LIST_UNLOCK(&aqsi->flist);
+		} else {
+			ast_log(LOG_ERROR, "Can't find the datastore data ptr to aqsi!\n");
+			return -1;
+		}
+	} else {
+		ast_log(LOG_ERROR, "Can't find the queue_ds_sound_ending datastore!\n");
+		return -1;
+	}
+	return 0;
+}
+
+/* This routine proabably 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;
+	AST_LIST_LOCK(&playdata->flist);
+	while (!AST_LIST_EMPTY(&playdata->flist)) {
+		fn = AST_LIST_REMOVE_HEAD(&playdata->flist, list);
+		ast_free(fn->filename);
+		ast_free(fn);
+	}
+	AST_LIST_UNLOCK(&playdata->flist);
+	AST_LIST_HEAD_DESTROY(&playdata->flist);
+	ast_free(playdata);
+}
+
 /*!\brief The starting point for all queue calls
  *
  * The process involved here is to 
@@ -4754,6 +4907,9 @@
 	int qcontinue = 0;
 	int max_penalty, min_penalty;
 	enum queue_result reason = QUEUE_UNKNOWN;
+	struct ast_datastore *datastore = NULL;
+	struct ast_queue_streamfile_info *aqsi = calloc(1,sizeof(struct ast_queue_streamfile_info));
+
 	/* whether to exit Queue application after the timeout hits */
 	int tries = 0;
 	int noption = 0;
@@ -4856,6 +5012,19 @@
 	}
 	ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", S_OR(args.url, ""),
 		S_OR(chan->cid.cid_num, ""));
+
+	datastore = ast_channel_datastore_alloc(&queue_ds_sound_ending, NULL);
+
+	aqsi->endHandler = ast_queue_sound_finished_handler;
+	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);
+
 check_turns:
 	if (ringing) {
 		ast_indicate(chan, AST_CONTROL_RINGING);

Modified: team/murf/pinequeue/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/murf/pinequeue/include/asterisk/channel.h?view=diff&rev=279343&r1=279342&r2=279343
==============================================================================
--- team/murf/pinequeue/include/asterisk/channel.h (original)
+++ team/murf/pinequeue/include/asterisk/channel.h Sat Jul 24 17:01:30 2010
@@ -1749,6 +1749,23 @@
         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 */
+
+struct ast_queue_streamfile_name {
+	char *filename;
+	AST_LIST_ENTRY(ast_queue_streamfile_name) list;
+};
+
+struct ast_queue_streamfile_info {
+	void (*endHandler)(struct ast_channel *chan, int ringing, char *moh, int now_playing, 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;
+	int ringing;
+	char moh[80];
+	int now_playing;
+};
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/murf/pinequeue/main/file.c
URL: http://svnview.digium.com/svn/asterisk/team/murf/pinequeue/main/file.c?view=diff&rev=279343&r1=279342&r2=279343
==============================================================================
--- team/murf/pinequeue/main/file.c (original)
+++ team/murf/pinequeue/main/file.c Sat Jul 24 17:01:30 2010
@@ -42,6 +42,7 @@
 #include "asterisk/app.h"
 #include "asterisk/pbx.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/channel.h"
 #include "asterisk/module.h"
 #include "asterisk/astobj2.h"
 
@@ -686,6 +687,12 @@
 	return NULL;
 }
 
+const struct ast_datastore_info queue_ds_sound_ending = { /* this is here because it is referenced here
+							     and the only other place it is used is in app_queue,
+							     which is not always loaded. */
+        .type = "queue_sound_ending"
+};
+
 static struct ast_frame *read_frame(struct ast_filestream *s, int *whennext)
 {
 	struct ast_frame *fr, *new_fr;
@@ -695,6 +702,16 @@
 	}
 
 	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)(aqsi->chan, aqsi->ringing, aqsi->moh, aqsi->now_playing, datastore->data);
+			}
+		}
 		return NULL;
 	}
 

Modified: team/murf/pinequeue/main/say.c
URL: http://svnview.digium.com/svn/asterisk/team/murf/pinequeue/main/say.c?view=diff&rev=279343&r1=279342&r2=279343
==============================================================================
--- team/murf/pinequeue/main/say.c (original)
+++ team/murf/pinequeue/main/say.c Sat Jul 24 17:01:30 2010
@@ -54,7 +54,7 @@
 
 /* Forward declaration */
 static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
-
+static int wait_file_full(struct ast_channel *chan, const char *ints, const char *file, const char *lang, int audiofd, int ctrlfd);
 
 static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 {
@@ -123,14 +123,7 @@
 		}
 		if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
 			(snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {
-			res = ast_streamfile(chan, fn, lang);
-			if (!res) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, lang, audiofd, ctrlfd);
 		}
 		num++;
 	}
@@ -203,14 +196,7 @@
 			fn = fnbuf;
 		}
 		if (fn && ast_fileexists(fn, NULL, lang) > 0) {
-			res = ast_streamfile(chan, fn, lang);
-			if (!res) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, lang, audiofd, ctrlfd);
 		}
 		num++;
 	}
@@ -253,14 +239,7 @@
 			break;
 		}
 		if (fn && ast_fileexists(fn, NULL, lang) > 0) {
-			res = ast_streamfile(chan, fn, lang);
-			if (!res) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, lang, audiofd, ctrlfd);
 		}
 		num++;
 	}
@@ -415,13 +394,40 @@
 static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 
-static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang) 
+static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
+{
+	return wait_file_full(chan, ints, file, lang, -1, -1);
+}
+
+static int wait_file_full(struct ast_channel *chan, const char *ints, const char *file, const char *lang, int audiofd, int ctrlfd) 
 {
 	int res;
+	struct ast_datastore *datastore;
 	if ((res = ast_streamfile(chan, file, lang)))
 		ast_log(LOG_WARNING, "Unable to play message %s\n", file);
+	if (!res) {
+		extern const struct ast_datastore_info queue_ds_sound_ending;  /* defined in file.c */
+		if ((datastore = ast_channel_datastore_find(chan, &queue_ds_sound_ending, NULL))) { /* app_queue wants to schedule this instead of play & wait */
+			struct ast_queue_streamfile_info *aqsi = datastore->data;
+			if (aqsi && aqsi->now_playing) {
+				struct ast_queue_streamfile_name *fn = ast_calloc(1, sizeof(*fn));
+				aqsi->now_playing = 1;
+				fn->filename = ast_strdup(file);
+				
+				/* link the struct into the current ast_queue_streamfile_info struct */
+				AST_LIST_LOCK(&aqsi->flist);
+				AST_LIST_INSERT_TAIL(&aqsi->flist, fn, list);
+				AST_LIST_UNLOCK(&aqsi->flist);
+				return 0;
+			}
+		}
+		if ((audiofd  > -1) && (ctrlfd > -1))
+			res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+		else
+			res = ast_waitstream(chan, ints);
+	}
 	if (!res)
-		res = ast_waitstream(chan, ints);
+		ast_stopstream(chan);
 	return res;
 }
 
@@ -553,13 +559,7 @@
 			}
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -675,14 +675,7 @@
 			num -= left * (exp10_int(length-1));
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) {
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				} else {
-					res = ast_waitstream(chan, ints);
-				}
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res; 
@@ -784,13 +777,7 @@
 			}
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else  
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -914,21 +901,11 @@
 			res = -1;
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else  
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 			if (!res) {
-				if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
-					if ((audiofd > -1) && (ctrlfd > -1))
-						res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-					else
-						res = ast_waitstream(chan, ints);
-				}
-				ast_stopstream(chan);
+				if (strlen(fna)) {
+					res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
+				}
 				strcpy(fna, "");
 			}
 		}
@@ -1000,13 +977,7 @@
 		}
 		
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else  
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -1104,14 +1075,7 @@
 		}
 
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
-
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 			
 	}
@@ -1196,13 +1160,7 @@
 			res = -1;
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -1367,14 +1325,7 @@
 		}
 		tmpnum = 0;
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) {
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				} else {
-					res = ast_waitstream(chan, ints);
-				}
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -1449,13 +1400,7 @@
 			}
 		}
 		if (!res) {
-			if(!ast_streamfile(chan, fn, language)) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -1602,13 +1547,7 @@
 				}
 			}
 			if (!res) {
-				if (!ast_streamfile(chan, fn, language)) {
-					if ((audiofd > -1) && (ctrlfd > -1))
-						res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-					else
-						res = ast_waitstream(chan, ints);
-				}
-				ast_stopstream(chan);
+				res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 			}
 		}
 	return res;
@@ -1693,13 +1632,7 @@
 		}
 
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -1785,13 +1718,7 @@
 		}
 		
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else  
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -1832,13 +1759,7 @@
 	char file_name[255] = "digits/";
 	strcat(file_name, fn);
 	ast_debug(1, "Trying to play: %s\n", file_name);
-	if (!ast_streamfile(chan, file_name, language)) {
-		if ((audiofd > -1) && (ctrlfd > -1))
-			ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-		else
-			ast_waitstream(chan, ints);
-	}
-	ast_stopstream(chan);
+	wait_file_full(chan, ints, file_name, language, audiofd, ctrlfd);
 }
 
 static void powiedz(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
@@ -2174,17 +2095,10 @@
 			res = -1;
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);	
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 		if (!res && playh) {
 			res = wait_file(chan, ints, "digits/pt-e", language);
-			ast_stopstream(chan);
 			playh = 0;
 		}
 	}
@@ -2251,13 +2165,7 @@
 			}
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-				ast_stopstream(chan);
-			}
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -2361,13 +2269,7 @@
 				}
 			}
 			if (!res) {
-				if (!ast_streamfile(chan, fn, language)) {
-					if ((audiofd > -1) && (ctrlfd > -1))
-						res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-					else
-						res = ast_waitstream(chan, ints);
-				}
-				ast_stopstream(chan);
+				res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 			}
 	}
 	return res;
@@ -2467,13 +2369,7 @@
 			res = -1;
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -2536,13 +2432,7 @@
 			ast_copy_string(fn, "digits/larn", sizeof(fn));
 		}
 		if (!res) {
-			if(!ast_streamfile(chan, fn, language)) {
-				if ((audiofd  > -1) && (ctrlfd > -1))
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -2652,14 +2542,7 @@
 		}
 
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) {
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				} else {
-					res = ast_waitstream(chan, ints);
-				}
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -2805,22 +2688,11 @@
 		}
 
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else  
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 			if (!res) {
-				if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
-					if ((audiofd > -1) && (ctrlfd > -1)) {
-						res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-					} else {
-						res = ast_waitstream(chan, ints);
-					}
-				}
-				ast_stopstream(chan);
+				if (strlen(fna)) {
+					res = wait_file_full(chan, ints, fna, language, audiofd, ctrlfd);
+				}
 				strcpy(fna, "");
 			}
 		}
@@ -2968,22 +2840,11 @@
 		}
 
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) 
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				else  
-					res = ast_waitstream(chan, ints);
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 			if (!res) {
-				if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
-					if ((audiofd > -1) && (ctrlfd > -1)) {
-						res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-					} else {
-						res = ast_waitstream(chan, ints);
-					}
-				}
-				ast_stopstream(chan);
+				if (strlen(fna) != 0) {
+					res = wait_file_full(chan, ints, fna, language, audiofd, ctrlfd);
+				}
 				strcpy(fna, "");
 			}
 		}
@@ -3066,14 +2927,7 @@
 			res = -1;
 		}
 		if (!res) {
-			if (!ast_streamfile(chan, fn, language)) {
-				if ((audiofd > -1) && (ctrlfd > -1)) {
-					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
-				} else {
-					res = ast_waitstream(chan, ints);
-				}
-			}
-			ast_stopstream(chan);
+			res = wait_file_full(chan, ints, fn, language, audiofd, ctrlfd);
 		}
 	}
 	return res;
@@ -3125,20 +2979,18 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file_full(chan, ints, fn, lang, -1, -1);
 	}
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file_full(chan, ints, fn, lang, -1, -1);
 	}
 	if (!res)
 		res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res)
 		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
 	return res;
@@ -3154,19 +3006,17 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res)
 		res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+#ifdef IS_THIS_A_MISTAKE
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res) {
 		/* Year */
@@ -3203,19 +3053,17 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res)
 		res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+#ifdef IS_THIS_A_MISTAKE
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res) {
 		/* Year */
@@ -3254,23 +3102,23 @@
 
 	if (!res)
 		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}	
 	if (!res)
 		ast_say_number(chan, tm.tm_mday , ints, lang, (char *) NULL);
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);		
+		res = wait_file(chan, ints, fn, lang);
 	}
 	return res;
 }
@@ -3285,19 +3133,17 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res)
 		res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res)
 		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
@@ -3314,20 +3160,18 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res)
 		res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
-	}
+		res = wait_file(chan, ints, fn, lang);
+	}
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res)
 		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
 	return res;
@@ -3343,27 +3187,25 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
+		res = wait_file(chan, ints, fn, lang);
 		ast_copy_string(fn, "digits/tee", sizeof(fn));
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res)
 		res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res)
 		res = ast_waitstream(chan, ints);
+#endif
 	if (!res) {
 		ast_copy_string(fn, "digits/duan", sizeof(fn));
-		res = ast_streamfile(chan, fn, lang);
+		res = wait_file(chan, ints, fn, lang);
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res){
 		ast_copy_string(fn, "digits/posor", sizeof(fn));
-		res = ast_streamfile(chan, fn, lang);
+		res = wait_file(chan, ints, fn, lang);
 		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
 	}	
 	return res;
@@ -3406,24 +3248,20 @@
 	ast_localtime(&tv, &tm, NULL);
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res) {
-			res = ast_waitstream(chan, ints);
-		}
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res) {
 		snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
-		res = ast_streamfile(chan, fn, lang);
-		if (!res) {
-			res = ast_waitstream(chan, ints);
-		}
+		res = wait_file(chan, ints, fn, lang);
 	}
 	if (!res) {
 		res = ast_say_number(chan, tm.tm_mday, ints, lang, "m");
 	}
+#ifdef IS_THIS_A_MISTAKE 
 	if (!res) {
 		res = ast_waitstream(chan, ints);
 	}
+#endif
 	if (!res) {
 		res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m");
 	}
@@ -6126,26 +5964,20 @@
 			res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
 	} else if (tm.tm_min) {
 		if (!res)
-			res = ast_streamfile(chan, "digits/oh", lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+			res = wait_file(chan, ints, "digits/oh", lang);
 		if (!res)
 			res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
 	} else {
 		if (!res)
-			res = ast_streamfile(chan, "digits/oclock", lang);
-		if (!res)
-			res = ast_waitstream(chan, ints);
+			res = wait_file(chan, ints, "digits/oclock", lang);
 	}
 	if (pm) {
 		if (!res)
-			res = ast_streamfile(chan, "digits/p-m", lang);
+			res = wait_file(chan, ints, "digits/p-m", lang);
 	} else {
 		if (!res)
-			res = ast_streamfile(chan, "digits/a-m", lang);
-	}
-	if (!res)
-		res = ast_waitstream(chan, ints);
+			res = wait_file(chan, ints, "digits/a-m", lang);
+	}
 	return res;
 }
 
@@ -6160,9 +5992,7 @@
 	if (!res)
 		res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
 	if (!res)
-		res = ast_streamfile(chan, "digits/oclock", lang);
-	if (!res)
-		res = ast_waitstream(chan, ints);
+		res = wait_file(chan, ints, "digits/oclock", lang);

[... 696 lines stripped ...]



More information about the asterisk-commits mailing list