[asterisk-commits] russell: branch russell/events r123645 - in /team/russell/events: ./ apps/ ch...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jun 18 04:45:47 CDT 2008


Author: russell
Date: Wed Jun 18 04:45:43 2008
New Revision: 123645

URL: http://svn.digium.com/view/asterisk?view=rev&rev=123645
Log:
resolve, reset

Modified:
    team/russell/events/   (props changed)
    team/russell/events/apps/app_externalivr.c
    team/russell/events/apps/app_talkdetect.c
    team/russell/events/channels/chan_sip.c
    team/russell/events/include/asterisk/tcptls.h
    team/russell/events/main/astobj2.c
    team/russell/events/main/http.c
    team/russell/events/main/manager.c
    team/russell/events/main/tcptls.c
    team/russell/events/res/res_agi.c

Propchange: team/russell/events/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/russell/events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Jun 18 04:45:43 2008
@@ -1,1 +1,1 @@
-/trunk:1-123527
+/trunk:1-123644

Modified: team/russell/events/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_externalivr.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/apps/app_externalivr.c (original)
+++ team/russell/events/apps/app_externalivr.c Wed Jun 18 04:45:43 2008
@@ -515,8 +515,7 @@
 	if (child_stderr[1])
 		close(child_stderr[1]);
 	if (ser) {
-		fclose(ser->f);
-		ast_tcptls_session_instance_destroy(ser);
+		ao2_ref(ser, -1);
 	}
 	while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
 		ast_free(entry);

Modified: team/russell/events/apps/app_talkdetect.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_talkdetect.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/apps/app_talkdetect.c (original)
+++ team/russell/events/apps/app_talkdetect.c Wed Jun 18 04:45:43 2008
@@ -44,15 +44,15 @@
 static char *synopsis = "Background a file with talk detect";
 
 static char *descrip = 
-"  BackgroundDetect(filename[,sil[,min,[max]]]):  Plays  back  a  given\n"
-"filename, waiting for interruption from a given digit (the digit must\n"
-"start the beginning of a valid extension, or it will be ignored).\n"
-"During the playback of the file, audio is monitored in the receive\n"
-"direction, and if a period of non-silence which is greater than 'min' ms\n"
-"yet less than 'max' ms is followed by silence for at least 'sil' ms then\n"
-"the audio playback is aborted and processing jumps to the 'talk' extension\n"
-"if available.  If unspecified, sil, min, and max default to 1000, 100, and\n"
-"infinity respectively.\n";
+"  BackgroundDetect(<filename>[,<sil>[,<min>[,<max>[,<analysistime>]]]]):\n"
+"Plays back <filename>, waiting for interruption from a given digit (the digit\n"
+"must start the beginning of a valid extension, or it will be ignored).  During\n"
+"the playback of the file, audio is monitored in the receive direction, and if\n"
+"a period of non-silence which is greater than <min> ms yet less than <max> ms\n"
+"is followed by silence for at least <sil> ms, which occurs during the first\n"
+"<analysistime> ms, then the audio playback is aborted and processing jumps to\n"
+"the <talk> extension, if available.  If unspecified, <sil>, <min>, <max>, and\n"
+"<analysistime> default to 1000, 100, infinity, and infinity respectively.\n";
 
 
 static int background_detect_exec(struct ast_channel *chan, void *data)
@@ -61,18 +61,22 @@
 	char *tmp;
 	struct ast_frame *fr;
 	int notsilent = 0;
-	struct timeval start = { 0, 0};
+	struct timeval start = { 0, 0 };
+	struct timeval detection_start = { 0, 0 };
 	int sil = 1000;
 	int min = 100;
 	int max = -1;
+	int analysistime = -1;
+	int continue_analysis = 1;
 	int x;
-	int origrformat=0;
+	int origrformat = 0;
 	struct ast_dsp *dsp = NULL;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(filename);
 		AST_APP_ARG(silence);
 		AST_APP_ARG(min);
 		AST_APP_ARG(max);
+		AST_APP_ARG(analysistime);
 	);
 	
 	if (ast_strlen_zero(data)) {
@@ -83,18 +87,25 @@
 	tmp = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, tmp);
 
-	if (!ast_strlen_zero(args.silence) && (sscanf(args.silence, "%d", &x) == 1) && (x > 0))
+	if (!ast_strlen_zero(args.silence) && (sscanf(args.silence, "%d", &x) == 1) && (x > 0)) {
 		sil = x;
-	if (!ast_strlen_zero(args.min) && (sscanf(args.min, "%d", &x) == 1) && (x > 0))
+	}
+	if (!ast_strlen_zero(args.min) && (sscanf(args.min, "%d", &x) == 1) && (x > 0)) {
 		min = x;
-	if (!ast_strlen_zero(args.max) && (sscanf(args.max, "%d", &x) == 1) && (x > 0))
+	}
+	if (!ast_strlen_zero(args.max) && (sscanf(args.max, "%d", &x) == 1) && (x > 0)) {
 		max = x;
-
-	ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d\n", args.filename, sil, min, max);
+	}
+	if (!ast_strlen_zero(args.analysistime) && (sscanf(args.analysistime, "%d", &x) == 1) && (x > 0)) {
+		analysistime = x;
+	}
+
+	ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d, analysistime=%d\n", args.filename, sil, min, max, analysistime);
 	do {
 		if (chan->_state != AST_STATE_UP) {
-			if ((res = ast_answer(chan)))
+			if ((res = ast_answer(chan))) {
 				break;
+			}
 		}
 
 		origrformat = chan->readformat;
@@ -114,21 +125,31 @@
 			ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
 			break;
 		}
