Mon Jul 14 17:25:22 2008

Asterisk developer's documentation


res_agi.c File Reference

AGI - the Asterisk Gateway Interface. More...

#include "asterisk.h"
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/astdb.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/options.h"
#include "asterisk/image.h"
#include "asterisk/say.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/strings.h"
#include "asterisk/agi.h"

Include dependency graph for res_agi.c:

Go to the source code of this file.

Defines

#define AGI_BUF_LEN   2048
#define AGI_NANDFS_RETRY   3
#define AGI_PORT   4573
#define fdprintf   agi_debug_cli
#define MAX_AGI_CONNECT   2000
#define MAX_ARGS   128
#define MAX_COMMANDS   128
#define TONE_BLOCK_SIZE   200

Enumerations

enum  agi_result { AGI_RESULT_SUCCESS, AGI_RESULT_SUCCESS_FAST, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP }

Functions

static int agi_debug_cli (int fd, char *fmt,...)
static int agi_do_debug (int fd, int argc, char *argv[])
static int agi_exec (struct ast_channel *chan, void *data)
static int agi_exec_full (struct ast_channel *chan, void *data, int enhanced, int dead)
static int agi_handle_command (struct ast_channel *chan, AGI *agi, char *buf)
static int agi_no_debug (int fd, int argc, char *argv[])
static int agi_no_debug_deprecated (int fd, int argc, char *argv[])
int ast_agi_register (agi_command *agi)
void ast_agi_unregister (agi_command *agi)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Asterisk Gateway Interface (AGI)",.load=load_module,.unload=unload_module,)
static int deadagi_exec (struct ast_channel *chan, void *data)
static int eagi_exec (struct ast_channel *chan, void *data)
static agi_commandfind_command (char *cmds[], int exact)
static int handle_agidumphtml (int fd, int argc, char *argv[])
static int handle_answer (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_autohangup (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_channelstatus (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_controlstreamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_dbdel (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_dbdeltree (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_dbget (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_dbput (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_exec (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_getdata (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_getoption (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_getvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_getvariablefull (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_hangup (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_noop (struct ast_channel *chan, AGI *agi, int arg, char *argv[])
static int handle_recordfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_recvchar (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_recvtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_sayalpha (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_saydate (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_saydatetime (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_saydigits (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_saynumber (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_sayphonetic (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_saytime (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_sendimage (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_sendtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_setcallerid (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_setcontext (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_setextension (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_setmusic (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_setpriority (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_setvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_showagi (int fd, int argc, char *argv[])
static int handle_streamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_tddmode (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int handle_verbose (struct ast_channel *chan, AGI *agi, int argc, char **argv)
static int handle_waitfordigit (struct ast_channel *chan, AGI *agi, int argc, char *argv[])
static int help_workhorse (int fd, char *match[])
static enum agi_result launch_netscript (char *agiurl, char *argv[], int *fds, int *efd, int *opid)
static enum agi_result launch_script (char *script, char *argv[], int *fds, int *efd, int *efd2, int *opid)
static int load_module (void)
static int parse_args (char *s, int *max, char *argv[])
static enum agi_result run_agi (struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead)
static void setup_env (struct ast_channel *chan, char *request, int fd, int enhanced)
static int unload_module (void)
static int xagi_exec (struct ast_channel *chan, void *data)

Variables

static int agidebug = 0
static char * app = "AGI"
static struct ast_cli_entry cli_agi []
static struct ast_cli_entry cli_agi_no_debug_deprecated
static struct ast_cli_entry cli_dump_agihtml_deprecated
static struct ast_cli_entry cli_show_agi_deprecated
static agi_command commands [MAX_COMMANDS]
static char * deadapp = "DeadAGI"
static char * deadsynopsis = "Executes AGI on a hungup channel"
static char debug_usage []
static char * descrip
static char dumpagihtml_help []
static char * eapp = "EAGI"
static char * esynopsis = "Executes an EAGI compliant application"
static char no_debug_usage []
static char showagi_help []
static char * synopsis = "Executes an AGI compliant application"
static char usage_answer []
static char usage_autohangup []
static char usage_channelstatus []
static char usage_controlstreamfile []
static char usage_dbdel []
static char usage_dbdeltree []
static char usage_dbget []
static char usage_dbput []
static char usage_exec []
static char usage_getdata []
static char usage_getoption []
static char usage_getvariable []
static char usage_getvariablefull []
static char usage_hangup []
static char usage_noop []
static char usage_recordfile []
static char usage_recvchar []
static char usage_recvtext []
static char usage_sayalpha []
static char usage_saydate []
static char usage_saydatetime []
static char usage_saydigits []
static char usage_saynumber []
static char usage_sayphonetic []
static char usage_saytime []
static char usage_sendimage []
static char usage_sendtext []
static char usage_setcallerid []
static char usage_setcontext []
static char usage_setextension []
static char usage_setmusic []
static char usage_setpriority []
static char usage_setvariable []
static char usage_streamfile []
static char usage_tddmode []
static char usage_verbose []
static char usage_waitfordigit []
static char * xapp = "XAGI"
static char * xsynopsis = "Executes an XAGI compliant application"


Detailed Description

AGI - the Asterisk Gateway Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file res_agi.c.


Define Documentation

#define AGI_BUF_LEN   2048

Definition at line 74 of file res_agi.c.

Referenced by agi_exec_full(), and run_agi().

#define AGI_NANDFS_RETRY   3

Definition at line 73 of file res_agi.c.

Referenced by run_agi().

#define AGI_PORT   4573

Definition at line 120 of file res_agi.c.

Referenced by launch_netscript().

#define fdprintf   agi_debug_cli

Definition at line 77 of file res_agi.c.

Referenced by agi_handle_command(), handle_answer(), handle_autohangup(), handle_channelstatus(), handle_controlstreamfile(), handle_dbdel(), handle_dbdeltree(), handle_dbget(), handle_dbput(), handle_exec(), handle_getdata(), handle_getoption(), handle_getvariable(), handle_getvariablefull(), handle_hangup(), handle_noop(), handle_recordfile(), handle_recvchar(), handle_recvtext(), handle_sayalpha(), handle_saydate(), handle_saydatetime(), handle_saydigits(), handle_saynumber(), handle_sayphonetic(), handle_saytime(), handle_sendimage(), handle_sendtext(), handle_setcallerid(), handle_setcontext(), handle_setextension(), handle_setmusic(), handle_setpriority(), handle_setvariable(), handle_streamfile(), handle_tddmode(), handle_verbose(), handle_waitfordigit(), launch_netscript(), and setup_env().

#define MAX_AGI_CONNECT   2000

Definition at line 118 of file res_agi.c.

Referenced by launch_netscript().

#define MAX_ARGS   128

Definition at line 71 of file res_agi.c.

#define MAX_COMMANDS   128

Definition at line 72 of file res_agi.c.

Referenced by ast_agi_register().

#define TONE_BLOCK_SIZE   200

Definition at line 115 of file res_agi.c.


Enumeration Type Documentation

enum agi_result

Enumerator:
AGI_RESULT_SUCCESS 
AGI_RESULT_SUCCESS_FAST 
AGI_RESULT_FAILURE 
AGI_RESULT_HANGUP 

Definition at line 122 of file res_agi.c.


Function Documentation

static int agi_debug_cli ( int  fd,
char *  fmt,
  ... 
) [static]

Definition at line 129 of file res_agi.c.

References ast_carefulwrite(), ast_log(), ast_verbose(), free, LOG_ERROR, ast_variable::stuff, and vasprintf.

00130 {
00131    char *stuff;
00132    int res = 0;
00133 
00134    va_list ap;
00135    va_start(ap, fmt);
00136    res = vasprintf(&stuff, fmt, ap);
00137    va_end(ap);
00138    if (res == -1) {
00139       ast_log(LOG_ERROR, "Out of memory\n");
00140    } else {
00141       if (agidebug)
00142          ast_verbose("AGI Tx >> %s", stuff); /* \n provided by caller */
00143       res = ast_carefulwrite(fd, stuff, strlen(stuff), 100);
00144       free(stuff);
00145    }
00146 
00147    return res;
00148 }

static int agi_do_debug ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1366 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01367 {
01368    if (argc != 2)
01369       return RESULT_SHOWUSAGE;
01370    agidebug = 1;
01371    ast_cli(fd, "AGI Debugging Enabled\n");
01372    return RESULT_SUCCESS;
01373 }

static int agi_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 2178 of file res_agi.c.

References ast_channel::_softhangup, agi_exec_full(), ast_log(), ast_module_user::chan, and LOG_WARNING.

Referenced by load_module().

02179 {
02180    if (chan->_softhangup)
02181       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02182    return agi_exec_full(chan, data, 0, 0);
02183 }

static int agi_exec_full ( struct ast_channel chan,
void *  data,
int  enhanced,
int  dead 
) [static]

Definition at line 2103 of file res_agi.c.

References ast_channel::_state, AGI_BUF_LEN, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, AGI_RESULT_SUCCESS_FAST, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, ast_replace_sigchld(), AST_STATE_UP, ast_strlen_zero(), ast_unreplace_sigchld(), ast_module_user::chan, launch_script(), LOG_WARNING, MAX_ARGS, pbx_builtin_setvar_helper(), run_agi(), and strsep().

Referenced by agi_exec(), deadagi_exec(), eagi_exec(), and xagi_exec().

02104 {
02105    enum agi_result res;
02106    struct ast_module_user *u;
02107    char *argv[MAX_ARGS];
02108    char buf[AGI_BUF_LEN] = "";
02109    char *tmp = (char *)buf;
02110    int argc = 0;
02111    int fds[2];
02112    int efd = -1;
02113    int efd2 = -1;
02114    int pid;
02115         char *stringp;
02116    AGI agi;
02117 
02118    if (ast_strlen_zero(data)) {
02119       ast_log(LOG_WARNING, "AGI requires an argument (script)\n");
02120       return -1;
02121    }
02122    ast_copy_string(buf, data, sizeof(buf));
02123 
02124    memset(&agi, 0, sizeof(agi));
02125         while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1)
02126       argv[argc++] = stringp;
02127    argv[argc] = NULL;
02128 
02129    u = ast_module_user_add(chan);
02130 #if 0
02131     /* Answer if need be */
02132         if (chan->_state != AST_STATE_UP) {
02133       if (ast_answer(chan)) {
02134          LOCAL_USER_REMOVE(u);
02135          return -1;
02136       }
02137    }
02138 #endif
02139    ast_replace_sigchld();
02140    res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, (enhanced == 2) ? &efd2 : NULL, &pid);
02141    if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) {
02142       int status = 0;
02143       agi.fd = fds[1];
02144       agi.ctrl = fds[0];
02145       agi.audio = efd;
02146       agi.audio_in = efd2;
02147       agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0;
02148       res = run_agi(chan, argv[0], &agi, pid, &status, dead);
02149       /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */
02150       if ((res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) && status)
02151          res = AGI_RESULT_FAILURE;
02152       if (fds[1] != fds[0])
02153          close(fds[1]);
02154       if (efd > -1)
02155          close(efd);
02156       if (efd2 > -1)
02157          close(efd2);
02158    }
02159    ast_unreplace_sigchld();
02160    ast_module_user_remove(u);
02161 
02162    switch (res) {
02163    case AGI_RESULT_SUCCESS:
02164    case AGI_RESULT_SUCCESS_FAST:
02165       pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS");
02166       break;
02167    case AGI_RESULT_FAILURE:
02168       pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE");
02169       break;
02170    case AGI_RESULT_HANGUP:
02171       pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP");
02172       return -1;
02173    }
02174 
02175    return 0;
02176 }

static int agi_handle_command ( struct ast_channel chan,
AGI agi,
char *  buf 
) [static]

Definition at line 1848 of file res_agi.c.

References AST_PBX_KEEPALIVE, agi_state::fd, fdprintf, find_command(), agi_command::handler, MAX_ARGS, parse_args(), RESULT_FAILURE, RESULT_SHOWUSAGE, and agi_command::usage.

Referenced by run_agi().

01849 {
01850    char *argv[MAX_ARGS];
01851    int argc = MAX_ARGS;
01852    int res;
01853    agi_command *c;
01854 
01855    parse_args(buf, &argc, argv);
01856    c = find_command(argv, 0);
01857    if (c) {
01858       res = c->handler(chan, agi, argc, argv);
01859       switch(res) {
01860       case RESULT_SHOWUSAGE:
01861          fdprintf(agi->fd, "520-Invalid command syntax.  Proper usage follows:\n");
01862          fdprintf(agi->fd, c->usage);
01863          fdprintf(agi->fd, "520 End of proper usage.\n");
01864          break;
01865       case AST_PBX_KEEPALIVE:
01866          /* We've been asked to keep alive, so do so */
01867          return AST_PBX_KEEPALIVE;
01868          break;
01869       case RESULT_FAILURE:
01870          /* They've already given the failure.  We've been hung up on so handle this
01871             appropriately */
01872          return -1;
01873       }
01874    } else {
01875       fdprintf(agi->fd, "510 Invalid or unknown command\n");
01876    }
01877    return 0;
01878 }

static int agi_no_debug ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1384 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01385 {
01386    if (argc != 3)
01387       return RESULT_SHOWUSAGE;
01388    agidebug = 0;
01389    ast_cli(fd, "AGI Debugging Disabled\n");
01390    return RESULT_SUCCESS;
01391 }

static int agi_no_debug_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1375 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01376 {
01377    if (argc != 3)
01378       return RESULT_SHOWUSAGE;
01379    agidebug = 0;
01380    ast_cli(fd, "AGI Debugging Disabled\n");
01381    return RESULT_SUCCESS;
01382 }

int ast_agi_register ( agi_command agi  ) 

Definition at line 1719 of file res_agi.c.

References ast_log(), agi_command::cmda, commands, LOG_WARNING, and MAX_COMMANDS.

01720 {
01721    int x;
01722    for (x=0; x<MAX_COMMANDS - 1; x++) {
01723       if (commands[x].cmda[0] == agi->cmda[0]) {
01724          ast_log(LOG_WARNING, "Command already registered!\n");
01725          return -1;
01726       }
01727    }
01728    for (x=0; x<MAX_COMMANDS - 1; x++) {
01729       if (!commands[x].cmda[0]) {
01730          commands[x] = *agi;
01731          return 0;
01732       }
01733    }
01734    ast_log(LOG_WARNING, "No more room for new commands!\n");
01735    return -1;
01736 }

void ast_agi_unregister ( agi_command agi  ) 

Definition at line 1738 of file res_agi.c.

References agi_command::cmda, and commands.

01739 {
01740    int x;
01741    for (x=0; x<MAX_COMMANDS - 1; x++) {
01742       if (commands[x].cmda[0] == agi->cmda[0]) {
01743          memset(&commands[x], 0, sizeof(agi_command));
01744       }
01745    }
01746 }

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_GLOBAL_SYMBOLS  ,
"Asterisk Gateway Interface (AGI)"  ,
load = load_module,
unload = unload_module 
)

static int deadagi_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 2235 of file res_agi.c.

References agi_exec_full(), ast_check_hangup(), ast_log(), ast_module_user::chan, and LOG_WARNING.

Referenced by load_module().

02236 {
02237    if (!ast_check_hangup(chan))
02238       ast_log(LOG_WARNING,"Running DeadAGI on a live channel will cause problems, please use AGI\n");
02239    return agi_exec_full(chan, data, 0, 1);
02240 }

static int eagi_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 2185 of file res_agi.c.

References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), ast_module_user::chan, LOG_WARNING, and ast_channel::readformat.

Referenced by load_module().

02186 {
02187    int readformat;
02188    int res;
02189 
02190    if (chan->_softhangup)
02191       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02192    readformat = chan->readformat;
02193    if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
02194       ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
02195       return -1;
02196    }
02197    res = agi_exec_full(chan, data, 1, 0);
02198    if (!res) {
02199       if (ast_set_read_format(chan, readformat)) {
02200          ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
02201       }
02202    }
02203    return res;
02204 }

static agi_command* find_command ( char *  cmds[],
int  exact 
) [static]

Definition at line 1748 of file res_agi.c.

References agi_command::cmda, commands, and match().

01749 {
01750    int x;
01751    int y;
01752    int match;
01753 
01754    for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) {
01755       if (!commands[x].cmda[0])
01756          break;
01757       /* start optimistic */
01758       match = 1;
01759       for (y=0; match && cmds[y]; y++) {
01760          /* If there are no more words in the command (and we're looking for
01761             an exact match) or there is a difference between the two words,
01762             then this is not a match */
01763          if (!commands[x].cmda[y] && !exact)
01764             break;
01765          /* don't segfault if the next part of a command doesn't exist */
01766          if (!commands[x].cmda[y])
01767             return NULL;
01768          if (strcasecmp(commands[x].cmda[y], cmds[y]))
01769             match = 0;
01770       }
01771       /* If more words are needed to complete the command then this is not
01772          a candidate (unless we're looking for a really inexact answer  */
01773       if ((exact > -1) && commands[x].cmda[y])
01774          match = 0;
01775       if (match)
01776          return &commands[x];
01777    }
01778    return NULL;
01779 }

static int handle_agidumphtml ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2049 of file res_agi.c.

References ast_cli(), ast_join(), agi_command::cmda, commands, RESULT_SHOWUSAGE, RESULT_SUCCESS, strsep(), agi_command::summary, and agi_command::usage.

02050 {
02051    struct agi_command *e;
02052    char fullcmd[80];
02053    int x;
02054    FILE *htmlfile;
02055 
02056    if ((argc < 3))
02057       return RESULT_SHOWUSAGE;
02058 
02059    if (!(htmlfile = fopen(argv[2], "wt"))) {
02060       ast_cli(fd, "Could not create file '%s'\n", argv[2]);
02061       return RESULT_SHOWUSAGE;
02062    }
02063 
02064    fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n");
02065    fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n");
02066 
02067 
02068    fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n");
02069 
02070    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
02071       char *stringp, *tempstr;
02072 
02073       e = &commands[x]; 
02074       if (!e->cmda[0])  /* end ? */
02075          break;
02076       /* Hide commands that start with '_' */
02077       if ((e->cmda[0])[0] == '_')
02078          continue;
02079       ast_join(fullcmd, sizeof(fullcmd), e->cmda);
02080 
02081       fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n");
02082       fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TH></TR>\n", fullcmd,e->summary);
02083 
02084       stringp=e->usage;
02085       tempstr = strsep(&stringp, "\n");
02086 
02087       fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr);
02088       
02089       fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n");
02090       while ((tempstr = strsep(&stringp, "\n")) != NULL)
02091          fprintf(htmlfile, "%s<BR>\n",tempstr);
02092       fprintf(htmlfile, "</TD></TR>\n");
02093       fprintf(htmlfile, "</TABLE></TD></TR>\n\n");
02094 
02095    }
02096 
02097    fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n");
02098    fclose(htmlfile);
02099    ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]);
02100    return RESULT_SUCCESS;
02101 }

static int handle_answer ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 454 of file res_agi.c.

References ast_channel::_state, ast_answer(), AST_STATE_UP, agi_state::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS.

00455 {
00456    int res;
00457    res = 0;
00458    if (chan->_state != AST_STATE_UP) {
00459       /* Answer the chan */
00460       res = ast_answer(chan);
00461    }
00462    fdprintf(agi->fd, "200 result=%d\n", res);
00463    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00464 }

static int handle_autohangup ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 1103 of file res_agi.c.

References agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::whentohangup.

01104 {
01105    int timeout;
01106 
01107    if (argc != 3)
01108       return RESULT_SHOWUSAGE;
01109    if (sscanf(argv[2], "%d", &timeout) != 1)
01110       return RESULT_SHOWUSAGE;
01111    if (timeout < 0)
01112       timeout = 0;
01113    if (timeout)
01114       chan->whentohangup = time(NULL) + timeout;
01115    else
01116       chan->whentohangup = 0;
01117    fdprintf(agi->fd, "200 result=0\n");
01118    return RESULT_SUCCESS;
01119 }

static int handle_channelstatus ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1193 of file res_agi.c.

References ast_channel::_state, ast_channel_unlock, ast_get_channel_by_name_locked(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01194 {
01195    struct ast_channel *c;
01196    if (argc == 2) {
01197       /* no argument: supply info on the current channel */
01198       fdprintf(agi->fd, "200 result=%d\n", chan->_state);
01199       return RESULT_SUCCESS;
01200    } else if (argc == 3) {
01201       /* one argument: look for info on the specified channel */
01202       c = ast_get_channel_by_name_locked(argv[2]);
01203       if (c) {
01204          fdprintf(agi->fd, "200 result=%d\n", c->_state);
01205          ast_channel_unlock(c);
01206          return RESULT_SUCCESS;
01207       }
01208       /* if we get this far no channel name matched the argument given */
01209       fdprintf(agi->fd, "200 result=-1\n");
01210       return RESULT_SUCCESS;
01211    } else {
01212       return RESULT_SHOWUSAGE;
01213    }
01214 }

static int handle_controlstreamfile ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 565 of file res_agi.c.

References ast_control_streamfile(), ast_strlen_zero(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, skipms, and stop.

00566 {
00567    int res = 0;
00568    int skipms = 3000;
00569    char *fwd = NULL;
00570    char *rev = NULL;
00571    char *pause = NULL;
00572    char *stop = NULL;
00573 
00574    if (argc < 5 || argc > 9)
00575       return RESULT_SHOWUSAGE;
00576 
00577    if (!ast_strlen_zero(argv[4]))
00578       stop = argv[4];
00579    else
00580       stop = NULL;
00581    
00582    if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1))
00583       return RESULT_SHOWUSAGE;
00584 
00585    if (argc > 6 && !ast_strlen_zero(argv[6]))
00586       fwd = argv[6];
00587    else
00588       fwd = "#";
00589 
00590    if (argc > 7 && !ast_strlen_zero(argv[7]))
00591       rev = argv[7];
00592    else
00593       rev = "*";
00594    
00595    if (argc > 8 && !ast_strlen_zero(argv[8]))
00596       pause = argv[8];
00597    else
00598       pause = NULL;
00599    
00600    res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms);
00601    
00602    fdprintf(agi->fd, "200 result=%d\n", res);
00603 
00604    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00605 }

static int handle_dbdel ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1333 of file res_agi.c.

References ast_db_del(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01334 {
01335    int res;
01336 
01337    if (argc != 4)
01338       return RESULT_SHOWUSAGE;
01339    res = ast_db_del(argv[2], argv[3]);
01340    fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
01341    return RESULT_SUCCESS;
01342 }

static int handle_dbdeltree ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1344 of file res_agi.c.

References ast_db_deltree(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01345 {
01346    int res;
01347    if ((argc < 3) || (argc > 4))
01348       return RESULT_SHOWUSAGE;
01349    if (argc == 4)
01350       res = ast_db_deltree(argv[2], argv[3]);
01351    else
01352       res = ast_db_deltree(argv[2], NULL);
01353 
01354    fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
01355    return RESULT_SUCCESS;
01356 }

static int handle_dbget ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1306 of file res_agi.c.

References ast_db_get(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01307 {
01308    int res;
01309    char tmp[256];
01310 
01311    if (argc != 4)
01312       return RESULT_SHOWUSAGE;
01313    res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
01314    if (res) 
01315       fdprintf(agi->fd, "200 result=0\n");
01316    else
01317       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01318 
01319    return RESULT_SUCCESS;
01320 }

static int handle_dbput ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1322 of file res_agi.c.

References ast_db_put(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01323 {
01324    int res;
01325 
01326    if (argc != 5)
01327       return RESULT_SHOWUSAGE;
01328    res = ast_db_put(argv[2], argv[3], argv[4]);
01329    fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
01330    return RESULT_SUCCESS;
01331 }

static int handle_exec ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1147 of file res_agi.c.

References app, ast_log(), ast_verbose(), agi_state::fd, fdprintf, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), RESULT_SHOWUSAGE, and VERBOSE_PREFIX_3.

01148 {
01149    int res;
01150    struct ast_app *app;
01151 
01152    if (argc < 2)
01153       return RESULT_SHOWUSAGE;
01154 
01155    if (option_verbose > 2)
01156       ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]);
01157 
01158    app = pbx_findapp(argv[1]);
01159 
01160    if (app) {
01161       res = pbx_exec(chan, app, argv[2]);
01162    } else {
01163       ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
01164       res = -2;
01165    }
01166    fdprintf(agi->fd, "200 result=%d\n", res);
01167 
01168    /* Even though this is wrong, users are depending upon this result. */
01169    return res;
01170 }

static int handle_getdata ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 862 of file res_agi.c.

References ast_app_getdata_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00863 {
00864    int res;
00865    char data[1024];
00866    int max;
00867    int timeout;
00868 
00869    if (argc < 3)
00870       return RESULT_SHOWUSAGE;
00871    if (argc >= 4)
00872       timeout = atoi(argv[3]); 
00873    else
00874       timeout = 0;
00875    if (argc >= 5) 
00876       max = atoi(argv[4]); 
00877    else
00878       max = 1024;
00879    res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
00880    if (res == 2)        /* New command */
00881       return RESULT_SUCCESS;
00882    else if (res == 1)
00883       fdprintf(agi->fd, "200 result=%s (timeout)\n", data);
00884    else if (res < 0 )
00885       fdprintf(agi->fd, "200 result=-1\n");
00886    else
00887       fdprintf(agi->fd, "200 result=%s\n", data);
00888    return RESULT_SUCCESS;
00889 }

static int handle_getoption ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 663 of file res_agi.c.

References ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_verbose(), ast_waitfordigit_full(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, ast_pbx::dtimeout, agi_state::fd, fdprintf, LOG_DEBUG, LOG_WARNING, option_verbose, ast_channel::pbx, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.

00664 {
00665    int res;
00666    int vres;   
00667    struct ast_filestream *fs;
00668    struct ast_filestream *vfs;
00669    long sample_offset = 0;
00670    long max_length;
00671    int timeout = 0;
00672    char *edigits = "";
00673 
00674    if ( argc < 4 || argc > 5 )
00675       return RESULT_SHOWUSAGE;
00676 
00677    if ( argv[3] ) 
00678       edigits = argv[3];
00679 
00680    if ( argc == 5 )
00681       timeout = atoi(argv[4]);
00682    else if (chan->pbx->dtimeout) {
00683       /* by default dtimeout is set to 5sec */
00684       timeout = chan->pbx->dtimeout * 1000; /* in msec */
00685    }
00686 
00687    fs = ast_openstream(chan, argv[2], chan->language);
00688    if (!fs) {
00689       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
00690       ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
00691       return RESULT_SUCCESS;
00692    }
00693    vfs = ast_openvstream(chan, argv[2], chan->language);
00694    if (vfs)
00695       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00696    
00697    if (option_verbose > 2)
00698       ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
00699 
00700    ast_seekstream(fs, 0, SEEK_END);
00701    max_length = ast_tellstream(fs);
00702    ast_seekstream(fs, sample_offset, SEEK_SET);
00703    res = ast_applystream(chan, fs);
00704    if (vfs)
00705       vres = ast_applystream(chan, vfs);
00706    ast_playstream(fs);
00707    if (vfs)
00708       ast_playstream(vfs);
00709 
00710    res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
00711    /* this is to check for if ast_waitstream closed the stream, we probably are at
00712     * the end of the stream, return that amount, else check for the amount */
00713    sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
00714    ast_stopstream(chan);
00715    if (res == 1) {
00716       /* Stop this command, don't print a result line, as there is a new command */
00717       return RESULT_SUCCESS;
00718    }
00719 
00720    /* If the user didnt press a key, wait for digitTimeout*/
00721    if (res == 0 ) {
00722       res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
00723       /* Make sure the new result is in the escape digits of the GET OPTION */
00724       if ( !strchr(edigits,res) )
00725          res=0;
00726    }
00727 
00728         fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00729    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00730 }

static int handle_getvariable ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1225 of file res_agi.c.

References ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01226 {
01227    char *ret;
01228    char tempstr[1024];
01229 
01230    if (argc != 3)
01231       return RESULT_SHOWUSAGE;
01232 
01233    /* check if we want to execute an ast_custom_function */
01234    if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
01235       ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
01236    } else {
01237       pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
01238    }
01239 
01240    if (ret)
01241       fdprintf(agi->fd, "200 result=1 (%s)\n", ret);
01242    else
01243       fdprintf(agi->fd, "200 result=0\n");
01244 
01245    return RESULT_SUCCESS;
01246 }

static int handle_getvariablefull ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1248 of file res_agi.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), agi_state::fd, fdprintf, pbx_substitute_variables_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01249 {
01250    char tmp[4096] = "";
01251    struct ast_channel *chan2=NULL;
01252 
01253    if ((argc != 4) && (argc != 5))
01254       return RESULT_SHOWUSAGE;
01255    if (argc == 5) {
01256       chan2 = ast_get_channel_by_name_locked(argv[4]);
01257    } else {
01258       chan2 = chan;
01259    }
01260    if (chan2) {
01261       pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1);
01262       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01263    } else {
01264       fdprintf(agi->fd, "200 result=0\n");
01265    }
01266    if (chan2 && (chan2 != chan))
01267       ast_channel_unlock(chan2);
01268    return RESULT_SUCCESS;
01269 }

static int handle_hangup ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1121 of file res_agi.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01122 {
01123    struct ast_channel *c;
01124    if (argc == 1) {
01125       /* no argument: hangup the current channel */
01126       ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
01127       fdprintf(agi->fd, "200 result=1\n");
01128       return RESULT_SUCCESS;
01129    } else if (argc == 2) {
01130       /* one argument: look for info on the specified channel */
01131       c = ast_get_channel_by_name_locked(argv[1]);
01132       if (c) {
01133          /* we have a matching channel */
01134          ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
01135          fdprintf(agi->fd, "200 result=1\n");
01136          ast_channel_unlock(c);
01137          return RESULT_SUCCESS;
01138       }
01139       /* if we get this far no channel name matched the argument given */
01140       fdprintf(agi->fd, "200 result=-1\n");
01141       return RESULT_SUCCESS;
01142    } else {
01143       return RESULT_SHOWUSAGE;
01144    }
01145 }

static int handle_noop ( struct ast_channel chan,
AGI agi,
int  arg,
char *  argv[] 
) [static]

Definition at line 1393 of file res_agi.c.

References agi_state::fd, fdprintf, and RESULT_SUCCESS.

01394 {
01395    fdprintf(agi->fd, "200 result=0\n");
01396    return RESULT_SUCCESS;
01397 }

static int handle_recordfile ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 926 of file res_agi.c.

References ast_applystream(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate(), ast_log(), ast_read(), ast_seekstream(), ast_set_read_format(), ast_stream_rewind(), ast_streamfile(), ast_tellstream(), ast_truncstream(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), f, agi_state::fd, fdprintf, LOG_WARNING, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, and ast_dsp::totalsilence.

00927 {
00928    struct ast_filestream *fs;
00929    struct ast_frame *f;
00930    struct timeval start;
00931    long sample_offset = 0;
00932    int res = 0;
00933    int ms;
00934 
00935         struct ast_dsp *sildet=NULL;         /* silence detector dsp */
00936         int totalsilence = 0;
00937         int dspsilence = 0;
00938         int silence = 0;                /* amount of silence to allow */
00939         int gotsilence = 0;             /* did we timeout for silence? */
00940         char *silencestr=NULL;
00941         int rfmt=0;
00942 
00943 
00944    /* XXX EAGI FIXME XXX */
00945 
00946    if (argc < 6)
00947       return RESULT_SHOWUSAGE;
00948    if (sscanf(argv[5], "%d", &ms) != 1)
00949       return RESULT_SHOWUSAGE;
00950 
00951    if (argc > 6)
00952       silencestr = strchr(argv[6],'s');
00953    if ((argc > 7) && (!silencestr))
00954       silencestr = strchr(argv[7],'s');
00955    if ((argc > 8) && (!silencestr))
00956       silencestr = strchr(argv[8],'s');
00957 
00958    if (silencestr) {
00959       if (strlen(silencestr) > 2) {
00960          if ((silencestr[0] == 's') && (silencestr[1] == '=')) {
00961             silencestr++;
00962             silencestr++;
00963             if (silencestr)
00964                         silence = atoi(silencestr);
00965                if (silence > 0)
00966                         silence *= 1000;
00967             }
00968       }
00969    }
00970 
00971         if (silence > 0) {
00972          rfmt = chan->readformat;
00973                 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
00974                 if (res < 0) {
00975                   ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
00976                         return -1;
00977                 }
00978                   sildet = ast_dsp_new();
00979                 if (!sildet) {
00980                   ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
00981                         return -1;
00982                 }
00983                   ast_dsp_set_threshold(sildet, 256);
00984          }
00985 
00986    /* backward compatibility, if no offset given, arg[6] would have been
00987     * caught below and taken to be a beep, else if it is a digit then it is a
00988     * offset */
00989    if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '=')))
00990       res = ast_streamfile(chan, "beep", chan->language);
00991 
00992    if ((argc > 7) && (!strchr(argv[7], '=')))
00993       res = ast_streamfile(chan, "beep", chan->language);
00994 
00995    if (!res)
00996       res = ast_waitstream(chan, argv[4]);
00997    if (res) {
00998       fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
00999    } else {
01000       fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644);
01001       if (!fs) {
01002          res = -1;
01003          fdprintf(agi->fd, "200 result=%d (writefile)\n", res);
01004          if (sildet)
01005             ast_dsp_free(sildet);
01006          return RESULT_FAILURE;
01007       }
01008       
01009       /* Request a video update */
01010       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
01011    
01012       chan->stream = fs;
01013       ast_applystream(chan,fs);
01014       /* really should have checks */
01015       ast_seekstream(fs, sample_offset, SEEK_SET);
01016       ast_truncstream(fs);
01017       
01018       start = ast_tvnow();
01019       while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
01020          res = ast_waitfor(chan, -1);
01021          if (res < 0) {
01022             ast_closestream(fs);
01023             fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
01024             if (sildet)
01025                ast_dsp_free(sildet);
01026             return RESULT_FAILURE;
01027          }
01028          f = ast_read(chan);
01029          if (!f) {
01030             fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset);
01031             ast_closestream(fs);
01032             if (sildet)
01033                ast_dsp_free(sildet);
01034             return RESULT_FAILURE;
01035          }
01036          switch(f->frametype) {
01037          case AST_FRAME_DTMF:
01038             if (strchr(argv[4], f->subclass)) {
01039                /* This is an interrupting chracter, so rewind to chop off any small
01040                   amount of DTMF that may have been recorded
01041                */
01042                ast_stream_rewind(fs, 200);
01043                ast_truncstream(fs);
01044                sample_offset = ast_tellstream(fs);
01045                fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset);
01046                ast_closestream(fs);
01047                ast_frfree(f);
01048                if (sildet)
01049                   ast_dsp_free(sildet);
01050                return RESULT_SUCCESS;
01051             }
01052             break;
01053          case AST_FRAME_VOICE:
01054             ast_writestream(fs, f);
01055             /* this is a safe place to check progress since we know that fs
01056              * is valid after a write, and it will then have our current
01057              * location */
01058             sample_offset = ast_tellstream(fs);
01059                                 if (silence > 0) {
01060                                  dspsilence = 0;
01061                                         ast_dsp_silence(sildet, f, &dspsilence);
01062                                         if (dspsilence) {
01063                                              totalsilence = dspsilence;
01064                                         } else {
01065                                                 totalsilence = 0;
01066                                         }
01067                                         if (totalsilence > silence) {
01068                                              /* Ended happily with silence */
01069                                                 gotsilence = 1;
01070                                                 break;
01071                                         }
01072                               }
01073             break;
01074          case AST_FRAME_VIDEO:
01075             ast_writestream(fs, f);
01076          default:
01077             /* Ignore all other frames */
01078             break;
01079          }
01080          ast_frfree(f);
01081          if (gotsilence)
01082             break;
01083          }
01084 
01085                if (gotsilence) {
01086                         ast_stream_rewind(fs, silence-1000);
01087                   ast_truncstream(fs);
01088          sample_offset = ast_tellstream(fs);
01089       }     
01090       fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
01091       ast_closestream(fs);
01092    }
01093 
01094         if (silence > 0) {
01095                 res = ast_set_read_format(chan, rfmt);
01096                 if (res)
01097                         ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
01098                 ast_dsp_free(sildet);
01099         }
01100    return RESULT_SUCCESS;
01101 }

static int handle_recvchar ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 496 of file res_agi.c.

References ast_recvchar(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00497 {
00498    int res;
00499    if (argc != 3)
00500       return RESULT_SHOWUSAGE;
00501    res = ast_recvchar(chan,atoi(argv[2]));
00502    if (res == 0) {
00503       fdprintf(agi->fd, "200 result=%d (timeout)\n", res);
00504       return RESULT_SUCCESS;
00505    }
00506    if (res > 0) {
00507       fdprintf(agi->fd, "200 result=%d\n", res);
00508       return RESULT_SUCCESS;
00509    }
00510    else {
00511       fdprintf(agi->fd, "200 result=%d (hangup)\n", res);
00512       return RESULT_FAILURE;
00513    }
00514 }

static int handle_recvtext ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 516 of file res_agi.c.

References ast_recvtext(), ast_hostent::buf, agi_state::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00517 {
00518    char *buf;
00519    
00520    if (argc != 3)
00521       return RESULT_SHOWUSAGE;
00522    buf = ast_recvtext(chan,atoi(argv[2]));
00523    if (buf) {
00524       fdprintf(agi->fd, "200 result=1 (%s)\n", buf);
00525       free(buf);
00526    } else { 
00527       fdprintf(agi->fd, "200 result=-1\n");
00528    }
00529    return RESULT_SUCCESS;
00530 }

static int handle_sayalpha ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 770 of file res_agi.c.

References ast_say_character_str_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00771 {
00772    int res;
00773 
00774    if (argc != 4)
00775       return RESULT_SHOWUSAGE;
00776 
00777    res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00778    if (res == 1) /* New command */
00779       return RESULT_SUCCESS;
00780    fdprintf(agi->fd, "200 result=%d\n", res);
00781    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00782 }

static int handle_saydate ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 784 of file res_agi.c.

References ast_say_date, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00785 {
00786    int res;
00787    int num;
00788    if (argc != 4)
00789       return RESULT_SHOWUSAGE;
00790    if (sscanf(argv[2], "%d", &num) != 1)
00791       return RESULT_SHOWUSAGE;
00792    res = ast_say_date(chan, num, argv[3], chan->language);
00793    if (res == 1)
00794       return RESULT_SUCCESS;
00795    fdprintf(agi->fd, "200 result=%d\n", res);
00796    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00797 }

static int handle_saydatetime ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 814 of file res_agi.c.

References ast_get_time_t(), ast_say_date_with_format, ast_strlen_zero(), agi_state::fd, fdprintf, format, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00815 {
00816    int res=0;
00817    time_t unixtime;
00818    char *format, *zone=NULL;
00819    
00820    if (argc < 4)
00821       return RESULT_SHOWUSAGE;
00822 
00823    if (argc > 4) {
00824       format = argv[4];
00825    } else {
00826       /* XXX this doesn't belong here, but in the 'say' module */
00827       if (!strcasecmp(chan->language, "de")) {
00828          format = "A dBY HMS";
00829       } else {
00830          format = "ABdY 'digits/at' IMp"; 
00831       }
00832    }
00833 
00834    if (argc > 5 && !ast_strlen_zero(argv[5]))
00835       zone = argv[5];
00836 
00837    if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
00838       return RESULT_SHOWUSAGE;
00839 
00840    res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone);
00841    if (res == 1)
00842       return RESULT_SUCCESS;
00843 
00844    fdprintf(agi->fd, "200 result=%d\n", res);
00845    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00846 }

static int handle_saydigits ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 753 of file res_agi.c.

References ast_say_digit_str_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00754 {
00755    int res;
00756    int num;
00757 
00758    if (argc != 4)
00759       return RESULT_SHOWUSAGE;
00760    if (sscanf(argv[2], "%d", &num) != 1)
00761       return RESULT_SHOWUSAGE;
00762 
00763    res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00764    if (res == 1) /* New command */
00765       return RESULT_SUCCESS;
00766    fdprintf(agi->fd, "200 result=%d\n", res);
00767    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00768 }

static int handle_saynumber ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 738 of file res_agi.c.

References ast_say_number_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00739 {
00740    int res;
00741    int num;
00742    if (argc != 4)
00743       return RESULT_SHOWUSAGE;
00744    if (sscanf(argv[2], "%d", &num) != 1)
00745       return RESULT_SHOWUSAGE;
00746    res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl);
00747    if (res == 1)
00748       return RESULT_SUCCESS;
00749    fdprintf(agi->fd, "200 result=%d\n", res);
00750    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00751 }

static int handle_sayphonetic ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 848 of file res_agi.c.

References ast_say_phonetic_str_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00849 {
00850    int res;
00851 
00852    if (argc != 4)
00853       return RESULT_SHOWUSAGE;
00854 
00855    res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00856    if (res == 1) /* New command */
00857       return RESULT_SUCCESS;
00858    fdprintf(agi->fd, "200 result=%d\n", res);
00859    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00860 }

static int handle_saytime ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 799 of file res_agi.c.

References ast_say_time, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00800 {
00801    int res;
00802    int num;
00803    if (argc != 4)
00804       return RESULT_SHOWUSAGE;
00805    if (sscanf(argv[2], "%d", &num) != 1)
00806       return RESULT_SHOWUSAGE;
00807    res = ast_say_time(chan, num, argv[3], chan->language);
00808    if (res == 1)
00809       return RESULT_SUCCESS;
00810    fdprintf(agi->fd, "200 result=%d\n", res);
00811    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00812 }

static int handle_sendimage ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 553 of file res_agi.c.

References ast_check_hangup(), ast_send_image(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00554 {
00555    int res;
00556    if (argc != 3)
00557       return RESULT_SHOWUSAGE;
00558    res = ast_send_image(chan, argv[2]);
00559    if (!ast_check_hangup(chan))
00560       res = 0;
00561    fdprintf(agi->fd, "200 result=%d\n", res);
00562    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00563 }

static int handle_sendtext ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 479 of file res_agi.c.

References ast_sendtext(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00480 {
00481    int res;
00482    if (argc != 3)
00483       return RESULT_SHOWUSAGE;
00484    /* At the moment, the parser (perhaps broken) returns with
00485       the last argument PLUS the newline at the end of the input
00486       buffer. This probably needs to be fixed, but I wont do that
00487       because other stuff may break as a result. The right way
00488       would probably be to strip off the trailing newline before
00489       parsing, then here, add a newline at the end of the string
00490       before sending it to ast_sendtext --DUDE */
00491    res = ast_sendtext(chan, argv[2]);
00492    fdprintf(agi->fd, "200 result=%d\n", res);
00493    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00494 }

static int handle_setcallerid ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1172 of file res_agi.c.

References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, fdprintf, and RESULT_SUCCESS.

01173 {
01174    char tmp[256]="";
01175    char *l = NULL, *n = NULL;
01176 
01177    if (argv[2]) {
01178       ast_copy_string(tmp, argv[2], sizeof(tmp));
01179       ast_callerid_parse(tmp, &n, &l);
01180       if (l)
01181          ast_shrink_phone_number(l);
01182       else
01183          l = "";
01184       if (!n)
01185          n = "";
01186       ast_set_callerid(chan, l, n, NULL);
01187    }
01188 
01189    fdprintf(agi->fd, "200 result=1\n");
01190    return RESULT_SUCCESS;
01191 }

static int handle_setcontext ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 891 of file res_agi.c.

References ast_channel::context, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00892 {
00893 
00894    if (argc != 3)
00895       return RESULT_SHOWUSAGE;
00896    ast_copy_string(chan->context, argv[2], sizeof(chan->context));
00897    fdprintf(agi->fd, "200 result=0\n");
00898    return RESULT_SUCCESS;
00899 }

static int handle_setextension ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 901 of file res_agi.c.

References ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00902 {
00903    if (argc != 3)
00904       return RESULT_SHOWUSAGE;
00905    ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
00906    fdprintf(agi->fd, "200 result=0\n");
00907    return RESULT_SUCCESS;
00908 }

static int handle_setmusic ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 1399 of file res_agi.c.

References ast_moh_start(), ast_moh_stop(), agi_state::fd, fdprintf, and RESULT_SUCCESS.

01400 {
01401    if (!strncasecmp(argv[2], "on", 2))
01402       ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
01403    else if (!strncasecmp(argv[2], "off", 3))
01404       ast_moh_stop(chan);
01405    fdprintf(agi->fd, "200 result=0\n");
01406    return RESULT_SUCCESS;
01407 }

static int handle_setpriority ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 910 of file res_agi.c.

References ast_explicit_goto(), ast_findlabel_extension(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00911 {
00912    int pri;
00913    if (argc != 3)
00914       return RESULT_SHOWUSAGE;   
00915 
00916    if (sscanf(argv[2], "%d", &pri) != 1) {
00917       if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
00918          return RESULT_SHOWUSAGE;
00919    }
00920 
00921    ast_explicit_goto(chan, NULL, NULL, pri);
00922    fdprintf(agi->fd, "200 result=0\n");
00923    return RESULT_SUCCESS;
00924 }

static int handle_setvariable ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1216 of file res_agi.c.

References agi_state::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS.

01217 {
01218    if (argv[3])
01219       pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
01220 
01221    fdprintf(agi->fd, "200 result=1\n");
01222    return RESULT_SUCCESS;
01223 }

static int handle_showagi ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2025 of file res_agi.c.

References ast_cli(), ast_join(), find_command(), help_workhorse(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage.

02026 {
02027    struct agi_command *e;
02028    char fullcmd[80];
02029    if ((argc < 2))
02030       return RESULT_SHOWUSAGE;
02031    if (argc > 2) {
02032       e = find_command(argv + 2, 1);
02033       if (e) 
02034          ast_cli(fd, e->usage);
02035       else {
02036          if (find_command(argv + 2, -1)) {
02037             return help_workhorse(fd, argv + 1);
02038          } else {
02039             ast_join(fullcmd, sizeof(fullcmd), argv+1);
02040             ast_cli(fd, "No such command '%s'.\n", fullcmd);
02041          }
02042       }
02043    } else {
02044       return help_workhorse(fd, NULL);
02045    }
02046    return RESULT_SUCCESS;
02047 }

static int handle_streamfile ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 607 of file res_agi.c.

References ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_verbose(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, LOG_DEBUG, option_verbose, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.

00608 {
00609    int res;
00610    int vres;   
00611    struct ast_filestream *fs;
00612    struct ast_filestream *vfs;
00613    long sample_offset = 0;
00614    long max_length;
00615    char *edigits = "";
00616 
00617    if (argc < 4 || argc > 5)
00618       return RESULT_SHOWUSAGE;
00619 
00620    if (argv[3]) 
00621       edigits = argv[3];
00622 
00623    if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1))
00624       return RESULT_SHOWUSAGE;
00625    
00626    fs = ast_openstream(chan, argv[2], chan->language);   
00627    
00628    if (!fs) {
00629       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
00630       return RESULT_SUCCESS;
00631    }  
00632    vfs = ast_openvstream(chan, argv[2], chan->language);
00633    if (vfs)
00634       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00635       
00636    if (option_verbose > 2)
00637       ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
00638 
00639    ast_seekstream(fs, 0, SEEK_END);
00640    max_length = ast_tellstream(fs);
00641    ast_seekstream(fs, sample_offset, SEEK_SET);
00642    res = ast_applystream(chan, fs);
00643    if (vfs)
00644       vres = ast_applystream(chan, vfs);
00645    ast_playstream(fs);
00646    if (vfs)
00647       ast_playstream(vfs);
00648    
00649    res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
00650    /* this is to check for if ast_waitstream closed the stream, we probably are at
00651     * the end of the stream, return that amount, else check for the amount */
00652    sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
00653    ast_stopstream(chan);
00654    if (res == 1) {
00655       /* Stop this command, don't print a result line, as there is a new command */
00656       return RESULT_SUCCESS;
00657    }
00658    fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00659    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00660 }

static int handle_tddmode ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 532 of file res_agi.c.

References ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00533 {
00534    int res,x;
00535    if (argc != 3)
00536       return RESULT_SHOWUSAGE;
00537    if (!strncasecmp(argv[2],"on",2)) 
00538       x = 1; 
00539    else 
00540       x = 0;
00541    if (!strncasecmp(argv[2],"mate",4)) 
00542       x = 2;
00543    if (!strncasecmp(argv[2],"tdd",3))
00544       x = 1;
00545    res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
00546    if (res != RESULT_SUCCESS)
00547       fdprintf(agi->fd, "200 result=0\n");
00548    else
00549       fdprintf(agi->fd, "200 result=1\n");
00550    return RESULT_SUCCESS;
00551 }

static int handle_verbose ( struct ast_channel chan,
AGI agi,
int  argc,
char **  argv 
) [static]

Definition at line 1271 of file res_agi.c.

References ast_verbose(), ast_channel::data, agi_state::fd, fdprintf, option_verbose, prefix, RESULT_SHOWUSAGE, RESULT_SUCCESS, VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

01272 {
01273    int level = 0;
01274    char *prefix;
01275 
01276    if (argc < 2)
01277       return RESULT_SHOWUSAGE;
01278 
01279    if (argv[2])
01280       sscanf(argv[2], "%d", &level);
01281 
01282    switch (level) {
01283       case 4:
01284          prefix = VERBOSE_PREFIX_4;
01285          break;
01286       case 3:
01287          prefix = VERBOSE_PREFIX_3;
01288          break;
01289       case 2:
01290          prefix = VERBOSE_PREFIX_2;
01291          break;
01292       case 1:
01293       default:
01294          prefix = VERBOSE_PREFIX_1;
01295          break;
01296    }
01297 
01298    if (level <= option_verbose)
01299       ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]);
01300    
01301    fdprintf(agi->fd, "200 result=1\n");
01302    
01303    return RESULT_SUCCESS;
01304 }

static int handle_waitfordigit ( struct ast_channel chan,
AGI agi,
int  argc,
char *  argv[] 
) [static]

Definition at line 466 of file res_agi.c.

References ast_waitfordigit_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00467 {
00468    int res;
00469    int to;
00470    if (argc != 4)
00471       return RESULT_SHOWUSAGE;
00472    if (sscanf(argv[3], "%d", &to) != 1)
00473       return RESULT_SHOWUSAGE;
00474    res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
00475    fdprintf(agi->fd, "200 result=%d\n", res);
00476    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00477 }

static int help_workhorse ( int  fd,
char *  match[] 
) [static]

Definition at line 1696 of file res_agi.c.

References ast_cli(), ast_join(), agi_command::cmda, commands, and agi_command::summary.

01697 {
01698    char fullcmd[80];
01699    char matchstr[80];
01700    int x;
01701    struct agi_command *e;
01702    if (match)
01703       ast_join(matchstr, sizeof(matchstr), match);
01704    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
01705       e = &commands[x]; 
01706       if (!e->cmda[0])
01707          break;
01708       /* Hide commands that start with '_' */
01709       if ((e->cmda[0])[0] == '_')
01710          continue;
01711       ast_join(fullcmd, sizeof(fullcmd), e->cmda);
01712       if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr)))
01713          continue;
01714       ast_cli(fd, "%20.20s   %s\n", fullcmd, e->summary);
01715    }
01716    return 0;
01717 }

static enum agi_result launch_netscript ( char *  agiurl,
char *  argv[],
int *  fds,
int *  efd,
int *  opid 
) [static]

Definition at line 152 of file res_agi.c.

References AGI_PORT, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS_FAST, ahp, ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), errno, pollfd::events, pollfd::fd, fdprintf, hp, LOG_DEBUG, LOG_WARNING, MAX_AGI_CONNECT, option_debug, poll(), POLLOUT, and s.

Referenced by launch_script().

00153 {
00154    int s;
00155    int flags;
00156    struct pollfd pfds[1];
00157    char *host;
00158    char *c; int port = AGI_PORT;
00159    char *script="";
00160    struct sockaddr_in sin;
00161    struct hostent *hp;
00162    struct ast_hostent ahp;
00163    int res;
00164 
00165    /* agiusl is "agi://host.domain[:port][/script/name]" */
00166    host = ast_strdupa(agiurl + 6);  /* Remove agi:// */
00167    /* Strip off any script name */
00168    if ((c = strchr(host, '/'))) {
00169       *c = '\0';
00170       c++;
00171       script = c;
00172    }
00173    if ((c = strchr(host, ':'))) {
00174       *c = '\0';
00175       c++;
00176       port = atoi(c);
00177    }
00178    if (efd) {
00179       ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n");
00180       return -1;
00181    }
00182    hp = ast_gethostbyname(host, &ahp);
00183    if (!hp) {
00184       ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
00185       return -1;
00186    }
00187    s = socket(AF_INET, SOCK_STREAM, 0);
00188    if (s < 0) {
00189       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
00190       return -1;
00191    }
00192    flags = fcntl(s, F_GETFL);
00193    if (flags < 0) {
00194       ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno));
00195       close(s);
00196       return -1;
00197    }
00198    if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
00199       ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno));
00200       close(s);
00201       return -1;
00202    }
00203    memset(&sin, 0, sizeof(sin));
00204    sin.sin_family = AF_INET;
00205    sin.sin_port = htons(port);
00206    memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
00207    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) {
00208       ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno));
00209       close(s);
00210       return AGI_RESULT_FAILURE;
00211    }
00212 
00213    pfds[0].fd = s;
00214    pfds[0].events = POLLOUT;
00215    while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) {
00216       if (errno != EINTR) {
00217          if (!res) {
00218             ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n",
00219                agiurl, MAX_AGI_CONNECT);
00220          } else
00221             ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
00222          close(s);
00223          return AGI_RESULT_FAILURE;
00224       }
00225    }
00226 
00227    if (fdprintf(s, "agi_network: yes\n") < 0) {
00228       if (errno != EINTR) {
00229          ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno));
00230          close(s);
00231          return AGI_RESULT_FAILURE;
00232       }
00233    }
00234 
00235    /* If we have a script parameter, relay it to the fastagi server */
00236    if (!ast_strlen_zero(script))
00237       fdprintf(s, "agi_network_script: %s\n", script);
00238 
00239    if (option_debug > 3)
00240       ast_log(LOG_DEBUG, "Wow, connected!\n");
00241    fds[0] = s;
00242    fds[1] = s;
00243    *opid = -1;
00244    return AGI_RESULT_SUCCESS_FAST;
00245 }

