[asterisk-commits] russell: branch 1.4 r81599 - in /branches/1.4: include/asterisk/ main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Sep 5 15:53:41 CDT 2007


Author: russell
Date: Wed Sep  5 15:53:41 2007
New Revision: 81599

URL: http://svn.digium.com/view/asterisk?view=rev&rev=81599
Log:
Fix an issue that can occur when you do an attended transfer to parking.  If
you complete the transfer before the announcement of the parking spot finishes,
then the channel being parked will hear the remainder of the announcement.
These changes make it so that will not happen anymore.

Basically, res_features sets a flag on the channel is playing the announcement
to so that the file streaming core knows that it needs to watch out for a
channel masquerade, and if it occurs, to abort the announcement.

(closes BE-182)

Modified:
    branches/1.4/include/asterisk/channel.h
    branches/1.4/include/asterisk/file.h
    branches/1.4/main/file.c
    branches/1.4/main/say.c
    branches/1.4/res/res_features.c

Modified: branches/1.4/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/branches/1.4/include/asterisk/channel.h?view=diff&rev=81599&r1=81598&r2=81599
==============================================================================
--- branches/1.4/include/asterisk/channel.h (original)
+++ branches/1.4/include/asterisk/channel.h Wed Sep  5 15:53:41 2007
@@ -478,6 +478,9 @@
 	/*! This is set to tell the channel not to generate DTMF begin frames, and
 	 *  to instead only generate END frames. */
 	AST_FLAG_END_DTMF_ONLY = (1 << 14),
+	/*! This flag indicates that on a masquerade, an active stream should not
+	 *  be carried over */
+	AST_FLAG_MASQ_NOSTREAM = (1 << 15),
 };
 
 /*! \brief ast_bridge_config flags */

Modified: branches/1.4/include/asterisk/file.h
URL: http://svn.digium.com/view/asterisk/branches/1.4/include/asterisk/file.h?view=diff&rev=81599&r1=81598&r2=81599
==============================================================================
--- branches/1.4/include/asterisk/file.h (original)
+++ branches/1.4/include/asterisk/file.h Wed Sep  5 15:53:41 2007
@@ -129,6 +129,7 @@
 	int lastwriteformat;
 	int lasttimeout;
 	struct ast_channel *owner;
+	const char *orig_chan_name;
 	FILE *f;
 	struct ast_frame fr;	/* frame produced by read, typically */
 	char *buf;		/* buffer pointed to by ast_frame; */

Modified: branches/1.4/main/file.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/file.c?view=diff&rev=81599&r1=81598&r2=81599
==============================================================================
--- branches/1.4/main/file.c (original)
+++ branches/1.4/main/file.c Wed Sep  5 15:53:41 2007
@@ -614,39 +614,68 @@
 	return f;
 }
 
-static int ast_readaudio_callback(void *data)
-{
-	struct ast_filestream *s = data;
+enum fsread_res {
+	FSREAD_FAILURE,
+	FSREAD_SUCCESS_SCHED,
+	FSREAD_SUCCESS_NOSCHED,
+};
+
+static int ast_fsread_audio(void *data);
+
+static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
+{
 	int whennext = 0;
 
-	while(!whennext) {
-		struct ast_frame *fr = s->fmt->read(s, &whennext);
+	while (!whennext) {
+		struct ast_frame *fr;
+		
+		if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name))
+			goto return_failure;
+		
+		fr = s->fmt->read(s, &whennext);
 		if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
 			if (fr)
 				ast_log(LOG_WARNING, "Failed to write frame\n");
-			s->owner->streamid = -1;
-#ifdef HAVE_ZAPTEL
-			ast_settimeout(s->owner, 0, NULL, NULL);
-#endif			
-			return 0;
+			goto return_failure;
 		}
 	}
 	if (whennext != s->lasttimeout) {
 #ifdef HAVE_ZAPTEL
 		if (s->owner->timingfd > -1)
-			ast_settimeout(s->owner, whennext, ast_readaudio_callback, s);
+			ast_settimeout(s->owner, whennext, ast_fsread_audio, s);
 		else
 #endif		
-			s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s);
+			s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_fsread_audio, s);
 		s->lasttimeout = whennext;
-		return 0;
-	}
-	return 1;
-}
-
-static int ast_readvideo_callback(void *data)
-{
-	struct ast_filestream *s = data;
+		return FSREAD_SUCCESS_NOSCHED;
+	}
+	return FSREAD_SUCCESS_SCHED;
+
+return_failure:
+	s->owner->streamid = -1;
+#ifdef HAVE_ZAPTEL
+	ast_settimeout(s->owner, 0, NULL, NULL);
+#endif			
+	return FSREAD_FAILURE;
+}
+
+static int ast_fsread_audio(void *data)
+{
+	struct ast_filestream *fs = data;
+	enum fsread_res res;
+
+	res = ast_readaudio_callback(fs);
+
+	if (res == FSREAD_SUCCESS_SCHED)
+		return 1;
+	
+	return 0;
+}
+
+static int ast_fsread_video(void *data);
+
+static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
+{
 	int whennext = 0;
 
 	while (!whennext) {
@@ -655,15 +684,31 @@
 			if (fr)
 				ast_log(LOG_WARNING, "Failed to write frame\n");
 			s->owner->vstreamid = -1;
-			return 0;
-		}
-	}
+			return FSREAD_FAILURE;
+		}
+	}
+
 	if (whennext != s->lasttimeout) {
-		s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext/8, ast_readvideo_callback, s);
+		s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext / 8, 
+			ast_fsread_video, s);
 		s->lasttimeout = whennext;