-
+		detection_start = ast_tvnow();
 		while (chan->stream) {
 			res = ast_sched_wait(chan->sched);
 			if ((res < 0) && !chan->timingfunc) {
 				res = 0;
 				break;
 			}
-			if (res < 0)
+			if (res < 0) {
 				res = 1000;
+			}
 			res = ast_waitfor(chan, res);
 			if (res < 0) {
 				ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
 				break;
 			} else if (res > 0) {
 				fr = ast_read(chan);
+				if (continue_analysis && analysistime >= 0) {
+					/* If we have a limit for the time to analyze voice
+					 * frames and the time has not expired */
+					if (ast_tvdiff_ms(ast_tvnow(), detection_start) >= analysistime) {
+						continue_analysis = 0;
+						ast_verb(3, "BackgroundDetect: Talk analysis time complete on %s.\n", chan->name);
+					}
+				}
+				
 				if (!fr) {
 					res = -1;
 					break;
@@ -142,7 +163,7 @@
 						ast_frfree(fr);
 						break;
 					}
-				} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
+				} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR) && continue_analysis) {
 					int totalsilence;
 					int ms;
 					res = ast_dsp_silence(dsp, fr, &totalsilence);
@@ -155,11 +176,11 @@
 							if (ms < 0)
 								ms = 0;
 							if ((ms > min) && ((max < 0) || (ms < max))) {
-								char ms_str[10];
+								char ms_str[12];
 								ast_debug(1, "Found qualified token of %d ms\n", ms);
 
 								/* Save detected talk time (in milliseconds) */ 
-								sprintf(ms_str, "%d", ms );	
+								snprintf(ms_str, sizeof(ms_str), "%d", ms);	
 								pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
 
 								ast_goto_if_exists(chan, chan->context, "talk", 1);
@@ -193,8 +214,9 @@
 				chan->name, ast_getformatname(origrformat));
 		}
 	}
-	if (dsp)
+	if (dsp) {
 		ast_dsp_free(dsp);
+	}
 	return res;
 }
 

Modified: team/russell/events/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_sip.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/channels/chan_sip.c (original)
+++ team/russell/events/channels/chan_sip.c Wed Jun 18 04:45:43 2008
@@ -798,7 +798,6 @@
 
 /*!< The SIP socket definition */
 struct sip_socket {
-	ast_mutex_t *lock;
 	enum sip_transport type;
 	int fd;
 	uint16_t port;
@@ -844,6 +843,7 @@
 	char *header[SIP_MAX_HEADERS];
 	char *line[SIP_MAX_LINES];
 	struct ast_str *data;	
+	/* XXX Do we need to unref socket.ser when the request goes away? */
 	struct sip_socket socket;	/*!< The socket used for this request */
 };
 
@@ -2291,14 +2291,6 @@
 
 static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *ser);
 
-static void *sip_tcp_helper_thread(void *data)
-{
-	struct sip_pvt *pvt = data;
-	struct ast_tcptls_session_instance *ser = pvt->socket.ser;
-
-	return _sip_tcp_helper_thread(pvt, ser);
-}
-
 static void *sip_tcp_worker_fn(void *data)
 {
 	struct ast_tcptls_session_instance *ser = data;
@@ -2312,7 +2304,7 @@
 	int res, cl;
 	struct sip_request req = { 0, } , reqcpy = { 0, };
 	struct sip_threadinfo *me;
-	char buf[1024];
+	char buf[1024] = "";
 
 	me = ast_calloc(1, sizeof(*me));
 
@@ -2330,12 +2322,6 @@
 	AST_LIST_INSERT_TAIL(&threadl, me, list);
 	AST_LIST_UNLOCK(&threadl);
 
-	req.socket.lock = ast_calloc(1, sizeof(*req.socket.lock));
-
-	if (!req.socket.lock)
-		goto cleanup;
-
-	ast_mutex_init(req.socket.lock);
 	if (!(req.data = ast_str_create(SIP_MIN_PACKET)))
 		goto cleanup;
 	if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET)))
@@ -2364,14 +2350,12 @@
 
 		/* Read in headers one line at a time */
 		while (req.len < 4 || strncmp((char *)&req.data->str + req.len - 4, "\r\n\r\n", 4)) {
-			if (req.socket.lock) 
-				ast_mutex_lock(req.socket.lock);
+			ast_mutex_lock(&ser->lock);
 			if (!fgets(buf, sizeof(buf), ser->f)) {
-				ast_mutex_unlock(req.socket.lock);
+				ast_mutex_unlock(&ser->lock);
 				goto cleanup;
 			}
-			if (req.socket.lock) 
-				ast_mutex_unlock(req.socket.lock);
+			ast_mutex_unlock(&ser->lock);
 			if (me->stop) 
 				 goto cleanup;
 			ast_str_append(&req.data, 0, "%s", buf);
@@ -2381,12 +2365,12 @@
 		parse_request(&reqcpy);
 		if (sscanf(get_header(&reqcpy, "Content-Length"), "%d", &cl)) {
 			while (cl > 0) {
-				if (req.socket.lock) 
-					ast_mutex_lock(req.socket.lock);
-				if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, ser->f))
+				ast_mutex_lock(&ser->lock);
+				if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, ser->f)) {
+					ast_mutex_unlock(&ser->lock);
 					goto cleanup;
-				if (req.socket.lock) 
-					ast_mutex_unlock(req.socket.lock);
+				}
+				ast_mutex_unlock(&ser->lock);
 				if (me->stop)
 					goto cleanup;
 				cl -= strlen(buf);