static enum agi_result launch_script ( char *  script,
char *  argv[],
int *  fds,
int *  efd,
int *  efd2,
int *  opid 
) [static]

Definition at line 247 of file res_agi.c.

References AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_MONITOR_DIR, ast_config_AST_RUN_DIR, ast_config_AST_SPOOL_DIR, ast_config_AST_VAR_DIR, ast_log(), ast_set_priority(), ast_verbose(), errno, launch_netscript(), LOG_WARNING, option_verbose, setenv(), and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

00248 {
00249    char tmp[256];
00250    int pid;
00251    int toast[2];
00252    int fromast[2];
00253    int audio[2];
00254    int audio2[2];
00255    int x;
00256    int res;
00257    sigset_t signal_set, old_set;
00258    
00259    if (!strncasecmp(script, "agi://", 6))
00260       return launch_netscript(script, argv, fds, efd, opid);
00261    
00262    if (script[0] != '/') {
00263       snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script);
00264       script = tmp;
00265    }
00266    if (pipe(toast)) {
00267       ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
00268       return AGI_RESULT_FAILURE;
00269    }
00270    if (pipe(fromast)) {
00271       ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
00272       close(toast[0]);
00273       close(toast[1]);
00274       return AGI_RESULT_FAILURE;
00275    }
00276    if (efd) {
00277       if (pipe(audio)) {
00278          ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
00279          close(fromast[0]);
00280          close(fromast[1]);
00281          close(toast[0]);
00282          close(toast[1]);
00283          return AGI_RESULT_FAILURE;
00284       }
00285       res = fcntl(audio[1], F_GETFL);
00286       if (res > -1) 
00287          res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
00288       if (res < 0) {
00289          ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
00290          close(fromast[0]);
00291          close(fromast[1]);
00292          close(toast[0]);
00293          close(toast[1]);
00294          close(audio[0]);
00295          close(audio[1]);
00296          return AGI_RESULT_FAILURE;
00297       }
00298    }
00299    if (efd2) {
00300       if (pipe(audio2)) {
00301          ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
00302          close(fromast[0]);
00303          close(fromast[1]);
00304          close(toast[0]);
00305          close(toast[1]);
00306          close(audio[0]);
00307          close(audio[1]);
00308          return AGI_RESULT_FAILURE;
00309       }
00310       res = fcntl(audio2[0], F_GETFL);
00311       if (res > -1)
00312          res = fcntl(audio2[0], F_SETFL, res | O_NONBLOCK);
00313       if (res < 0) {
00314          ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
00315          close(fromast[0]);
00316          close(fromast[1]);
00317          close(toast[0]);
00318          close(toast[1]);
00319          close(audio[0]);
00320          close(audio[1]);
00321          close(audio2[0]);
00322          close(audio2[1]);
00323          return AGI_RESULT_FAILURE;
00324       }
00325    }
00326 
00327    /* Block SIGHUP during the fork - prevents a race */
00328    sigfillset(&signal_set);
00329    pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
00330    pid = fork();
00331    if (pid < 0) {
00332       ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
00333       pthread_sigmask(SIG_SETMASK, &old_set, NULL);
00334       return AGI_RESULT_FAILURE;
00335    }
00336    if (!pid) {
00337       /* Pass paths to AGI via environmental variables */
00338       setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
00339       setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
00340       setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
00341       setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
00342       setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
00343       setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
00344       setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
00345       setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
00346       setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
00347       setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
00348       setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
00349 
00350       /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
00351       ast_set_priority(0);
00352 
00353       /* Redirect stdin and out, provide enhanced audio channel if desired */
00354       dup2(fromast[0], STDIN_FILENO);
00355       dup2(toast[1], STDOUT_FILENO);
00356       if (efd) {
00357          dup2(audio[0], STDERR_FILENO + 1);
00358       } else {
00359          close(STDERR_FILENO + 1);
00360       }
00361       if (efd2) {
00362          dup2(audio2[1], STDERR_FILENO + 2);
00363       } else {
00364          close(STDERR_FILENO + 2);
00365       }
00366 
00367       /* Before we unblock our signals, return our trapped signals back to the defaults */
00368       signal(SIGHUP, SIG_DFL);
00369       signal(SIGCHLD, SIG_DFL);
00370       signal(SIGINT, SIG_DFL);
00371       signal(SIGURG, SIG_DFL);
00372       signal(SIGTERM, SIG_DFL);
00373       signal(SIGPIPE, SIG_DFL);
00374       signal(SIGXFSZ, SIG_DFL);
00375 
00376       /* unblock important signal handlers */
00377       if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
00378          ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
00379          _exit(1);
00380       }
00381 
00382       /* Close everything but stdin/out/error */
00383       for (x=STDERR_FILENO + 3;x<1024;x++)
00384          close(x);
00385 
00386       /* Execute script */
00387       execv(script, argv);
00388       /* Can't use ast_log since FD's are closed */
00389       fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno));
00390       /* Special case to set status of AGI to failure */
00391       fprintf(stdout, "failure\n");
00392       fflush(stdout);
00393       _exit(1);
00394    }
00395    pthread_sigmask(SIG_SETMASK, &old_set, NULL);
00396    if (option_verbose > 2) 
00397       ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
00398    fds[0] = toast[0];
00399    fds[1] = fromast[1];
00400    if (efd) {
00401       *efd = audio[1];
00402    }
00403    if (efd2) {
00404       *efd2 = audio2[0];
00405    }
00406    /* close what we're not using in the parent */
00407    close(toast[1]);
00408    close(fromast[0]);
00409 
00410    if (efd) {
00411       close(audio[0]);
00412    }
00413    if (efd2) {
00414       close(audio2[1]);
00415    }
00416 
00417    *opid = pid;
00418    return AGI_RESULT_SUCCESS;
00419 }

