Add DeadAGI Application

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2317 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 22 years ago
parent 4653b4bb79
commit 534e78b372

@ -70,17 +70,20 @@ static char *app = "AGI";
static char *eapp = "EAGI"; static char *eapp = "EAGI";
static char *deadapp = "DeadAGI";
static char *synopsis = "Executes an AGI compliant application"; static char *synopsis = "Executes an AGI compliant application";
static char *esynopsis = "Executes an EAGI compliant application"; static char *esynopsis = "Executes an EAGI compliant application";
static char *deadsynopsis = "Executes AGI on a hungup channel";
static char *descrip = static char *descrip =
" [E]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n" " [E|Dead]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n"
"program on a channel. AGI allows Asterisk to launch external programs\n" "program on a channel. AGI allows Asterisk to launch external programs\n"
"written in any language to control a telephony channel, play audio,\n" "written in any language to control a telephony channel, play audio,\n"
"read DTMF digits, etc. by communicating with the AGI protocol on stdin\n" "read DTMF digits, etc. by communicating with the AGI protocol on stdin\n"
"and stdout.\n" "and stdout.\n"
"Returns -1 on hangup or if application requested hangup, or\n" "Returns -1 on hangup (except for DeadAGI) or if application requested\n"
"0 on non-hangup exit. \n" " hangup, or 0 on non-hangup exit. \n"
"Using 'EAGI' provides enhanced AGI, with incoming audio available out of band" "Using 'EAGI' provides enhanced AGI, with incoming audio available out of band"
"on file descriptor 3\n\n" "on file descriptor 3\n\n"
"Use the CLI command 'show agi' to list available agi commands\n"; "Use the CLI command 'show agi' to list available agi commands\n";
@ -1256,7 +1259,7 @@ static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf)
return 0; return 0;
} }
#define RETRY 3 #define RETRY 3
static int run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid) static int run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid, int dead)
{ {
struct ast_channel *c; struct ast_channel *c;
int outfd; int outfd;
@ -1265,7 +1268,8 @@ static int run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid)
struct ast_frame *f; struct ast_frame *f;
char buf[2048]; char buf[2048];
FILE *readf; FILE *readf;
//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) /* 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 = RETRY; int retry = RETRY;
if (!(readf = fdopen(agi->ctrl, "r"))) { if (!(readf = fdopen(agi->ctrl, "r"))) {
@ -1277,7 +1281,7 @@ static int run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid)
setup_env(chan, request, agi->fd, (agi->audio > -1)); setup_env(chan, request, agi->fd, (agi->audio > -1));
for (;;) { for (;;) {
ms = -1; ms = -1;
c = ast_waitfor_nandfds(&chan, 1, &agi->ctrl, 1, NULL, &outfd, &ms); c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
if (c) { if (c) {
retry = RETRY; retry = RETRY;
/* Idle the channel until we get a command */ /* Idle the channel until we get a command */
@ -1408,7 +1412,7 @@ static int handle_dumpagihtml(int fd, int argc, char *argv[]) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced) static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int dead)
{ {
int res=0; int res=0;
struct localuser *u; struct localuser *u;
@ -1452,7 +1456,7 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced)
agi.fd = fds[1]; agi.fd = fds[1];
agi.ctrl = fds[0]; agi.ctrl = fds[0];
agi.audio = efd; agi.audio = efd;
res = run_agi(chan, tmp, &agi, pid); res = run_agi(chan, tmp, &agi, pid, dead);
close(fds[0]); close(fds[0]);
close(fds[1]); close(fds[1]);
if (efd > -1) if (efd > -1)
@ -1464,7 +1468,7 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced)
static int agi_exec(struct ast_channel *chan, void *data) static int agi_exec(struct ast_channel *chan, void *data)
{ {
return agi_exec_full(chan, data, 0); return agi_exec_full(chan, data, 0, 0);
} }
static int eagi_exec(struct ast_channel *chan, void *data) static int eagi_exec(struct ast_channel *chan, void *data)
@ -1476,7 +1480,7 @@ static int eagi_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
return -1; return -1;
} }
res = agi_exec_full(chan, data, 1); res = agi_exec_full(chan, data, 1, 0);
if (!res) { if (!res) {
if (ast_set_read_format(chan, readformat)) { if (ast_set_read_format(chan, readformat)) {
ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
@ -1485,6 +1489,11 @@ static int eagi_exec(struct ast_channel *chan, void *data)
return res; return res;
} }
static int deadagi_exec(struct ast_channel *chan, void *data)
{
return agi_exec_full(chan, data, 0, 1);
}
static char showagi_help[] = static char showagi_help[] =
"Usage: show agi [topic]\n" "Usage: show agi [topic]\n"
" When called with a topic as an argument, displays usage\n" " When called with a topic as an argument, displays usage\n"
@ -1508,6 +1517,7 @@ int unload_module(void)
ast_cli_unregister(&showagi); ast_cli_unregister(&showagi);
ast_cli_unregister(&dumpagihtml); ast_cli_unregister(&dumpagihtml);
ast_unregister_application(eapp); ast_unregister_application(eapp);
ast_unregister_application(deadapp);
return ast_unregister_application(app); return ast_unregister_application(app);
} }
@ -1515,6 +1525,7 @@ int load_module(void)
{ {
ast_cli_register(&showagi); ast_cli_register(&showagi);
ast_cli_register(&dumpagihtml); ast_cli_register(&dumpagihtml);
ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip);
ast_register_application(eapp, eagi_exec, esynopsis, descrip); ast_register_application(eapp, eagi_exec, esynopsis, descrip);
return ast_register_application(app, agi_exec, synopsis, descrip); return ast_register_application(app, agi_exec, synopsis, descrip);
} }

Loading…
Cancel
Save