@@ -2405,7 +2389,8 @@
 	ast_free(me);
 cleanup2:
 	fclose(ser->f);
-	ser = ast_tcptls_session_instance_destroy(ser);
+	ser->f = NULL;
+	ser->fd = -1;
 	if (reqcpy.data)
 		ast_free(reqcpy.data);
 	if (req.data) {
@@ -2414,11 +2399,8 @@
 	}
 	
 
-	if (req.socket.lock) {
-		ast_mutex_destroy(req.socket.lock);
-		ast_free(req.socket.lock);
-		req.socket.lock = NULL;
-	}
+	ao2_ref(ser, -1);
+	ser = NULL;
 
 	return NULL;
 }
@@ -2761,8 +2743,8 @@
 	if (sip_prepare_socket(p) < 0)
 		return XMIT_ERROR;
 
-	if (p->socket.lock)
-		ast_mutex_lock(p->socket.lock);
+	if (p->socket.ser)
+		ast_mutex_lock(&p->socket.ser->lock);
 
 	if (p->socket.type & SIP_TRANSPORT_UDP) 
 		res = sendto(p->socket.fd, data->str, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
@@ -2773,8 +2755,8 @@
 			ast_debug(1, "No p->socket.ser->f len=%d\n", len);
 	} 
 
-	if (p->socket.lock)
-		ast_mutex_unlock(p->socket.lock);
+	if (p->socket.ser)
+		ast_mutex_unlock(&p->socket.ser->lock);
 
 	if (res == -1) {
 		switch (errno) {
@@ -3780,6 +3762,11 @@
 	if (peer->dnsmgr)
 		ast_dnsmgr_release(peer->dnsmgr);
 	clear_peer_mailboxes(peer);
+
+	if (peer->socket.ser) {
+		ao2_ref(peer->socket.ser, -1);
+		peer->socket.ser = NULL;
+	}
 }
 
 /*! \brief Update peer data in database (if used) */
@@ -4201,6 +4188,20 @@
 	}
 }
 
+static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket *from_sock)
+{
+	if (to_sock->ser) {
+		ao2_ref(to_sock->ser, -1);
+		to_sock->ser = NULL;
+	}
+
+	if (from_sock->ser) {
+		ao2_ref(from_sock->ser, +1);
+	}
+
+	*to_sock = *from_sock;
+}
+
 /*! \brief Create address structure from peer reference.
  *	This function copies data from peer to the dialog, so we don't have to look up the peer
  *	again from memory or database during the life time of the dialog.
@@ -4210,7 +4211,7 @@
  */
 static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
 {
-	dialog->socket = peer->socket;
+	copy_socket_data(&dialog->socket, &peer->socket);
 
 	if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
 	    (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
@@ -4652,7 +4653,11 @@
 	}
 
 	ast_string_field_free_memory(p);
-	return;
+
+	if (p->socket.ser) {
+		ao2_ref(p->socket.ser, -1);
+		p->socket.ser = NULL;
+	}
 }
 
 /*! \brief  update_call_counter: Handle call_limit for SIP users 
@@ -7946,11 +7951,7 @@
 	build_via(p);
 	ast_string_field_set(p, callid, callid);
 
-	p->socket.lock = req->socket.lock;
-	p->socket.type = req->socket.type;
-	p->socket.fd = req->socket.fd;
-	p->socket.port = req->socket.port;
-	p->socket.ser = req->socket.ser;
+	copy_socket_data(&p->socket, &req->socket);
 
 	/* Use this temporary pvt structure to send the message */
 	__transmit_response(p, msg, req, XMIT_UNRELIABLE);
@@ -10317,7 +10318,8 @@
 		}
 	}
 
-	pvt->socket = peer->socket = req->socket;
+	copy_socket_data(&peer->socket, &req->socket);
+	copy_socket_data(&pvt->socket, &peer->socket);
 
 	/* Look for brackets */
 	curi = contact;
@@ -19436,7 +19438,6 @@
 	req.socket.type = SIP_TRANSPORT_UDP;
 	req.socket.ser	= NULL;
 	req.socket.port = bindaddr.sin_port;
-	req.socket.lock = NULL;
 
 	handle_request_do(&req, &sin);
 	if (req.data) {
@@ -19491,7 +19492,7 @@
 			return 1;
 		}
 
-		p->socket = req->socket;
+		copy_socket_data(&p->socket, &req->socket);
 
 		/* Go ahead and lock the owner if it has one -- we may need it */
 		/* becaues this is deadlock-prone, we need to try and unlock if failed */
@@ -19589,13 +19590,18 @@
 
 	if ((ser = sip_tcp_locate(&ca.sin))) {
 		s->fd = ser->fd;
+		if (s->ser) {
+			ao2_ref(s->ser, -1);
+			s->ser = NULL;
+		}
+		ao2_ref(ser, +1);
 		s->ser = ser;
 		return s->fd;
 	}
 