static int load_module ( void   )  [static]

Definition at line 2296 of file res_agi.c.

References agi_exec(), ast_cli_register_multiple(), ast_register_application(), cli_agi, deadagi_exec(), eagi_exec(), and xagi_exec().

static int parse_args ( char *  s,
int *  max,
char *  argv[] 
) [static]

Definition at line 1782 of file res_agi.c.

References ast_log(), LOG_WARNING, and MAX_ARGS.

01783 {
01784    int x=0;
01785    int quoted=0;
01786    int escaped=0;
01787    int whitespace=1;
01788    char *cur;
01789 
01790    cur = s;
01791    while(*s) {
01792       switch(*s) {
01793       case '"':
01794          /* If it's escaped, put a literal quote */
01795          if (escaped) 
01796             goto normal;
01797          else 
01798             quoted = !quoted;
01799          if (quoted && whitespace) {
01800             /* If we're starting a quote, coming off white space start a new word, too */
01801             argv[x++] = cur;
01802             whitespace=0;
01803          }
01804          escaped = 0;
01805       break;
01806       case ' ':
01807       case '\t':
01808          if (!quoted && !escaped) {
01809             /* If we're not quoted, mark this as whitespace, and
01810                end the previous argument */
01811             whitespace = 1;
01812             *(cur++) = '\0';
01813          } else
01814             /* Otherwise, just treat it as anything else */ 
01815             goto normal;
01816          break;
01817       case '\\':
01818          /* If we're escaped, print a literal, otherwise enable escaping */
01819          if (escaped) {
01820             goto normal;
01821          } else {
01822             escaped=1;
01823          }
01824          break;
01825       default:
01826 normal:
01827          if (whitespace) {
01828             if (x >= MAX_ARGS -1) {
01829                ast_log(LOG_WARNING, "Too many arguments, truncating\n");
01830                break;
01831             }
01832             /* Coming off of whitespace, start the next argument */
01833             argv[x++] = cur;
01834             whitespace=0;
01835          }
01836          *(cur++) = *s;
01837          escaped=0;
01838       }
01839       s++;
01840    }
01841    /* Null terminate */
01842    *(cur++) = '\0';
01843    argv[x] = NULL;
01844    *max = x;
01845    return 0;
01846 }

