[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