-	if (s->ser && s->ser->parent->tls_cfg) 
+	if (s->ser && s->ser->parent->tls_cfg) {
 		ca.tls_cfg = s->ser->parent->tls_cfg;
-	else {
+	} else {
 		if (s->type & SIP_TRANSPORT_TLS) {
 			ca.tls_cfg = ast_calloc(1, sizeof(*ca.tls_cfg));
 			if (!ca.tls_cfg)
@@ -19605,7 +19611,12 @@
 				ast_copy_string(ca.hostname, p->tohost, sizeof(ca.hostname));
 		}
 	}
-	s->ser = (!s->ser) ? ast_tcptls_client_start(&ca) : s->ser;
+	
+	if (s->ser) {
+		/* the pvt socket already has a server instance ... */
+	} else {
+		s->ser = ast_tcptls_client_start(&ca);
+	}
 
 	if (!s->ser) {
 		if (ca.tls_cfg)
@@ -19615,8 +19626,12 @@
 
 	s->fd = ca.accept_fd;
 
-	if (ast_pthread_create_background(&ca.master, NULL, sip_tcp_helper_thread, p)) {
+	/* Give the new thread a reference */
+	ao2_ref(s->ser, +1);
+
+	if (ast_pthread_create_background(&ca.master, NULL, sip_tcp_worker_fn, s->ser)) {
 		ast_debug(1, "Unable to launch '%s'.", ca.name);
+		ao2_ref(s->ser, -1);
 		close(ca.accept_fd);
 		s->fd = ca.accept_fd = -1;
 	}

Modified: team/russell/events/include/asterisk/tcptls.h
URL: http://svn.digium.com/view/asterisk/team/russell/events/include/asterisk/tcptls.h?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/include/asterisk/tcptls.h (original)
+++ team/russell/events/include/asterisk/tcptls.h Wed Jun 18 04:45:43 2008
@@ -52,6 +52,7 @@
 #include <fcntl.h>
 
 #include "asterisk/utils.h"
+#include "asterisk/astobj2.h"
 
 #if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
 #define DO_SSL  /* comment in/out if you want to support ssl */
@@ -130,6 +131,7 @@
 	struct sockaddr_in requestor;
 	struct server_args *parent;
 	pthread_t worker_thread;
+	ast_mutex_t lock;
 };
 
 /*! \brief
@@ -169,11 +171,4 @@
 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *ser, void *buf, size_t count);
 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, void *buf, size_t count);
 
-/*!
- * \brief Destroy a server instance
- *
- * \return NULL for convenience
- */
-struct ast_tcptls_session_instance *ast_tcptls_session_instance_destroy(struct ast_tcptls_session_instance *i);
-
 #endif /* _ASTERISK_SERVER_H */

Modified: team/russell/events/main/astobj2.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/astobj2.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/main/astobj2.c (original)
+++ team/russell/events/main/astobj2.c Wed Jun 18 04:45:43 2008
@@ -934,7 +934,7 @@
 		 * right here so that when the container is unreffed later, the
 		 * objects will be freed
 		 */
-		ao2_t_ref(obj, -1, test);
+		ao2_t_ref(obj, -1, "test");
 	}
 	ast_cli(a->fd, "testing callbacks\n");
 	ao2_t_callback(c1, 0, print_cb, &a->fd,"test callback");

Modified: team/russell/events/main/http.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/http.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/main/http.c (original)
+++ team/russell/events/main/http.c Wed Jun 18 04:45:43 2008
@@ -736,7 +736,8 @@
 
 done:
 	fclose(ser->f);
-	ser = ast_tcptls_session_instance_destroy(ser);
+	ao2_ref(ser, -1);
+	ser = NULL;
 
 	return NULL;
 }

Modified: team/russell/events/main/manager.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/manager.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/main/manager.c (original)
+++ team/russell/events/main/manager.c Wed Jun 18 04:45:43 2008
@@ -3089,7 +3089,8 @@
 	destroy_session(s);
 
 done:
-	ser = ast_tcptls_session_instance_destroy(ser);
+	ao2_ref(ser, -1);
+	ser = NULL;
 	return NULL;
 }
 

Modified: team/russell/events/main/tcptls.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/tcptls.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/main/tcptls.c (original)
+++ team/russell/events/main/tcptls.c Wed Jun 18 04:45:43 2008
@@ -83,6 +83,12 @@
 
 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *ser, void *buf, size_t count)
 {
+	if (ser->fd == -1) {
+		ast_log(LOG_ERROR, "server_read called with an fd of -1\n");
+		errno = EIO;
+		return -1;
+	}
+
 #ifdef DO_SSL
 	if (ser->ssl)
 		return ssl_read(ser->ssl, buf, count);
@@ -92,11 +98,23 @@
 
 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, void *buf, size_t count)
 {
+	if (ser->fd == -1) {
+		ast_log(LOG_ERROR, "server_write called with an fd of -1\n");
+		errno = EIO;
+		return -1;
+	}
+
 #ifdef DO_SSL
 	if (ser->ssl)
 		return ssl_write(ser->ssl, buf, count);
 #endif
 	return write(ser->fd, buf, count);
+}
+
+static void session_instance_destructor(void *obj)
+{
+	struct ast_tcptls_session_instance *i = obj;
+	ast_mutex_destroy(&i->lock);
 }
 
 void *ast_tcptls_server_root(void *data)