static enum agi_result run_agi ( struct ast_channel chan,
char *  request,
AGI agi,
int  pid,
int *  status,
int  dead 
) [static]

Definition at line 1879 of file res_agi.c.

References AGI_BUF_LEN, agi_handle_command(), AGI_NANDFS_RETRY, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_verbose(), ast_waitfor_nandfds(), ast_write(), agi_state::audio, agi_state::audio_in, agi_state::ctrl, ast_frame::data, ast_frame::datalen, errno, f, agi_state::fast, agi_state::fd, ast_frame::frametype, len, LOG_DEBUG, LOG_WARNING, option_verbose, setup_env(), ast_frame::subclass, and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

01880 {
01881    struct ast_channel *c;
01882    int outfd;
01883    int ms;
01884    enum agi_result returnstatus = AGI_RESULT_SUCCESS;
01885    struct ast_frame *f;
01886    struct ast_frame fr;
01887    char buf[AGI_BUF_LEN];
01888    char audiobuf[AGI_BUF_LEN];
01889    char *res = NULL;
01890    int audiobytes;
01891    int fds[2];
01892    int enhanced = 0;
01893    FILE *readf;
01894    /* how many times we'll retry if ast_waitfor_nandfs will return without either 
01895      channel or file descriptor in case select is interrupted by a system call (EINTR) */
01896    int retry = AGI_NANDFS_RETRY;
01897 
01898    if (!(readf = fdopen(agi->ctrl, "r"))) {
01899       ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n");
01900       if (pid > -1)
01901          kill(pid, SIGHUP);
01902       close(agi->ctrl);
01903       return AGI_RESULT_FAILURE;
01904    }
01905    setlinebuf(readf);
01906    if (agi->audio > -1) {
01907        enhanced = 1;
01908    }
01909    if (agi->audio_in > -1) {
01910        enhanced++;
01911    }
01912    setup_env(chan, request, agi->fd, enhanced);
01913    fds[0] = agi->ctrl;
01914    fds[1] = agi->audio_in;
01915    for (;;) {
01916       ms = -1;
01917       if (agi->audio_in > -1) {
01918           c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, fds, 2, NULL, &outfd, &ms);
01919       } else {
01920           c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
01921       }
01922       if (c) {
01923          retry = AGI_NANDFS_RETRY;
01924          /* Idle the channel until we get a command */
01925          f = ast_read(c);
01926          if (!f) {
01927             ast_log(LOG_DEBUG, "%s hungup\n", chan->name);
01928             returnstatus = AGI_RESULT_HANGUP;
01929             break;
01930          } else {
01931             /* If it's voice, write it to the audio pipe */
01932             if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) {
01933                /* Write, ignoring errors */
01934                write(agi->audio, f->data, f->datalen);
01935             }
01936             ast_frfree(f);
01937          }
01938       } else if (outfd > -1) {
01939           if ((agi->audio_in > -1) && (outfd == agi->audio_in)) {
01940          audiobytes = read(agi->audio_in, audiobuf, sizeof(audiobuf));
01941          if (audiobytes > 0) {
01942              fr.frametype = AST_FRAME_VOICE;
01943              fr.subclass = AST_FORMAT_SLINEAR;
01944              fr.datalen = audiobytes;
01945              fr.data = audiobuf;
01946              ast_write(chan, &fr);
01947          }
01948           } else {
01949          size_t len = sizeof(buf);
01950          size_t buflen = 0;
01951 
01952          retry = AGI_NANDFS_RETRY;
01953          buf[0] = '\0';
01954 
01955          while (buflen < (len - 1)) {
01956             res = fgets(buf + buflen, len, readf);
01957             if (feof(readf)) 
01958                break;
01959             if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN))) 
01960                break;
01961             if (res != NULL && !agi->fast)
01962                break;
01963             buflen = strlen(buf);
01964             if (buflen && buf[buflen - 1] == '\n')
01965                break;
01966             len -= buflen;
01967             if (agidebug)
01968                ast_verbose( "AGI Rx << temp buffer %s - errno %s\n", buf, strerror(errno));
01969          }
01970 
01971          if (!buf[0]) {
01972             /* Program terminated */
01973             if (returnstatus)
01974                returnstatus = -1;
01975             if (option_verbose > 2) 
01976                ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus);
01977             if (pid > 0)
01978                waitpid(pid, status, 0);
01979             /* No need to kill the pid anymore, since they closed us */
01980             pid = -1;
01981             break;
01982          }
01983 
01984          /* Special case for inability to execute child process */
01985          if (*buf && strncasecmp(buf, "failure", 7) == 0) {
01986             returnstatus = AGI_RESULT_FAILURE;
01987             break;
01988          }
01989 
01990          /* get rid of trailing newline, if any */
01991          if (*buf && buf[strlen(buf) - 1] == '\n')
01992             buf[strlen(buf) - 1] = 0;
01993          if (agidebug)
01994             ast_verbose("AGI Rx << %s\n", buf);
01995          returnstatus |= agi_handle_command(chan, agi, buf);
01996          /* If the handle_command returns -1, we need to stop */
01997          if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
01998             break;
01999          }
02000           }
02001       } else {
02002          if (--retry <= 0) {
02003             ast_log(LOG_WARNING, "No channel, no fd?\n");
02004             returnstatus = AGI_RESULT_FAILURE;
02005             break;
02006          }
02007       }
02008    }
02009    /* Notify process */
02010    if (pid > -1) {
02011       const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
02012       if (ast_strlen_zero(sighup) || !ast_false(sighup)) {
02013          if (kill(pid, SIGHUP)) {
02014             ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno));
02015          } else { /* Give the process a chance to die */
02016             usleep(1);
02017          }
02018       }
02019       waitpid(pid, status, WNOHANG);
02020    }
02021    fclose(readf);
02022    return returnstatus;
02023 }