-		return 0;
-	}
-	return 1;
+		return FSREAD_SUCCESS_NOSCHED;
+	}
+
+	return FSREAD_SUCCESS_SCHED;
+}
+
+static int ast_fsread_video(void *data)
+{
+	struct ast_filestream *fs = data;
+	enum fsread_res res;
+
+	res = ast_readvideo_callback(fs);
+
+	if (res == FSREAD_SUCCESS_SCHED)
+		return 1;
+	
+	return 0;
 }
 
 int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
@@ -674,11 +719,14 @@
 
 int ast_playstream(struct ast_filestream *s)
 {
+	enum fsread_res res;
+
 	if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
-		ast_readaudio_callback(s);
+		res = ast_readaudio_callback(s);
 	else
-		ast_readvideo_callback(s);
-	return 0;
+		res = ast_readvideo_callback(s);
+
+	return (res == FSREAD_FAILURE) ? -1 : 0;
 }
 
 int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
@@ -748,6 +796,8 @@
 	fclose(f->f);
 	if (f->vfs)
 		ast_closestream(f->vfs);
+	if (f->orig_chan_name)
+		free((void *) f->orig_chan_name);
 	ast_module_unref(f->fmt->module);
 	free(f);
 	return 0;
@@ -798,17 +848,20 @@
 	if (vfs)
 		ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
 	if (fs){
+		int res;
+		if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
+			fs->orig_chan_name = ast_strdup(chan->name);
 		if (ast_applystream(chan, fs))
 			return -1;
 		if (vfs && ast_applystream(chan, vfs))
 			return -1;
-		ast_playstream(fs);
-		if (vfs)
-			ast_playstream(vfs);
+		res = ast_playstream(fs);
+		if (!res && vfs)
+			res = ast_playstream(vfs);
 		if (option_verbose > 2)
 			ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default");
 
-		return 0;
+		return res;
 	}
 	ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
 	return -1;
@@ -997,6 +1050,9 @@
 	const char *forward, const char *rewind, int skip_ms,
 	int audiofd, int cmdfd,  const char *context)
 {
+	const char *orig_chan_name = NULL;
+	int err = 0;
+
 	if (!breakon)
 		breakon = "";
 	if (!forward)
@@ -1006,10 +1062,22 @@
 
 	/* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
 	ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
-	
+
+	if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM))
+		orig_chan_name = ast_strdupa(c->name);
+
 	while (c->stream) {
 		int res;
-		int ms = ast_sched_wait(c->sched);
+		int ms;
+
+		if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) {
+			ast_stopstream(c);
+			err = 1;
+			break;
+		}
+
+		ms = ast_sched_wait(c->sched);
+
 		if (ms < 0 && !c->timingfunc) {
 			ast_stopstream(c);
 			break;
@@ -1104,7 +1172,7 @@
 
 	ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 
-	return (c->_softhangup ? -1 : 0);
+	return (err || c->_softhangup) ? -1 : 0;
 }
 
 int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)

Modified: branches/1.4/main/say.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/say.c?view=diff&rev=81599&r1=81598&r2=81599
==============================================================================
--- branches/1.4/main/say.c (original)
+++ branches/1.4/main/say.c Wed Sep  5 15:53:41 2007
@@ -258,9 +258,9 @@
 			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);
+					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+				else
+					res = ast_waitstream(chan, ints);
 			}
 			ast_stopstream(chan);
 		}

Modified: branches/1.4/res/res_features.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_features.c?view=diff&rev=81599&r1=81598&r2=81599
==============================================================================
--- branches/1.4/res/res_features.c (original)
+++ branches/1.4/res/res_features.c Wed Sep  5 15:53:41 2007
@@ -422,8 +422,12 @@
 	if (!con)	/* Still no context? Bad */
 		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
 	/* Tell the peer channel the number of the parking space */
-	if (peer && pu->parkingnum != -1) /* Only say number if it's a number */
+	if (peer && pu->parkingnum != -1) { /* Only say number if it's a number */
+		/* Make sure we don't start saying digits to the channel being parked */
+		ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
 		ast_say_digits(peer, pu->parkingnum, "", peer->language);
+		ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
+	}
 	if (con) {
 		if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, strdup(pu->parkingexten), ast_free, registrar))
 			notify_metermaids(pu->parkingexten, parking_con);




More information about the asterisk-commits mailing list