@@ -122,12 +140,15 @@
 				ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
 			continue;
 		}
-		ser = ast_calloc(1, sizeof(*ser));
+		ser = ao2_alloc(sizeof(*ser), session_instance_destructor);
 		if (!ser) {
 			ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
 			close(fd);
 			continue;
 		}
+
+		ast_mutex_init(&ser->lock);
+
 		flags = fcntl(fd, F_GETFL);
 		fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
 		ser->fd = fd;
@@ -139,7 +160,7 @@
 		if (ast_pthread_create_detached_background(&ser->worker_thread, NULL, ast_make_file_from_fd, ser)) {
 			ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
 			close(ser->fd);
-			ast_free(ser);
+			ao2_ref(ser, -1);
 		}
 	}
 	return NULL;
@@ -234,8 +255,10 @@
 		goto error;
 	}
 
-	if (!(ser = ast_calloc(1, sizeof(*ser))))
-		goto error;
+	if (!(ser = ao2_alloc(sizeof(*ser), session_instance_destructor)))
+		goto error;
+
+	ast_mutex_init(&ser->lock);
 
 	flags = fcntl(desc->accept_fd, F_GETFL);
 	fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
@@ -261,7 +284,7 @@
 	close(desc->accept_fd);
 	desc->accept_fd = -1;
 	if (ser)
-		ast_free(ser);
+		ao2_ref(ser, -1);
 	return NULL;
 }
 
@@ -446,8 +469,3 @@
 		return ser;
 }
 
-struct ast_tcptls_session_instance *ast_tcptls_session_instance_destroy(struct ast_tcptls_session_instance *i)
-{
-	ast_free(i);
-	return NULL;
-}

Modified: team/russell/events/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/res/res_agi.c?view=diff&rev=123645&r1=123644&r2=123645
==============================================================================
--- team/russell/events/res/res_agi.c (original)
+++ team/russell/events/res/res_agi.c Wed Jun 18 04:45:43 2008
@@ -20,7 +20,7 @@
  *
  * \brief AGI - the Asterisk Gateway Interface
  *
- * \author Mark Spencer <markster at digium.com> 
+ * \author Mark Spencer <markster at digium.com>
  */
 
 #include "asterisk.h"
@@ -162,9 +162,9 @@
 	struct agi_cmd *cmd;
 	AST_LIST_HEAD(, agi_cmd) *chan_cmds = data;
 	AST_LIST_LOCK(chan_cmds);
-	while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) { 
+	while ( (cmd = AST_LIST_REMOVE_HEAD(chan_cmds, entry)) ) {
 		free_agi_cmd(cmd);
-	} 
+	}
 	AST_LIST_UNLOCK(chan_cmds);
 	AST_LIST_HEAD_DESTROY(chan_cmds);
 	ast_free(chan_cmds);
@@ -248,7 +248,7 @@
 	datastore = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
 	ast_channel_unlock(chan);
 	if (datastore) {
-		/* we already have an AGI datastore, let's just 
+		/* we already have an AGI datastore, let's just
 		   return success */
 		return 0;
 	}
@@ -274,9 +274,9 @@
 }
 
 /*!
- * \brief CLI command to add applications to execute in Async AGI 
+ * \brief CLI command to add applications to execute in Async AGI
  * \param e
- * \param cmd 
+ * \param cmd
  * \param a
  *
  * \retval CLI_SUCCESS on success
@@ -322,7 +322,7 @@
  * It will append the application to the specified channel's queue
  * if the channel is not inside Async AGI application it will return an error
  * \retval 0 on success or incorrect use
- * \retval 1 on failure to add the command ( most likely because the channel 
+ * \retval 1 on failure to add the command ( most likely because the channel
  * is not in Async AGI loop )
 */
 static int action_add_agi_cmd(struct mansession *s, const struct message *m)