static void setup_env ( struct ast_channel chan,
char *  request,
int  fd,
int  enhanced 
) [static]

Definition at line 421 of file res_agi.c.

References ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, fdprintf, ast_channel::priority, S_OR, ast_channel::tech, and ast_channel_tech::type.

Referenced by run_agi().

00422 {
00423    /* Print initial environment, with agi_request always being the first
00424       thing */
00425    fdprintf(fd, "agi_request: %s\n", request);
00426    fdprintf(fd, "agi_channel: %s\n", chan->name);
00427    fdprintf(fd, "agi_language: %s\n", chan->language);
00428    fdprintf(fd, "agi_type: %s\n", chan->tech->type);
00429    fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid);
00430 
00431    /* ANI/DNIS */
00432    fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown"));
00433    fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown"));
00434    fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres);
00435    fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2);
00436    fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton);
00437    fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns);
00438    fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown"));
00439    fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown"));
00440 
00441    /* Context information */
00442    fdprintf(fd, "agi_context: %s\n", chan->context);
00443    fdprintf(fd, "agi_extension: %s\n", chan->exten);
00444    fdprintf(fd, "agi_priority: %d\n", chan->priority);
00445    fdprintf(fd, "agi_enhanced: %d%s\n", enhanced, ".0");
00446 
00447    /* User information */
00448    fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
00449     
00450    /* End with empty return */
00451    fdprintf(fd, "\n");
00452 }

