Whitespace only
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@123609 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
bf03be75ff
commit
499e256f2b
268
res/res_agi.c
268
res/res_agi.c
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* \brief AGI - the Asterisk Gateway Interface
|
||||
*
|
||||
* \author Mark Spencer <markster@digium.com>
|
||||
* \author Mark Spencer <markster@digium.com>
|
||||
*/
|
||||
|
||||
#include "asterisk.h"
|
||||
|
@ -162,9 +162,9 @@ static void agi_destroy_commands_cb(void *data)
|
|||
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 @@ static int add_to_agi(struct ast_channel *chan)
|
|||
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 @@ static int add_to_agi(struct ast_channel *chan)
|
|||
}
|
||||
|
||||
/*!
|
||||
* \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 @@ static char *handle_cli_agi_add_cmd(struct ast_cli_entry *e, int cmd, struct ast
|
|||
* 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 void setup_env(struct ast_channel *chan, char *request, int fd, int enhan
|
|||
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.
|
||||
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?
|
||||
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 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i
|
|||
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 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i
|
|||
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 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i
|
|||
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 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i
|
|||
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 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i
|
|||
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 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i
|
|||
}
|
||||
}
|
||||
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 @@ quit:
|
|||
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 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, cha
|
|||
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 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, cha
|
|||
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 @@ static int handle_recvchar(struct ast_channel *chan, AGI *agi, int argc, char *a
|
|||
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_recvchar(struct ast_channel *chan, AGI *agi, int argc, char *a
|
|||
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 @@ static int handle_recvtext(struct ast_channel *chan, AGI *agi, int argc, char *a
|
|||
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 @@ static int handle_tddmode(struct ast_channel *chan, AGI *agi, int argc, char *ar
|
|||
return RESULT_SHOWUSAGE;
|
||||
|
||||
if (!strncasecmp(argv[2],"on",2)) {
|
||||
x = 1;
|
||||
x = 1;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
|
@ -892,25 +892,25 @@ static int handle_controlstreamfile(struct ast_channel *chan, AGI *agi, int argc
|
|||
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 @@ static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
|
||||
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 @@ static int handle_streamfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, char *
|
|||
if ( argc < 4 || argc > 5 )
|
||||
return RESULT_SHOWUSAGE;
|
||||
|
||||
if ( argv[3] )
|
||||
if ( argv[3] )
|
||||
edigits = argv[3];
|
||||
|
||||
if ( argc == 5 )
|
||||
|
@ -995,7 +995,7 @@ static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, char *
|
|||
|
||||
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 @@ static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
int res = 0;
|
||||
time_t unixtime;
|
||||
char *format, *zone = NULL;
|
||||
|
||||
|
||||
if (argc < 4)
|
||||
return RESULT_SHOWUSAGE;
|
||||
|
||||
|
@ -1126,7 +1126,7 @@ static int handle_saydatetime(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
if (!strcasecmp(chan->language, "de")) {
|
||||
format = "A dBY HMS";
|
||||
} else {
|
||||
format = "ABdY 'digits/at' IMp";
|
||||
format = "ABdY 'digits/at' IMp";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1166,11 +1166,11 @@ static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, char *ar
|
|||
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 @@ static int handle_setcontext(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_setpriority(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
}
|
||||
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 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
|
|||
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 @@ static int handle_verbose(struct ast_channel *chan, AGI *agi, int argc, char **a
|
|||
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 @@ static int handle_dbget(struct ast_channel *chan, AGI *agi, int argc, char **arg
|
|||
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 @@ static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, cha
|
|||
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 @@ static int handle_speechset(struct ast_channel *chan, AGI *agi, int argc, char *
|
|||
/* 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 @@ static int handle_speechdestroy(struct ast_channel *chan, AGI *agi, int argc, ch
|
|||
} else {
|
||||
ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
|
||||
}
|
||||
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1748,17 +1748,17 @@ static int handle_speechloadgrammar(struct ast_channel *chan, AGI *agi, int argc
|
|||
{
|
||||
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 @@ static int handle_speechunloadgrammar(struct ast_channel *chan, AGI *agi, int ar
|
|||
{
|
||||
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 @@ static int handle_speechactivategrammar(struct ast_channel *chan, AGI *agi, int
|
|||
{
|
||||
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 @@ static int handle_speechdeactivategrammar(struct ast_channel *chan, AGI *agi, in
|
|||
{
|
||||
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 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
|
|||
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 */
|
||||
ast_sched_runq(chan->sched);
|
||||
|
||||
|
||||
/* See maximum time of waiting */
|
||||
if ((res = ast_sched_wait(chan->sched)) < 0)
|
||||
res = 1000;
|
||||
|
||||
|
||||
/* Wait for frame */
|
||||
if (ast_waitfor(chan, res) > 0) {
|
||||
if (!(fr = ast_read(chan))) {
|
||||
|
@ -1894,7 +1894,7 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Perform timeout check */
|
||||
if ((timeout > 0) && (start > 0)) {
|
||||
time(¤t);
|
||||
|
@ -1905,17 +1905,17 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check the speech structure for any changes */
|
||||
ast_mutex_lock(&speech->lock);
|
||||
|
||||
|
||||
/* See if we need to quiet the audio stream playback */
|
||||
if (ast_test_flag(speech, AST_SPEECH_QUIET) && chan->stream) {
|
||||
current_offset = ast_tellstream(chan->stream);
|
||||
ast_stopstream(chan);
|
||||
ast_clear_flag(speech, AST_SPEECH_QUIET);
|
||||
}
|
||||
|
||||
|
||||
/* Check each state */
|
||||
switch (speech->state) {
|
||||
case AST_SPEECH_STATE_READY:
|
||||
|
@ -1948,7 +1948,7 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
|
|||
break;
|
||||
}
|
||||
ast_mutex_unlock(&speech->lock);
|
||||
|
||||
|
||||
/* Check frame for DTMF or hangup */
|
||||
if (fr) {
|
||||
if (fr->frametype == AST_FRAME_DTMF) {
|
||||
|
@ -1960,7 +1960,7 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
|
|||
ast_frfree(fr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!strcasecmp(reason, "speech")) {
|
||||
/* Build string containing speech results */
|
||||
for (result = speech->results; result; result = AST_LIST_NEXT(result, list)) {
|
||||
|
@ -1978,7 +1978,7 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
|
|||
} else {
|
||||
ast_agi_fdprintf(chan, agi->fd, "200 result=0 endpos=%ld\n", current_offset);
|
||||
}
|
||||
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2044,7 +2044,7 @@ static char usage_setvariable[] =
|
|||
|
||||
static char usage_channelstatus[] =
|
||||
" Usage: CHANNEL STATUS [<channelname>]\n"
|
||||
" Returns the status of the specified channel.\n"
|
||||
" Returns the status of the specified channel.\n"
|
||||
" If no channel name is given the returns the status of the\n"
|
||||
" current channel. Return values:\n"
|
||||
" 0 Channel is down and available\n"
|
||||
|
@ -2070,12 +2070,12 @@ static char usage_hangup[] =
|
|||
" Hangs up the specified channel.\n"
|
||||
" If no channel name is given, hangs up the current channel\n";
|
||||
|
||||
static char usage_answer[] =
|
||||
static char usage_answer[] =
|
||||
" Usage: ANSWER\n"
|
||||
" Answers channel if not already in answer state. Returns -1 on\n"
|
||||
" channel failure, or 0 if successful.\n";
|
||||
|
||||
static char usage_waitfordigit[] =
|
||||
static char usage_waitfordigit[] =
|
||||
" Usage: WAIT FOR DIGIT <timeout>\n"
|
||||
" Waits up to 'timeout' milliseconds for channel to receive a DTMF digit.\n"
|
||||
" Returns -1 on channel failure, 0 if no digit is received in the timeout, or\n"
|
||||
|
@ -2136,7 +2136,7 @@ static char usage_controlstreamfile[] =
|
|||
" extension must not be included in the filename.\n\n"
|
||||
" Note: ffchar and rewchar default to * and # respectively.\n";
|
||||
|
||||
static char usage_getoption[] =
|
||||
static char usage_getoption[] =
|
||||
" Usage: GET OPTION <filename> <escape_digits> [timeout]\n"
|
||||
" Behaves similar to STREAM FILE but used with a timeout option.\n";
|
||||
|
||||
|
@ -2377,7 +2377,7 @@ int ast_agi_unregister(struct ast_module *mod, agi_command *cmd)
|
|||
struct agi_command *e;
|
||||
int unregistered = 0;
|
||||
char fullcmd[80];
|
||||
|
||||
|
||||
ast_join(fullcmd, sizeof(fullcmd), cmd->cmda);
|
||||
|
||||
AST_RWLIST_WRLOCK(&agi_commands);
|
||||
|
@ -2460,9 +2460,9 @@ static int parse_args(char *s, int *max, char *argv[])
|
|||
switch(*s) {
|
||||
case '"':
|
||||
/* If it's escaped, put a literal quote */
|
||||
if (escaped)
|
||||
if (escaped)
|
||||
goto normal;
|
||||
else
|
||||
else
|
||||
quoted = !quoted;
|
||||
if (quoted && whitespace) {
|
||||
/* If we're starting a quote, coming off white space start a new word, too */
|
||||
|
@ -2479,7 +2479,7 @@ static int parse_args(char *s, int *max, char *argv[])
|
|||
whitespace = 1;
|
||||
*(cur++) = '\0';
|
||||
} else
|
||||
/* Otherwise, just treat it as anything else */
|
||||
/* Otherwise, just treat it as anything else */
|
||||
goto normal;
|
||||
break;
|
||||
case '\\':
|
||||
|
@ -2522,7 +2522,7 @@ static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int
|
|||
char *ami_cmd = ast_strdupa(buf);
|
||||
int command_id = ast_random(), resultcode = 200;
|
||||
|
||||
manager_event(EVENT_FLAG_CALL, "AGIExec",
|
||||
manager_event(EVENT_FLAG_CALL, "AGIExec",
|
||||
"SubEvent: Start\r\n"
|
||||
"Channel: %s\r\n"
|
||||
"CommandId: %d\r\n"
|
||||
|
@ -2594,7 +2594,7 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
|
|||
char buf[AGI_BUF_LEN];
|
||||
char *res = NULL;
|
||||
FILE *readf;
|
||||
/* how many times we'll retry if ast_waitfor_nandfs will return without either
|
||||
/* how many times we'll retry if ast_waitfor_nandfs will return without either
|
||||
channel or file descriptor in case select is interrupted by a system call (EINTR) */
|
||||
int retry = AGI_NANDFS_RETRY;
|
||||
|
||||
|
@ -2642,9 +2642,9 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
|
|||
|
||||
while (buflen < (len - 1)) {
|
||||
res = fgets(buf + buflen, len, readf);
|
||||
if (feof(readf))
|
||||
if (feof(readf))
|
||||
break;
|
||||
if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN)))
|
||||
if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN)))
|
||||
break;
|
||||
if (res != NULL && !agi->fast)
|
||||
break;
|
||||
|
@ -2793,7 +2793,7 @@ static int write_htmldump(char *filename)
|
|||
AST_RWLIST_RDLOCK(&agi_commands);
|
||||
AST_RWLIST_TRAVERSE(&agi_commands, command, list) {
|
||||
char *stringp, *tempstr;
|
||||
|
||||
|
||||
if (!command->cmda[0]) /* end ? */
|
||||
break;
|
||||
/* Hide commands that start with '_' */
|
||||
|
@ -2917,7 +2917,7 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int
|
|||
close(fds[1]);
|
||||
if (efd > -1)
|
||||
close(efd);
|
||||
}
|
||||
}
|
||||
ast_safe_fork_cleanup();
|
||||
|
||||
switch (res) {
|
||||
|
|
Reference in New Issue