@@ -358,20 +358,20 @@
 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
 {
 /* This buffer sizes might cause truncation if the AGI command writes more data
-   than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command 
-   that writes a response larger than 1024 bytes?, I don't think so, most of 
-   them are just result=blah stuff. However probably if GET VARIABLE is called 
-   and the variable has large amount of data, that could be a problem. We could 
+   than AGI_BUF_SIZE as result. But let's be serious, is there an AGI command
+   that writes a response larger than 1024 bytes?, I don't think so, most of
+   them are just result=blah stuff. However probably if GET VARIABLE is called
+   and the variable has large amount of data, that could be a problem. We could
    make this buffers dynamic, but let's leave that as a second step.
 
-   AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe 
-   number. Some characters of AGI buf will be url encoded to be sent to manager 
-   clients.  An URL encoded character will take 3 bytes, but again, to cause 
-   truncation more than about 70% of the AGI buffer should be URL encoded for 
-   that to happen.  Not likely at all. 
-
-   On the other hand. I wonder if read() could eventually return less data than 
-   the amount already available in the pipe? If so, how to deal with that?  
+   AMI_BUF_SIZE is twice AGI_BUF_SIZE just for the sake of choosing a safe
+   number. Some characters of AGI buf will be url encoded to be sent to manager
+   clients.  An URL encoded character will take 3 bytes, but again, to cause
+   truncation more than about 70% of the AGI buffer should be URL encoded for
+   that to happen.  Not likely at all.
+
+   On the other hand. I wonder if read() could eventually return less data than
+   the amount already available in the pipe? If so, how to deal with that?
    So far, my tests on Linux have not had any problems.
  */
 #define AGI_BUF_SIZE 1024
@@ -379,7 +379,7 @@
 	struct ast_frame *f;
 	struct agi_cmd *cmd;
 	int res, fds[2];
-	int timeout = 100; 
+	int timeout = 100;
 	char agi_buffer[AGI_BUF_SIZE + 1];
 	char ami_buffer[AMI_BUF_SIZE];
 	enum agi_result returnstatus = AGI_RESULT_SUCCESS_ASYNC;
@@ -394,28 +394,28 @@
 	if (add_to_agi(chan)) {
 		ast_log(LOG_ERROR, "failed to start Async AGI on channel %s\n", chan->name);
 		return AGI_RESULT_FAILURE;
-	}	
-
-	/* this pipe allows us to create a "fake" AGI struct to use 
+	}
+
+	/* this pipe allows us to create a "fake" AGI struct to use
 	   the AGI commands */
 	res = pipe(fds);
 	if (res) {
 		ast_log(LOG_ERROR, "failed to create Async AGI pipe\n");
-		/* intentionally do not remove datastore, added with 
-		   add_to_agi(), from channel. It will be removed when 
+		/* intentionally do not remove datastore, added with
+		   add_to_agi(), from channel. It will be removed when
 		   the channel is hung up anyways */
 		return AGI_RESULT_FAILURE;
 	}
 
-	/* handlers will get the pipe write fd and we read the AGI responses 
+	/* handlers will get the pipe write fd and we read the AGI responses
 	   from the pipe read fd */
-	async_agi.fd = fds[1]; 
+	async_agi.fd = fds[1];
 	async_agi.ctrl = fds[1];
 	async_agi.audio = -1; /* no audio support */
 	async_agi.fast = 0;
 
-	/* notify possible manager users of a new channel ready to 
-	   receive commands */	
+	/* notify possible manager users of a new channel ready to
+	   receive commands */
 	setup_env(chan, "async", fds[1], 0, 0, NULL);
 	/* read the environment */
 	res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
@@ -425,29 +425,29 @@
 		goto quit;
 	}
 	agi_buffer[res] = '\0';
-	/* encode it and send it thru the manager so whoever is going to take 
-	   care of AGI commands on this channel can decide which AGI commands 
+	/* encode it and send it thru the manager so whoever is going to take
+	   care of AGI commands on this channel can decide which AGI commands
 	   to execute based on the setup info */
 	ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, 1);
-	manager_event(EVENT_FLAG_CALL, "AsyncAGI", "SubEvent: Start\r\nChannel: %s\r\nEnv: %s\r\n", chan->name, ami_buffer); 
+	manager_event(EVENT_FLAG_CALL, "AsyncAGI", "SubEvent: Start\r\nChannel: %s\r\nEnv: %s\r\n", chan->name, ami_buffer);
 	while (1) {
 		/* bail out if we need to hangup */
 		if (ast_check_hangup(chan)) {
 			ast_log(LOG_DEBUG, "ast_check_hangup returned true on chan %s\n", chan->name);
 			break;
 		}
-		/* retrieve a command 
+		/* retrieve a command
 		   (commands are added via the manager or the cli threads) */
 		cmd = get_agi_cmd(chan);
 		if (cmd) {
-			/* OK, we have a command, let's call the 
+			/* OK, we have a command, let's call the
 			   command handler. */
 			res = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
 			if ((res < 0) || (res == AST_PBX_KEEPALIVE)) {
 				free_agi_cmd(cmd);
 				break;
 			}
-			/* the command handler must have written to our fake 
+			/* the command handler must have written to our fake
 			   AGI struct fd (the pipe), let's read the response */
 			res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
 			if (!res) {
@@ -457,7 +457,7 @@
 				break;
 			}
 			/* we have a response, let's send the response thru the
-			   manager. Include the CommandID if it was specified 
+			   manager. Include the CommandID if it was specified
 			   when the command was added */
 			agi_buffer[res] = '\0';
 			ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, 1);
@@ -481,7 +481,7 @@
 				returnstatus = AGI_RESULT_HANGUP;
 				break;
 			}
-			/* is there any other frame we should care about 
+			/* is there any other frame we should care about
 			   besides AST_CONTROL_HANGUP? */
 			if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
 				ast_log(LOG_DEBUG, "Got HANGUP frame on channel %s, going out ...\n", chan->name);
@@ -492,7 +492,7 @@
 		}
 	}
 quit:
-	/* notify manager users this channel cannot be 
+	/* notify manager users this channel cannot be
 	   controlled anymore by Async AGI */
 	manager_event(EVENT_FLAG_CALL, "AsyncAGI", "SubEvent: End\r\nChannel: %s\r\n", chan->name);
 
@@ -500,14 +500,14 @@
 	close(fds[0]);
 	close(fds[1]);
 
-	/* intentionally don't get rid of the datastore. So commands can be 
+	/* intentionally don't get rid of the datastore. So commands can be
 	   still in the queue in case AsyncAGI gets called again.
 	   Datastore destructor will be called on channel destroy anyway  */
 
 	return returnstatus;
 