static int unload_module ( void   )  [static]

Definition at line 2286 of file res_agi.c.

References ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_unregister_application(), and cli_agi.

static int xagi_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 2206 of file res_agi.c.

References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), ast_set_write_format(), ast_module_user::chan, LOG_WARNING, ast_channel::readformat, and ast_channel::writeformat.

Referenced by load_module().

02207 {
02208    int readformat, writeformat;
02209    int res;
02210 
02211    if (chan->_softhangup)
02212       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02213    readformat = chan->readformat;
02214    if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
02215       ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
02216       return -1;
02217    }
02218    writeformat = chan->writeformat;
02219    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
02220       ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
02221       return -1;
02222    }
02223    res = agi_exec_full(chan, data, 2, 0);
02224    if (!res) {
02225       if (ast_set_read_format(chan, readformat)) {
02226          ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
02227       }
02228       if (ast_set_write_format(chan, writeformat)) {
02229          ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(writeformat));
02230       }
02231    }
02232    return res;
02233 }


Variable Documentation

int agidebug = 0 [static]

Definition at line 113 of file res_agi.c.

char* app = "AGI" [static]

Definition at line 79 of file res_agi.c.

struct ast_cli_entry cli_agi[] [static]

Definition at line 2268 of file res_agi.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_agi_no_debug_deprecated [static]

Initial value:

 {
   { "agi", "no", "debug", NULL },
   agi_no_debug_deprecated, NULL,
   NULL }

Definition at line 2263 of file res_agi.c.

struct ast_cli_entry cli_dump_agihtml_deprecated [static]

Initial value:

 {
   { "dump", "agihtml", NULL },
   handle_agidumphtml, NULL,
   NULL }

Definition at line 2258 of file res_agi.c.

struct ast_cli_entry cli_show_agi_deprecated [static]

Initial value:

 {
   { "show", "agi", NULL },
   handle_showagi, NULL,
   NULL }

Definition at line 2253 of file res_agi.c.

agi_command commands[MAX_COMMANDS] [static]

Definition at line 1656 of file res_agi.c.

Referenced by aji_dinfo_handler(), ast_agi_register(), ast_agi_unregister(), dundi_showframe(), find_command(), handle_agidumphtml(), and help_workhorse().

char* deadapp = "DeadAGI" [static]

Definition at line 85 of file res_agi.c.

char* deadsynopsis = "Executes AGI on a hungup channel" [static]

Definition at line 90 of file res_agi.c.

char debug_usage[] [static]

Initial value:

 
"Usage: agi debug\n"
"       Enables dumping of AGI transactions for debugging purposes\n"

Definition at line 1358 of file res_agi.c.