-#undef AGI_BUF_SIZE 
-#undef AMI_BUF_SIZE 
+#undef AGI_BUF_SIZE
+#undef AMI_BUF_SIZE
 }
 
 /* launch_netscript: The fastagi handler.
@@ -610,7 +610,7 @@
 		return launch_netscript(script, argv, fds, efd, opid);
 	if (!strncasecmp(script, "agi:async", sizeof("agi:async")-1))
 		return launch_asyncagi(chan, argv, efd);
-	
+
 	if (script[0] != '/') {
 		snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
 		script = tmp;
@@ -642,7 +642,7 @@
 			return AGI_RESULT_FAILURE;
 		}
 		res = fcntl(audio[1], F_GETFL);
-		if (res > -1) 
+		if (res > -1)
 			res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
@@ -811,7 +811,7 @@
 	if (res == 0) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=%d (timeout)\n", res);
 		return RESULT_SUCCESS;
-	} 
+	}
 	if (res > 0) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=%d\n", res);
 		return RESULT_SUCCESS;
@@ -823,7 +823,7 @@
 static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
 {
 	char *buf;
-	
+
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
 
@@ -831,7 +831,7 @@
 	if (buf) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1 (%s)\n", buf);
 		ast_free(buf);
-	} else {	
+	} else {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=-1\n");
 	}
 	return RESULT_SUCCESS;
@@ -845,7 +845,7 @@
 		return RESULT_SHOWUSAGE;
 
 	if (!strncasecmp(argv[2],"on",2)) {
-		x = 1; 
+		x = 1;
 	} else  {
 		x = 0;
 	}
@@ -892,25 +892,25 @@
 	if (!ast_strlen_zero(argv[4])) {
 		stop = argv[4];
 	}
-	
+
 	if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) {
 		return RESULT_SHOWUSAGE;
 	}
 
 	if (argc > 6 && !ast_strlen_zero(argv[6])) {
 		fwd = argv[6];
-	} 
+	}
 
 	if (argc > 7 && !ast_strlen_zero(argv[7])) {
 		rev = argv[7];
 	}
-	
+
 	if (argc > 8 && !ast_strlen_zero(argv[8])) {
 		pause = argv[8];
-	} 
-	
+	}
+
 	res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms, NULL);
-	
+
 	ast_agi_fdprintf(chan, agi->fd, "200 result=%d\n", res);
 
 	return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
@@ -926,7 +926,7 @@
 	if (argc < 4 || argc > 5)
 		return RESULT_SHOWUSAGE;
 
-	if (argv[3]) 
+	if (argv[3])
 		edigits = argv[3];
 
 	if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1))
@@ -939,7 +939,7 @@
 
 	if ((vfs = ast_openvstream(chan, argv[2], chan->language)))
 		ast_debug(1, "Ooh, found a video stream, too\n");
-		
+
 	ast_verb(3, "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
 
 	ast_seekstream(fs, 0, SEEK_END);
@@ -951,7 +951,7 @@
 	ast_playstream(fs);
 	if (vfs)
 		ast_playstream(vfs);
-	
+
 	res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
 	/* this is to check for if ast_waitstream closed the stream, we probably are at
 	 * the end of the stream, return that amount, else check for the amount */
@@ -977,7 +977,7 @@
 	if ( argc < 4 || argc > 5 )
 		return RESULT_SHOWUSAGE;
 
-	if ( argv[3] ) 
+	if ( argv[3] )
 		edigits = argv[3];
 
 	if ( argc == 5 )
@@ -995,7 +995,7 @@
 
 	if ((vfs = ast_openvstream(chan, argv[2], chan->language)))
 		ast_debug(1, "Ooh, found a video stream, too\n");
-	
+
 	ast_verb(3, "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
 
 	ast_seekstream(fs, 0, SEEK_END);
@@ -1115,7 +1115,7 @@
 	int res = 0;
 	time_t unixtime;
 	char *format, *zone = NULL;
-	
+
 	if (argc < 4)
 		return RESULT_SHOWUSAGE;
 
@@ -1126,7 +1126,7 @@
 		if (!strcasecmp(chan->language, "de")) {
 			format = "A dBY HMS";
 		} else {
-			format = "ABdY 'digits/at' IMp"; 
+			format = "ABdY 'digits/at' IMp";
 		}
 	}
 
@@ -1166,11 +1166,11 @@
 	if (argc < 3)
 		return RESULT_SHOWUSAGE;
 	if (argc >= 4)
-		timeout = atoi(argv[3]); 
+		timeout = atoi(argv[3]);
 	else
 		timeout = 0;
-	if (argc >= 5) 
-		max = atoi(argv[4]); 
+	if (argc >= 5)
+		max = atoi(argv[4]);
 	else
 		max = 1024;
 	res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
@@ -1194,7 +1194,7 @@
 	ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	return RESULT_SUCCESS;
 }
-	
+
 static int handle_setextension(struct ast_channel *chan, AGI *agi, int argc, char **argv)
 {
 	if (argc != 3)
@@ -1209,7 +1209,7 @@
 	int pri;
 
 	if (argc != 3)
-		return RESULT_SHOWUSAGE;	
+		return RESULT_SHOWUSAGE;
 
 	if (sscanf(argv[2], "%d", &pri) != 1) {
 		if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
@@ -1220,7 +1220,7 @@
 	ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	return RESULT_SUCCESS;
 }
-		
+
 static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
 {
 	struct ast_filestream *fs;
@@ -1235,9 +1235,8 @@
 	int dspsilence = 0;
 	int silence = 0;                /* amount of silence to allow */
 	int gotsilence = 0;             /* did we timeout for silence? */
-	char *silencestr=NULL;
-	int rfmt=0;
-
+	char *silencestr = NULL;
+	int rfmt = 0;
 
 	/* XXX EAGI FIXME XXX */
 
@@ -1280,7 +1279,7 @@
 		}
 		ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
 	}