char* descrip [static]

Definition at line 92 of file res_agi.c.

char dumpagihtml_help[] [static]

Initial value:

"Usage: agi dumphtml <filename>\n"
"  Dumps the agi command list in html format to given filename\n"

Definition at line 2249 of file res_agi.c.

char* eapp = "EAGI" [static]

Definition at line 83 of file res_agi.c.

char* esynopsis = "Executes an EAGI compliant application" [static]

Definition at line 89 of file res_agi.c.

char no_debug_usage[] [static]

Initial value:

 
"Usage: agi debug off\n"
"       Disables dumping of AGI transactions for debugging purposes\n"

Definition at line 1362 of file res_agi.c.

char showagi_help[] [static]

Initial value:

"Usage: agi show [topic]\n"
"       When called with a topic as an argument, displays usage\n"
"       information on the given command.  If called without a\n"
"       topic, it provides a list of AGI commands.\n"

Definition at line 2242 of file res_agi.c.

char* synopsis = "Executes an AGI compliant application" [static]

Definition at line 87 of file res_agi.c.

char usage_answer[] [static]

Initial value:

 
" Usage: ANSWER\n"
"  Answers channel if not already in answer state. Returns -1 on\n"
" channel failure, or 0 if successful.\n"

Definition at line 1491 of file res_agi.c.

char usage_autohangup[] [static]

Initial value:

" Usage: SET AUTOHANGUP <time>\n"
"  Cause the channel to automatically hangup at <time> seconds in the\n"
" future.  Of course it can be hungup before then as well. Setting to 0 will\n"
" cause the autohangup feature to be disabled on this channel.\n"

Definition at line 1646 of file res_agi.c.

char usage_channelstatus[] [static]

Definition at line 1463 of file res_agi.c.

char usage_controlstreamfile[] [static]

Definition at line 1547 of file res_agi.c.

char usage_dbdel[] [static]

Initial value:

" Usage: DATABASE DEL <family> <key>\n"
"  Deletes an entry in the Asterisk database for a\n"
" given family and key.\n"
" Returns 1 if successful, 0 otherwise.\n"

Definition at line 1429 of file res_agi.c.

char usage_dbdeltree[] [static]

Initial value:

" Usage: DATABASE DELTREE <family> [keytree]\n"
"  Deletes a family or specific keytree within a family\n"
" in the Asterisk database.\n"
" Returns 1 if successful, 0 otherwise.\n"

Definition at line 1435 of file res_agi.c.

char usage_dbget[] [static]

Definition at line 1421 of file res_agi.c.

char usage_dbput[] [static]

Initial value:

" Usage: DATABASE PUT <family> <key> <value>\n"
"  Adds or updates an entry in the Asterisk database for a\n"
" given family, key, and value.\n"
" Returns 1 if successful, 0 otherwise.\n"

Definition at line 1415 of file res_agi.c.

char usage_exec[] [static]

Initial value:

" Usage: EXEC <application> <options>\n"
"  Executes <application> with given <options>.\n"
" Returns whatever the application returns, or -2 on failure to find application\n"

Definition at line 1481 of file res_agi.c.

char usage_getdata[] [static]

Initial value:

" Usage: GET DATA <file to be streamed> [timeout] [max digits]\n"
"  Stream the given file, and recieve DTMF data. Returns the digits received\n"
"from the channel at the other end.\n"

Definition at line 1616 of file res_agi.c.

char usage_getoption[] [static]

Initial value:

 
" Usage: GET OPTION <filename> <escape_digits> [timeout]\n"
"  Behaves similar to STREAM FILE but used with a timeout option.\n"

Definition at line 1557 of file res_agi.c.

char usage_getvariable[] [static]

Initial value:

" Usage: GET VARIABLE <variablename>\n"
"  Returns 0 if <variablename> is not set.  Returns 1 if <variablename>\n"
" is set and returns the variable in parentheses.\n"
" example return code: 200 result=1 (testvariable)\n"

Definition at line 1447 of file res_agi.c.

char usage_getvariablefull[] [static]

Definition at line 1453 of file res_agi.c.

char usage_hangup[] [static]

Initial value:

" Usage: HANGUP [<channelname>]\n"
"  Hangs up the specified channel.\n"
" If no channel name is given, hangs up the current channel\n"

Definition at line 1486 of file res_agi.c.

char usage_noop[] [static]

Initial value:

" Usage: NoOp\n"
"  Does nothing.\n"

Definition at line 1652 of file res_agi.c.

char usage_recordfile[] [static]

Definition at line 1634 of file res_agi.c.

char usage_recvchar[] [static]

Definition at line 1511 of file res_agi.c.

char usage_recvtext[] [static]

Initial value:

" Usage: RECEIVE TEXT <timeout>\n"
"  Receives a string of text on a channel. Specify timeout to be the\n"
" maximum time to wait for input in milliseconds, or 0 for infinite. Most channels\n"
" do not support the reception of text. Returns -1 for failure or 1 for success, and the string in parentheses.\n"

Definition at line 1519 of file res_agi.c.

char usage_sayalpha[] [static]

Definition at line 1575 of file res_agi.c.

char usage_saydate[] [static]

Definition at line 1582 of file res_agi.c.

char usage_saydatetime[] [static]

Definition at line 1598 of file res_agi.c.

char usage_saydigits[] [static]

Definition at line 1568 of file res_agi.c.

char usage_saynumber[] [static]

Definition at line 1561 of file res_agi.c.

char usage_sayphonetic[] [static]

Definition at line 1609 of file res_agi.c.

char usage_saytime[] [static]

Definition at line 1590 of file res_agi.c.

char usage_sendimage[] [static]

Definition at line 1530 of file res_agi.c.

char usage_sendtext[] [static]

Definition at line 1503 of file res_agi.c.

char usage_setcallerid[] [static]

Initial value:

" Usage: SET CALLERID <number>\n"
"  Changes the callerid of the current channel.\n"

Definition at line 1477 of file res_agi.c.

char usage_setcontext[] [static]

Initial value:

" Usage: SET CONTEXT <desired context>\n"
"  Sets the context for continuation upon exiting the application.\n"

Definition at line 1621 of file res_agi.c.

char usage_setextension[] [static]

Initial value:

" Usage: SET EXTENSION <new extension>\n"
"  Changes the extension for continuation upon exiting the application.\n"

Definition at line 1625 of file res_agi.c.

char usage_setmusic[] [static]

Initial value:

" Usage: SET MUSIC ON <on|off> <class>\n"
"  Enables/Disables the music on hold generator.  If <class> is\n"
" not specified, then the default music on hold class will be used.\n"
" Always returns 0.\n"

Definition at line 1409 of file res_agi.c.

char usage_setpriority[] [static]

Initial value:

" Usage: SET PRIORITY <priority>\n"
"  Changes the priority for continuation upon exiting the application.\n"
" The priority must be a valid priority or label.\n"

Definition at line 1629 of file res_agi.c.

char usage_setvariable[] [static]

Initial value:

" Usage: SET VARIABLE <variablename> <value>\n"

Definition at line 1460 of file res_agi.c.

char usage_streamfile[] [static]

Definition at line 1537 of file res_agi.c.

char usage_tddmode[] [static]

Initial value:

" Usage: TDD MODE <on|off>\n"
"  Enable/Disable TDD transmission/reception on a channel. Returns 1 if\n"
" successful, or 0 if channel is not TDD-capable.\n"

Definition at line 1525 of file res_agi.c.

char usage_verbose[] [static]

Initial value:

" Usage: VERBOSE <message> <level>\n"
"  Sends <message> to the console via verbose message system.\n"
" <level> is the the verbose level (1-4)\n"
" Always returns 1.\n"

Definition at line 1441 of file res_agi.c.

char usage_waitfordigit[] [static]

Definition at line 1496 of file res_agi.c.

char* xapp = "XAGI" [static]

Definition at line 81 of file res_agi.c.

char* xsynopsis = "Executes an XAGI compliant application" [static]

Definition at line 88 of file res_agi.c.


Generated on Mon Jul 14 17:25:23 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1