-
+	
 	/* backward compatibility, if no offset given, arg[6] would have been
 	 * caught below and taken to be a beep, else if it is a digit then it is a
 	 * offset */
@@ -1303,16 +1302,16 @@
 				ast_dsp_free(sildet);
 			return RESULT_FAILURE;
 		}
-		
+
 		/* Request a video update */
 		ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-	
+
 		chan->stream = fs;
 		ast_applystream(chan,fs);
 		/* really should have checks */
 		ast_seekstream(fs, sample_offset, SEEK_SET);
 		ast_truncstream(fs);
-		
+
 		start = ast_tvnow();
 		while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
 			res = ast_waitfor(chan, -1);
@@ -1380,11 +1379,11 @@
 				break;
 		}
 
-			if (gotsilence) {
-				ast_stream_rewind(fs, silence-1000);
-				ast_truncstream(fs);
-				sample_offset = ast_tellstream(fs);
-		}		
+		if (gotsilence) {
+			ast_stream_rewind(fs, silence-1000);
+			ast_truncstream(fs);
+			sample_offset = ast_tellstream(fs);
+		}
 		ast_agi_fdprintf(chan, agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
 		ast_closestream(fs);
 	}
@@ -1393,8 +1392,9 @@
 		res = ast_set_read_format(chan, rfmt);
 		if (res)
 			ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
-			ast_dsp_free(sildet);
-	}
+		ast_dsp_free(sildet);
+	}
+
 	return RESULT_SUCCESS;
 }
 
@@ -1593,9 +1593,9 @@
 		sscanf(argv[2], "%d", &level);
 
 	ast_verb(level, "%s: %s\n", chan->data, argv[1]);
-	
+
 	ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1607,7 +1607,7 @@
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
 	res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
-	if (res) 
+	if (res)
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	else
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1 (%s)\n", tmp);
@@ -1704,12 +1704,12 @@
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	if ((agi->speech = ast_speech_new(argv[2], AST_FORMAT_SLINEAR)))
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
 	else
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1718,16 +1718,16 @@
 	/* Check for minimum arguments */
         if (argc != 3)
 		return RESULT_SHOWUSAGE;
-	
+
 	/* Check to make sure speech structure exists */
 	if (!agi->speech) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	ast_speech_change(agi->speech, argv[2], argv[3]);
 	ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1740,7 +1740,7 @@
 	} else {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	}
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1748,17 +1748,17 @@
 {
 	if (argc != 5)
 		return RESULT_SHOWUSAGE;
-	
+
 	if (!agi->speech) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	if (ast_speech_grammar_load(agi->speech, argv[3], argv[4]))
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	else
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1766,17 +1766,17 @@
 {
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
-	
+
 	if (!agi->speech) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	if (ast_speech_grammar_unload(agi->speech, argv[3]))
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	else
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1784,17 +1784,17 @@
 {
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
-	
+
 	if (!agi->speech) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	if (ast_speech_grammar_activate(agi->speech, argv[3]))
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	else
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1802,36 +1802,36 @@
 {
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
-	
+
 	if (!agi->speech) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	if (ast_speech_grammar_deactivate(agi->speech, argv[3]))
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	else
 		ast_agi_fdprintf(chan, agi->fd, "200 result=1\n");
-	
+
 	return RESULT_SUCCESS;
 }
 
 static int speech_streamfile(struct ast_channel *chan, const char *filename, const char *preflang, int offset)
 {
 	struct ast_filestream *fs = NULL;
-	
+
 	if (!(fs = ast_openstream(chan, filename, preflang)))
 		return -1;
-	
+
 	if (offset)
 		ast_seekstream(fs, offset, SEEK_SET);
-	
+
 	if (ast_applystream(chan, fs))
 		return -1;
-	
+
 	if (ast_playstream(fs))
 		return -1;
-	
+
 	return 0;
 }
 
@@ -1846,47 +1846,47 @@
 	struct ast_speech_result *result = NULL;
 	size_t left = sizeof(tmp);
 	time_t start = 0, current;
-	
+
 	if (argc < 4)
 		return RESULT_SHOWUSAGE;
-	
+
 	if (!speech) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	prompt = argv[2];
 	timeout = atoi(argv[3]);
-	
+
 	/* If offset is specified then convert from text to integer */
 	if (argc == 5)
 		offset = atoi(argv[4]);
-	
+
 	/* We want frames coming in signed linear */
 	old_read_format = chan->readformat;
 	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
 		ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
-	
+
 	/* Setup speech structure */
 	if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) {
 		ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);
 		ast_speech_start(speech);
 	}
-	
+
 	/* Start playing prompt */
 	speech_streamfile(chan, prompt, chan->language, offset);
-	
+
 	/* Go into loop reading in frames, passing to speech thingy, checking for hangup, all that jazz */
 	while (ast_strlen_zero(reason)) {
 		/* Run scheduled items */

[... 180 lines stripped ...]



More information about the asterisk-commits mailing list