Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:44 2007

Asterisk developer's documentation :: Codename Pineapple


res_agi.c File Reference


Detailed Description

AGI - the Asterisk Gateway Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file res_agi.c.

#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_PORT   4573
#define fdprintf   agi_debug_cli
#define MAX_AGI_CONNECT   2000
#define MAX_ARGS   128
#define MAX_COMMANDS   128
#define RETRY   3
#define TONE_BLOCK_SIZE   200

Enumerations

enum  agi_result { AGI_RESULT_SUCCESS, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP }

Functions

static void 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[])
int ast_agi_register (agi_command *agi)
void ast_agi_unregister (agi_command *agi)
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Asterisk Gateway Interface (AGI)")
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 *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, int argc, char *argv[])
static void setup_env (struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[])
static int unload_module (void)

Variables

static int agidebug = 0
static char * app = "AGI"
static struct ast_cli_entry cli_agi []
static agi_command commands [MAX_COMMANDS]
static char * deadapp = "DeadAGI"
static char * deadsynopsis = "Executes AGI on a hungup channel"
static const char debug_usage []
static char * descrip
static char dumpagihtml_help []
static char * eapp = "EAGI"
static char * esynopsis = "Executes an EAGI compliant application"
static const 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 []


Define Documentation

#define AGI_PORT   4573
 

Definition at line 110 of file res_agi.c.

Referenced by launch_netscript().

#define fdprintf   agi_debug_cli
 

Definition at line 72 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 108 of file res_agi.c.

Referenced by launch_netscript().

#define MAX_ARGS   128
 

Definition at line 68 of file res_agi.c.

Referenced by agi_exec_full(), agi_handle_command(), and parse_args().

#define MAX_COMMANDS   128
 

Definition at line 69 of file res_agi.c.

Referenced by ast_agi_register(), and ast_agi_unregister().

#define RETRY   3
 

Definition at line 1833 of file res_agi.c.

Referenced by run_agi().

#define TONE_BLOCK_SIZE   200
 

Definition at line 105 of file res_agi.c.


Enumeration Type Documentation

enum agi_result
 

Enumerator:
AGI_RESULT_SUCCESS 
AGI_RESULT_FAILURE 
AGI_RESULT_HANGUP 

Definition at line 112 of file res_agi.c.

00112                 {
00113    AGI_RESULT_SUCCESS,
00114    AGI_RESULT_FAILURE,
00115    AGI_RESULT_HANGUP
00116 };


Function Documentation

static void agi_debug_cli int  fd,
char *  fmt,
  ...
[static]
 

Definition at line 118 of file res_agi.c.

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

00119 {
00120    char *stuff;
00121    int res = 0;
00122 
00123    va_list ap;
00124    va_start(ap, fmt);
00125    res = vasprintf(&stuff, fmt, ap);
00126    va_end(ap);
00127    if (res == -1) {
00128       ast_log(LOG_ERROR, "Out of memory\n");
00129    } else {
00130       if (agidebug)
00131          ast_verbose("AGI Tx >> %s\n", stuff);
00132       ast_carefulwrite(fd, stuff, strlen(stuff), 100);
00133       free(stuff);
00134    }
00135 }

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

Definition at line 1329 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01330 {
01331    if (argc != 2)
01332       return RESULT_SHOWUSAGE;
01333    agidebug = 1;
01334    ast_cli(fd, "AGI Debugging Enabled\n");
01335    return RESULT_SUCCESS;
01336 }

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

Definition at line 2066 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().

02067 {
02068    if (chan->_softhangup)
02069       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02070    return agi_exec_full(chan, data, 0, 0);
02071 }

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

Definition at line 1998 of file res_agi.c.

References ast_channel::_state, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, 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(), and eagi_exec().

01999 {
02000    enum agi_result res;
02001    struct ast_module_user *u;
02002    char *argv[MAX_ARGS];
02003    char buf[2048]="";
02004    char *tmp = buf;
02005    int argc = 0;
02006    int fds[2];
02007    int efd = -1;
02008    int pid;
02009         char *stringp;
02010    AGI agi;
02011 
02012    if (ast_strlen_zero(data)) {
02013       ast_log(LOG_WARNING, "AGI requires an argument (script)\n");
02014       return -1;
02015    }
02016    ast_copy_string(buf, data, sizeof(buf));
02017 
02018    memset(&agi, 0, sizeof(agi));
02019         while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1)
02020       argv[argc++] = stringp;
02021    argv[argc] = NULL;
02022 
02023    u = ast_module_user_add(chan);
02024 #if 0
02025     /* Answer if need be */
02026         if (chan->_state != AST_STATE_UP) {
02027       if (ast_answer(chan)) {
02028          LOCAL_USER_REMOVE(u);
02029          return -1;
02030       }
02031    }
02032 #endif
02033    res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid);
02034    if (res == AGI_RESULT_SUCCESS) {
02035       int status = 0;
02036       agi.fd = fds[1];
02037       agi.ctrl = fds[0];
02038       agi.audio = efd;
02039       res = run_agi(chan, argv[0], &agi, pid, &status, dead, argc, argv);
02040       /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */
02041       if (res == AGI_RESULT_SUCCESS && status)
02042          res = AGI_RESULT_FAILURE;
02043       if (fds[1] != fds[0])
02044          close(fds[1]);
02045       if (efd > -1)
02046          close(efd);
02047       ast_unreplace_sigchld();
02048    }
02049    ast_module_user_remove(u);
02050 
02051    switch (res) {
02052    case AGI_RESULT_SUCCESS:
02053       pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS");
02054       break;
02055    case AGI_RESULT_FAILURE:
02056       pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE");
02057       break;
02058    case AGI_RESULT_HANGUP:
02059       pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP");
02060       return -1;
02061    }
02062 
02063    return 0;
02064 }

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

Definition at line 1802 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().

01803 {
01804    char *argv[MAX_ARGS];
01805    int argc = MAX_ARGS;
01806    int res;
01807    agi_command *c;
01808 
01809    parse_args(buf, &argc, argv);
01810    c = find_command(argv, 0);
01811    if (c) {
01812       res = c->handler(chan, agi, argc, argv);
01813       switch(res) {
01814       case RESULT_SHOWUSAGE:
01815          fdprintf(agi->fd, "520-Invalid command syntax.  Proper usage follows:\n");
01816          fdprintf(agi->fd, c->usage);
01817          fdprintf(agi->fd, "520 End of proper usage.\n");
01818          break;
01819       case AST_PBX_KEEPALIVE:
01820          /* We've been asked to keep alive, so do so */
01821          return AST_PBX_KEEPALIVE;
01822          break;
01823       case RESULT_FAILURE:
01824          /* They've already given the failure.  We've been hung up on so handle this
01825             appropriately */
01826          return -1;
01827       }
01828    } else {
01829       fdprintf(agi->fd, "510 Invalid or unknown command\n");
01830    }
01831    return 0;
01832 }

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

Definition at line 1338 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01339 {
01340    if (argc != 2)
01341       return RESULT_SHOWUSAGE;
01342    agidebug = 0;
01343    ast_cli(fd, "AGI Debugging Disabled\n");
01344    return RESULT_SUCCESS;
01345 }

int ast_agi_register agi_command agi  ) 
 

Definition at line 1673 of file res_agi.c.

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

01674 {
01675    int x;
01676    for (x=0; x<MAX_COMMANDS - 1; x++) {
01677       if (commands[x].cmda[0] == agi->cmda[0]) {
01678          ast_log(LOG_WARNING, "Command already registered!\n");
01679          return -1;
01680       }
01681    }
01682    for (x=0; x<MAX_COMMANDS - 1; x++) {
01683       if (!commands[x].cmda[0]) {
01684          commands[x] = *agi;
01685          return 0;
01686       }
01687    }
01688    ast_log(LOG_WARNING, "No more room for new commands!\n");
01689    return -1;
01690 }

void ast_agi_unregister agi_command agi  ) 
 

Definition at line 1692 of file res_agi.c.

References agi_command::cmda, commands, and MAX_COMMANDS.

01693 {
01694    int x;
01695    for (x=0; x<MAX_COMMANDS - 1; x++) {
01696       if (commands[x].cmda[0] == agi->cmda[0]) {
01697          memset(&commands[x], 0, sizeof(agi_command));
01698       }
01699    }
01700 }

AST_MODULE_INFO_STANDARD ASTERISK_GPL_KEY  ,
"Asterisk Gateway Interface (AGI)" 
 

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

Definition at line 2094 of file res_agi.c.

References agi_exec_full(), and ast_module_user::chan.

Referenced by load_module().

02095 {
02096    return agi_exec_full(chan, data, 0, 1);
02097 }

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

Definition at line 2073 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().

02074 {
02075    int readformat;
02076    int res;
02077 
02078    if (chan->_softhangup)
02079       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02080    readformat = chan->readformat;
02081    if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
02082       ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
02083       return -1;
02084    }
02085    res = agi_exec_full(chan, data, 1, 0);
02086    if (!res) {
02087       if (ast_set_read_format(chan, readformat)) {
02088          ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
02089       }
02090    }
02091    return res;
02092 }

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

Definition at line 1702 of file res_agi.c.

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

01703 {
01704    int x;
01705    int y;
01706    int match;
01707 
01708    for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) {
01709       if (!commands[x].cmda[0])
01710          break;
01711       /* start optimistic */
01712       match = 1;
01713       for (y=0; match && cmds[y]; y++) {
01714          /* If there are no more words in the command (and we're looking for
01715             an exact match) or there is a difference between the two words,
01716             then this is not a match */
01717          if (!commands[x].cmda[y] && !exact)
01718             break;
01719          /* don't segfault if the next part of a command doesn't exist */
01720          if (!commands[x].cmda[y])
01721             return NULL;
01722          if (strcasecmp(commands[x].cmda[y], cmds[y]))
01723             match = 0;
01724       }
01725       /* If more words are needed to complete the command then this is not
01726          a candidate (unless we're looking for a really inexact answer  */
01727       if ((exact > -1) && commands[x].cmda[y])
01728          match = 0;
01729       if (match)
01730          return &commands[x];
01731    }
01732    return NULL;
01733 }

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

Definition at line 1944 of file res_agi.c.

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

01945 {
01946    struct agi_command *e;
01947    char fullcmd[80];
01948    int x;
01949    FILE *htmlfile;
01950 
01951    if ((argc < 3))
01952       return RESULT_SHOWUSAGE;
01953 
01954    if (!(htmlfile = fopen(argv[2], "wt"))) {
01955       ast_cli(fd, "Could not create file '%s'\n", argv[2]);
01956       return RESULT_SHOWUSAGE;
01957    }
01958 
01959    fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n");
01960    fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n");
01961 
01962 
01963    fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n");
01964 
01965    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
01966       char *stringp, *tempstr;
01967 
01968       e = &commands[x]; 
01969       if (!e->cmda[0])  /* end ? */
01970          break;
01971       /* Hide commands that start with '_' */
01972       if ((e->cmda[0])[0] == '_')
01973          continue;
01974       ast_join(fullcmd, sizeof(fullcmd), e->cmda);
01975 
01976       fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n");
01977       fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TD></TR>\n", fullcmd,e->summary);
01978 
01979       stringp=e->usage;
01980       tempstr = strsep(&stringp, "\n");
01981 
01982       fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr);
01983       
01984       fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n");
01985       while ((tempstr = strsep(&stringp, "\n")) != NULL)
01986          fprintf(htmlfile, "%s<BR>\n",tempstr);
01987       fprintf(htmlfile, "</TD></TR>\n");
01988       fprintf(htmlfile, "</TABLE></TD></TR>\n\n");
01989 
01990    }
01991 
01992    fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n");
01993    fclose(htmlfile);
01994    ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]);
01995    return RESULT_SUCCESS;
01996 }

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

Definition at line 408 of file res_agi.c.

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

00409 {
00410    int res;
00411    res = 0;
00412    if (chan->_state != AST_STATE_UP) {
00413       /* Answer the chan */
00414       res = ast_answer(chan);
00415    }
00416    fdprintf(agi->fd, "200 result=%d\n", res);
00417    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00418 }

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

Definition at line 1067 of file res_agi.c.

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

01068 {
01069    int timeout;
01070 
01071    if (argc != 3)
01072       return RESULT_SHOWUSAGE;
01073    if (sscanf(argv[2], "%d", &timeout) != 1)
01074       return RESULT_SHOWUSAGE;
01075    if (timeout < 0)
01076       timeout = 0;
01077    if (timeout)
01078       chan->whentohangup = time(NULL) + timeout;
01079    else
01080       chan->whentohangup = 0;
01081    fdprintf(agi->fd, "200 result=0\n");
01082    return RESULT_SUCCESS;
01083 }

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

Definition at line 1156 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.

01157 {
01158    struct ast_channel *c;
01159    if (argc == 2) {
01160       /* no argument: supply info on the current channel */
01161       fdprintf(agi->fd, "200 result=%d\n", chan->_state);
01162       return RESULT_SUCCESS;
01163    } else if (argc == 3) {
01164       /* one argument: look for info on the specified channel */
01165       c = ast_get_channel_by_name_locked(argv[2]);
01166       if (c) {
01167          fdprintf(agi->fd, "200 result=%d\n", c->_state);
01168          ast_channel_unlock(c);
01169          return RESULT_SUCCESS;
01170       }
01171       /* if we get this far no channel name matched the argument given */
01172       fdprintf(agi->fd, "200 result=-1\n");
01173       return RESULT_SUCCESS;
01174    } else {
01175       return RESULT_SHOWUSAGE;
01176    }
01177 }

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

Definition at line 519 of file res_agi.c.

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

00520 {
00521    int res = 0;
00522    int skipms = 3000;
00523    char *fwd = NULL;
00524    char *rev = NULL;
00525    char *pause = NULL;
00526    char *stop = NULL;
00527 
00528    if (argc < 5 || argc > 9)
00529       return RESULT_SHOWUSAGE;
00530 
00531    if (!ast_strlen_zero(argv[4]))
00532       stop = argv[4];
00533    else
00534       stop = NULL;
00535    
00536    if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1))
00537       return RESULT_SHOWUSAGE;
00538 
00539    if (argc > 6 && !ast_strlen_zero(argv[6]))
00540       fwd = argv[6];
00541    else
00542       fwd = "#";
00543 
00544    if (argc > 7 && !ast_strlen_zero(argv[7]))
00545       rev = argv[7];
00546    else
00547       rev = "*";
00548    
00549    if (argc > 8 && !ast_strlen_zero(argv[8]))
00550       pause = argv[8];
00551    else
00552       pause = NULL;
00553    
00554    res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms);
00555    
00556    fdprintf(agi->fd, "200 result=%d\n", res);
00557 
00558    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00559 }

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

Definition at line 1296 of file res_agi.c.

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

01297 {
01298    int res;
01299 
01300    if (argc != 4)
01301       return RESULT_SHOWUSAGE;
01302    res = ast_db_del(argv[2], argv[3]);
01303    fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
01304    return RESULT_SUCCESS;
01305 }

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

Definition at line 1307 of file res_agi.c.

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

01308 {
01309    int res;
01310    if ((argc < 3) || (argc > 4))
01311       return RESULT_SHOWUSAGE;
01312    if (argc == 4)
01313       res = ast_db_deltree(argv[2], argv[3]);
01314    else
01315       res = ast_db_deltree(argv[2], NULL);
01316 
01317    fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
01318    return RESULT_SUCCESS;
01319 }

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

Definition at line 1269 of file res_agi.c.

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

01270 {
01271    int res;
01272    char tmp[256];
01273 
01274    if (argc != 4)
01275       return RESULT_SHOWUSAGE;
01276    res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
01277    if (res) 
01278       fdprintf(agi->fd, "200 result=0\n");
01279    else
01280       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01281 
01282    return RESULT_SUCCESS;
01283 }

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

Definition at line 1285 of file res_agi.c.

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

01286 {
01287    int res;
01288 
01289    if (argc != 5)
01290       return RESULT_SHOWUSAGE;
01291    res = ast_db_put(argv[2], argv[3], argv[4]);
01292    fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1');
01293    return RESULT_SUCCESS;
01294 }

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

Definition at line 1111 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.

01112 {
01113    int res;
01114    struct ast_app *app;
01115 
01116    if (argc < 2)
01117       return RESULT_SHOWUSAGE;
01118 
01119    if (option_verbose > 2)
01120       ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]);
01121 
01122    app = pbx_findapp(argv[1]);
01123 
01124    if (app) {
01125       res = pbx_exec(chan, app, argv[2]);
01126    } else {
01127       ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
01128       res = -2;
01129    }
01130    fdprintf(agi->fd, "200 result=%d\n", res);
01131 
01132    return res;
01133 }

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

Definition at line 826 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.

00827 {
00828    int res;
00829    char data[1024];
00830    int max;
00831    int timeout;
00832 
00833    if (argc < 3)
00834       return RESULT_SHOWUSAGE;
00835    if (argc >= 4)
00836       timeout = atoi(argv[3]); 
00837    else
00838       timeout = 0;
00839    if (argc >= 5) 
00840       max = atoi(argv[4]); 
00841    else
00842       max = 1024;
00843    res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
00844    if (res == 2)        /* New command */
00845       return RESULT_SUCCESS;
00846    else if (res == 1)
00847       fdprintf(agi->fd, "200 result=%s (timeout)\n", data);
00848    else if (res < 0 )
00849       fdprintf(agi->fd, "200 result=-1\n");
00850    else
00851       fdprintf(agi->fd, "200 result=%s\n", data);
00852    return RESULT_SUCCESS;
00853 }

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

Definition at line 621 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_debug, option_verbose, ast_channel::pbx, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.

00622 {
00623    int res;
00624    int vres;   
00625    struct ast_filestream *fs;
00626    struct ast_filestream *vfs;
00627    long sample_offset = 0;
00628    long max_length;
00629    int timeout = 0;
00630    char *edigits = "";
00631 
00632    if ( argc < 4 || argc > 5 )
00633       return RESULT_SHOWUSAGE;
00634 
00635    if ( argv[3] ) 
00636       edigits = argv[3];
00637 
00638    if ( argc == 5 )
00639       timeout = atoi(argv[4]);
00640    else if (chan->pbx->dtimeout) {
00641       /* by default dtimeout is set to 5sec */
00642       timeout = chan->pbx->dtimeout * 1000; /* in msec */
00643    }
00644 
00645    fs = ast_openstream(chan, argv[2], chan->language);
00646    if (!fs) {
00647       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
00648       ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
00649       return RESULT_SUCCESS;
00650    }
00651    vfs = ast_openvstream(chan, argv[2], chan->language);
00652    if (vfs && option_debug)
00653       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00654    
00655    if (option_verbose > 2)
00656       ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
00657 
00658    ast_seekstream(fs, 0, SEEK_END);
00659    max_length = ast_tellstream(fs);
00660    ast_seekstream(fs, sample_offset, SEEK_SET);
00661    res = ast_applystream(chan, fs);
00662    if (vfs)
00663       vres = ast_applystream(chan, vfs);
00664    res = ast_playstream(fs);
00665    if (vfs)
00666       vres = ast_playstream(vfs);
00667    if (res) {
00668       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00669       if (res >= 0)
00670          return RESULT_SHOWUSAGE;
00671       else
00672          return RESULT_FAILURE;
00673    }
00674    res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
00675    /* this is to check for if ast_waitstream closed the stream, we probably are at
00676     * the end of the stream, return that amount, else check for the amount */
00677    sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
00678    ast_stopstream(chan);
00679    if (res == 1) {
00680       /* Stop this command, don't print a result line, as there is a new command */
00681       return RESULT_SUCCESS;
00682    }
00683 
00684    /* If the user didnt press a key, wait for digitTimeout*/
00685    if (res == 0 ) {
00686       res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
00687       /* Make sure the new result is in the escape digits of the GET OPTION */
00688       if ( !strchr(edigits,res) )
00689          res=0;
00690    }
00691 
00692         fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00693    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00694 }

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

Definition at line 1188 of file res_agi.c.

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

01189 {
01190    char *ret;
01191    char tempstr[1024];
01192 
01193    if (argc != 3)
01194       return RESULT_SHOWUSAGE;
01195 
01196    /* check if we want to execute an ast_custom_function */
01197    if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
01198       ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
01199    } else {
01200       pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
01201    }
01202 
01203    if (ret)
01204       fdprintf(agi->fd, "200 result=1 (%s)\n", ret);
01205    else
01206       fdprintf(agi->fd, "200 result=0\n");
01207 
01208    return RESULT_SUCCESS;
01209 }

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

Definition at line 1211 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.

01212 {
01213    char tmp[4096] = "";
01214    struct ast_channel *chan2=NULL;
01215 
01216    if ((argc != 4) && (argc != 5))
01217       return RESULT_SHOWUSAGE;
01218    if (argc == 5) {
01219       chan2 = ast_get_channel_by_name_locked(argv[4]);
01220    } else {
01221       chan2 = chan;
01222    }
01223    if (chan) { /* XXX isn't this chan2 ? */
01224       pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1);
01225       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01226    } else {
01227       fdprintf(agi->fd, "200 result=0\n");
01228    }
01229    if (chan2 && (chan2 != chan))
01230       ast_channel_unlock(chan2);
01231    return RESULT_SUCCESS;
01232 }

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

Definition at line 1085 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.

01086 {
01087    struct ast_channel *c;
01088    if (argc == 1) {
01089       /* no argument: hangup the current channel */
01090       ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
01091       fdprintf(agi->fd, "200 result=1\n");
01092       return RESULT_SUCCESS;
01093    } else if (argc == 2) {
01094       /* one argument: look for info on the specified channel */
01095       c = ast_get_channel_by_name_locked(argv[1]);
01096       if (c) {
01097          /* we have a matching channel */
01098          ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
01099          fdprintf(agi->fd, "200 result=1\n");
01100          ast_channel_unlock(c);
01101          return RESULT_SUCCESS;
01102       }
01103       /* if we get this far no channel name matched the argument given */
01104       fdprintf(agi->fd, "200 result=-1\n");
01105       return RESULT_SUCCESS;
01106    } else {
01107       return RESULT_SHOWUSAGE;
01108    }
01109 }

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

Definition at line 1347 of file res_agi.c.

References agi_state::fd, fdprintf, and RESULT_SUCCESS.

01348 {
01349    fdprintf(agi->fd, "200 result=0\n");
01350    return RESULT_SUCCESS;
01351 }

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

Definition at line 890 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_FILE_MODE, 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(), ast_dsp::f, agi_state::fd, fdprintf, ast_frame::frametype, LOG_WARNING, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, ast_frame::subclass, and ast_dsp::totalsilence.

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

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

Definition at line 450 of file res_agi.c.

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

00451 {
00452    int res;
00453    if (argc != 3)
00454       return RESULT_SHOWUSAGE;
00455    res = ast_recvchar(chan,atoi(argv[2]));
00456    if (res == 0) {
00457       fdprintf(agi->fd, "200 result=%d (timeout)\n", res);
00458       return RESULT_SUCCESS;
00459    }
00460    if (res > 0) {
00461       fdprintf(agi->fd, "200 result=%d\n", res);
00462       return RESULT_SUCCESS;
00463    }
00464    else {
00465       fdprintf(agi->fd, "200 result=%d (hangup)\n", res);
00466       return RESULT_FAILURE;
00467    }
00468 }

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

Definition at line 470 of file res_agi.c.

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

00471 {
00472    char *buf;
00473    
00474    if (argc != 3)
00475       return RESULT_SHOWUSAGE;
00476    buf = ast_recvtext(chan,atoi(argv[2]));
00477    if (buf) {
00478       fdprintf(agi->fd, "200 result=1 (%s)\n", buf);
00479       free(buf);
00480    } else { 
00481       fdprintf(agi->fd, "200 result=-1\n");
00482    }
00483    return RESULT_SUCCESS;
00484 }

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

Definition at line 734 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.

00735 {
00736    int res;
00737 
00738    if (argc != 4)
00739       return RESULT_SHOWUSAGE;
00740 
00741    res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00742    if (res == 1) /* New command */
00743       return RESULT_SUCCESS;
00744    fdprintf(agi->fd, "200 result=%d\n", res);
00745    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00746 }

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

Definition at line 748 of file res_agi.c.

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

00749 {
00750    int res;
00751    int num;
00752    if (argc != 4)
00753       return RESULT_SHOWUSAGE;
00754    if (sscanf(argv[2], "%d", &num) != 1)
00755       return RESULT_SHOWUSAGE;
00756    res = ast_say_date(chan, num, argv[3], chan->language);
00757    if (res == 1)
00758       return RESULT_SUCCESS;
00759    fdprintf(agi->fd, "200 result=%d\n", res);
00760    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00761 }

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

Definition at line 778 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.

00779 {
00780    int res=0;
00781    time_t unixtime;
00782    char *format, *zone=NULL;
00783    
00784    if (argc < 4)
00785       return RESULT_SHOWUSAGE;
00786 
00787    if (argc > 4) {
00788       format = argv[4];
00789    } else {
00790       /* XXX this doesn't belong here, but in the 'say' module */
00791       if (!strcasecmp(chan->language, "de")) {
00792          format = "A dBY HMS";
00793       } else {
00794          format = "ABdY 'digits/at' IMp"; 
00795       }
00796    }
00797 
00798    if (argc > 5 && !ast_strlen_zero(argv[5]))
00799       zone = argv[5];
00800 
00801    if (ast_get_time_t(argv[2], &unixtime, 0, NULL))
00802       return RESULT_SHOWUSAGE;
00803 
00804    res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone);
00805    if (res == 1)
00806       return RESULT_SUCCESS;
00807 
00808    fdprintf(agi->fd, "200 result=%d\n", res);
00809    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00810 }

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

Definition at line 717 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.

00718 {
00719    int res;
00720    int num;
00721 
00722    if (argc != 4)
00723       return RESULT_SHOWUSAGE;
00724    if (sscanf(argv[2], "%d", &num) != 1)
00725       return RESULT_SHOWUSAGE;
00726 
00727    res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00728    if (res == 1) /* New command */
00729       return RESULT_SUCCESS;
00730    fdprintf(agi->fd, "200 result=%d\n", res);
00731    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00732 }

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

Definition at line 702 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.

00703 {
00704    int res;
00705    int num;
00706    if (argc != 4)
00707       return RESULT_SHOWUSAGE;
00708    if (sscanf(argv[2], "%d", &num) != 1)
00709       return RESULT_SHOWUSAGE;
00710    res = ast_say_number_full(chan, num, argv[3], chan->language, NULL, agi->audio, agi->ctrl);
00711    if (res == 1)
00712       return RESULT_SUCCESS;
00713    fdprintf(agi->fd, "200 result=%d\n", res);
00714    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00715 }

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

Definition at line 812 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.

00813 {
00814    int res;
00815 
00816    if (argc != 4)
00817       return RESULT_SHOWUSAGE;
00818 
00819    res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00820    if (res == 1) /* New command */
00821       return RESULT_SUCCESS;
00822    fdprintf(agi->fd, "200 result=%d\n", res);
00823    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00824 }

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

Definition at line 763 of file res_agi.c.

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

00764 {
00765    int res;
00766    int num;
00767    if (argc != 4)
00768       return RESULT_SHOWUSAGE;
00769    if (sscanf(argv[2], "%d", &num) != 1)
00770       return RESULT_SHOWUSAGE;
00771    res = ast_say_time(chan, num, argv[3], chan->language);
00772    if (res == 1)
00773       return RESULT_SUCCESS;
00774    fdprintf(agi->fd, "200 result=%d\n", res);
00775    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00776 }

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

Definition at line 507 of file res_agi.c.

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

00508 {
00509    int res;
00510    if (argc != 3)
00511       return RESULT_SHOWUSAGE;
00512    res = ast_send_image(chan, argv[2]);
00513    if (!ast_check_hangup(chan))
00514       res = 0;
00515    fdprintf(agi->fd, "200 result=%d\n", res);
00516    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00517 }

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

Definition at line 433 of file res_agi.c.

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

00434 {
00435    int res;
00436    if (argc != 3)
00437       return RESULT_SHOWUSAGE;
00438    /* At the moment, the parser (perhaps broken) returns with
00439       the last argument PLUS the newline at the end of the input
00440       buffer. This probably needs to be fixed, but I wont do that
00441       because other stuff may break as a result. The right way
00442       would probably be to strip off the trailing newline before
00443       parsing, then here, add a newline at the end of the string
00444       before sending it to ast_sendtext --DUDE */
00445    res = ast_sendtext(chan, argv[2]);
00446    fdprintf(agi->fd, "200 result=%d\n", res);
00447    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00448 }

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

Definition at line 1135 of file res_agi.c.

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

01136 {
01137    char tmp[256]="";
01138    char *l = NULL, *n = NULL;
01139 
01140    if (argv[2]) {
01141       ast_copy_string(tmp, argv[2], sizeof(tmp));
01142       ast_callerid_parse(tmp, &n, &l);
01143       if (l)
01144          ast_shrink_phone_number(l);
01145       else
01146          l = "";
01147       if (!n)
01148          n = "";
01149       ast_set_callerid(chan, l, n, NULL);
01150    }
01151 
01152    fdprintf(agi->fd, "200 result=1\n");
01153    return RESULT_SUCCESS;
01154 }

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

Definition at line 855 of file res_agi.c.

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

00856 {
00857 
00858    if (argc != 3)
00859       return RESULT_SHOWUSAGE;
00860    ast_copy_string(chan->context, argv[2], sizeof(chan->context));
00861    fdprintf(agi->fd, "200 result=0\n");
00862    return RESULT_SUCCESS;
00863 }

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

Definition at line 865 of file res_agi.c.

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

00866 {
00867    if (argc != 3)
00868       return RESULT_SHOWUSAGE;
00869    ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
00870    fdprintf(agi->fd, "200 result=0\n");
00871    return RESULT_SUCCESS;
00872 }

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

Definition at line 1353 of file res_agi.c.

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

01354 {
01355    if (!strncasecmp(argv[2], "on", 2))
01356       ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
01357    else if (!strncasecmp(argv[2], "off", 3))
01358       ast_moh_stop(chan);
01359    fdprintf(agi->fd, "200 result=0\n");
01360    return RESULT_SUCCESS;
01361 }

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

Definition at line 874 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.

00875 {
00876    int pri;
00877    if (argc != 3)
00878       return RESULT_SHOWUSAGE;   
00879 
00880    if (sscanf(argv[2], "%d", &pri) != 1) {
00881       if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
00882          return RESULT_SHOWUSAGE;
00883    }
00884 
00885    ast_explicit_goto(chan, NULL, NULL, pri);
00886    fdprintf(agi->fd, "200 result=0\n");
00887    return RESULT_SUCCESS;
00888 }

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

Definition at line 1179 of file res_agi.c.

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

01180 {
01181    if (argv[3])
01182       pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
01183 
01184    fdprintf(agi->fd, "200 result=1\n");
01185    return RESULT_SUCCESS;
01186 }

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

Definition at line 1920 of file res_agi.c.

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

01921 {
01922    struct agi_command *e;
01923    char fullcmd[80];
01924    if ((argc < 2))
01925       return RESULT_SHOWUSAGE;
01926    if (argc > 2) {
01927       e = find_command(argv + 2, 1);
01928       if (e) 
01929          ast_cli(fd, e->usage);
01930       else {
01931          if (find_command(argv + 2, -1)) {
01932             return help_workhorse(fd, argv + 1);
01933          } else {
01934             ast_join(fullcmd, sizeof(fullcmd), argv+1);
01935             ast_cli(fd, "No such command '%s'.\n", fullcmd);
01936          }
01937       }
01938    } else {
01939       return help_workhorse(fd, NULL);
01940    }
01941    return RESULT_SUCCESS;
01942 }

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

Definition at line 561 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_debug, option_verbose, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.

00562 {
00563    int res;
00564    int vres;   
00565    struct ast_filestream *fs;
00566    struct ast_filestream *vfs;
00567    long sample_offset = 0;
00568    long max_length;
00569    char *edigits = "";
00570 
00571    if (argc < 4 || argc > 5)
00572       return RESULT_SHOWUSAGE;
00573 
00574    if (argv[3]) 
00575       edigits = argv[3];
00576 
00577    if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1))
00578       return RESULT_SHOWUSAGE;
00579    
00580    fs = ast_openstream(chan, argv[2], chan->language);   
00581    
00582    if (!fs) {
00583       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
00584       return RESULT_SUCCESS;
00585    }  
00586    vfs = ast_openvstream(chan, argv[2], chan->language);
00587    if (vfs && option_debug)
00588       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00589       
00590    if (option_verbose > 2)
00591       ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset);
00592 
00593    ast_seekstream(fs, 0, SEEK_END);
00594    max_length = ast_tellstream(fs);
00595    ast_seekstream(fs, sample_offset, SEEK_SET);
00596    res = ast_applystream(chan, fs);
00597    if (vfs)
00598       vres = ast_applystream(chan, vfs);
00599    res = ast_playstream(fs);
00600    if (vfs)
00601       vres = ast_playstream(vfs);
00602    
00603    if (res) {
00604       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00605       return (res >= 0) ? RESULT_SHOWUSAGE : RESULT_FAILURE;
00606    }
00607    res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
00608    /* this is to check for if ast_waitstream closed the stream, we probably are at
00609     * the end of the stream, return that amount, else check for the amount */
00610    sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
00611    ast_stopstream(chan);
00612    if (res == 1) {
00613       /* Stop this command, don't print a result line, as there is a new command */
00614       return RESULT_SUCCESS;
00615    }
00616    fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00617    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00618 }

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

Definition at line 486 of file res_agi.c.

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

00487 {
00488    int res,x;
00489    if (argc != 3)
00490       return RESULT_SHOWUSAGE;
00491    if (!strncasecmp(argv[2],"on",2)) 
00492       x = 1; 
00493    else 
00494       x = 0;
00495    if (!strncasecmp(argv[2],"mate",4)) 
00496       x = 2;
00497    if (!strncasecmp(argv[2],"tdd",3))
00498       x = 1;
00499    res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
00500    if (res != RESULT_SUCCESS)
00501       fdprintf(agi->fd, "200 result=0\n");
00502    else
00503       fdprintf(agi->fd, "200 result=1\n");
00504    return RESULT_SUCCESS;
00505 }

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

Definition at line 1234 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.

01235 {
01236    int level = 0;
01237    char *prefix;
01238 
01239    if (argc < 2)
01240       return RESULT_SHOWUSAGE;
01241 
01242    if (argv[2])
01243       sscanf(argv[2], "%d", &level);
01244 
01245    switch (level) {
01246       case 4:
01247          prefix = VERBOSE_PREFIX_4;
01248          break;
01249       case 3:
01250          prefix = VERBOSE_PREFIX_3;
01251          break;
01252       case 2:
01253          prefix = VERBOSE_PREFIX_2;
01254          break;
01255       case 1:
01256       default:
01257          prefix = VERBOSE_PREFIX_1;
01258          break;
01259    }
01260 
01261    if (level <= option_verbose)
01262       ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]);
01263    
01264    fdprintf(agi->fd, "200 result=1\n");
01265    
01266    return RESULT_SUCCESS;
01267 }

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

Definition at line 420 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.

00421 {
00422    int res;
00423    int to;
00424    if (argc != 4)
00425       return RESULT_SHOWUSAGE;
00426    if (sscanf(argv[3], "%d", &to) != 1)
00427       return RESULT_SHOWUSAGE;
00428    res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
00429    fdprintf(agi->fd, "200 result=%d\n", res);
00430    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00431 }

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

Definition at line 1650 of file res_agi.c.

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

Referenced by handle_showagi().

01651 {
01652    char fullcmd[80];
01653    char matchstr[80];
01654    int x;
01655    struct agi_command *e;
01656    if (match)
01657       ast_join(matchstr, sizeof(matchstr), match);
01658    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
01659       e = &commands[x]; 
01660       if (!e->cmda[0])
01661          break;
01662       /* Hide commands that start with '_' */
01663       if ((e->cmda[0])[0] == '_')
01664          continue;
01665       ast_join(fullcmd, sizeof(fullcmd), e->cmda);
01666       if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr)))
01667          continue;
01668       ast_cli(fd, "%20.20s   %s\n", fullcmd, e->summary);
01669    }
01670    return 0;
01671 }

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

Definition at line 139 of file res_agi.c.

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

Referenced by launch_script().

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

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

Definition at line 235 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(), launch_netscript(), LOG_WARNING, option_verbose, setenv(), and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

00236 {
00237    char tmp[256];
00238    int pid;
00239    int toast[2];
00240    int fromast[2];
00241    int audio[2];
00242    int x;
00243    int res;
00244    sigset_t signal_set, old_set;
00245    
00246    if (!strncasecmp(script, "agi://", 6))
00247       return launch_netscript(script, argv, fds, efd, opid);
00248    
00249    if (script[0] != '/') {
00250       snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script);
00251       script = tmp;
00252    }
00253    if (pipe(toast)) {
00254       ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
00255       return AGI_RESULT_FAILURE;
00256    }
00257    if (pipe(fromast)) {
00258       ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
00259       close(toast[0]);
00260       close(toast[1]);
00261       return AGI_RESULT_FAILURE;
00262    }
00263    if (efd) {
00264       if (pipe(audio)) {
00265          ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
00266          close(fromast[0]);
00267          close(fromast[1]);
00268          close(toast[0]);
00269          close(toast[1]);
00270          return AGI_RESULT_FAILURE;
00271       }
00272       res = fcntl(audio[1], F_GETFL);
00273       if (res > -1) 
00274          res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
00275       if (res < 0) {
00276          ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
00277          close(fromast[0]);
00278          close(fromast[1]);
00279          close(toast[0]);
00280          close(toast[1]);
00281          close(audio[0]);
00282          close(audio[1]);
00283          return AGI_RESULT_FAILURE;
00284       }
00285    }
00286 
00287    /* Block SIGHUP during the fork - prevents a race */
00288    sigfillset(&signal_set);
00289    pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
00290    pid = fork();
00291    if (pid < 0) {
00292       ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
00293       pthread_sigmask(SIG_SETMASK, &old_set, NULL);
00294       return AGI_RESULT_FAILURE;
00295    }
00296    if (!pid) {
00297       /* Pass paths to AGI via environmental variables */
00298       setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1);
00299       setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1);
00300       setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1);
00301       setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1);
00302       setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1);
00303       setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1);
00304       setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1);
00305       setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1);
00306       setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1);
00307       setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1);
00308       setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1);
00309 
00310       /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
00311       ast_set_priority(0);
00312 
00313       /* Redirect stdin and out, provide enhanced audio channel if desired */
00314       dup2(fromast[0], STDIN_FILENO);
00315       dup2(toast[1], STDOUT_FILENO);
00316       if (efd) {
00317          dup2(audio[0], STDERR_FILENO + 1);
00318       } else {
00319          close(STDERR_FILENO + 1);
00320       }
00321 
00322       /* Before we unblock our signals, return our trapped signals back to the defaults */
00323       signal(SIGHUP, SIG_DFL);
00324       signal(SIGCHLD, SIG_DFL);
00325       signal(SIGINT, SIG_DFL);
00326       signal(SIGURG, SIG_DFL);
00327       signal(SIGTERM, SIG_DFL);
00328       signal(SIGPIPE, SIG_DFL);
00329       signal(SIGXFSZ, SIG_DFL);
00330 
00331       /* unblock important signal handlers */
00332       if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
00333          ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
00334          _exit(1);
00335       }
00336 
00337       /* Close everything but stdin/out/error */
00338       for (x=STDERR_FILENO + 2;x<1024;x++) 
00339          close(x);
00340 
00341       /* Execute script */
00342       /* XXX argv should be deprecated in favor of passing agi_argX paramaters */
00343       execv(script, argv);
00344       /* Can't use ast_log since FD's are closed */
00345       fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno));
00346       fflush(stdout);
00347       _exit(1);
00348    }
00349    pthread_sigmask(SIG_SETMASK, &old_set, NULL);
00350    if (option_verbose > 2) 
00351       ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
00352    fds[0] = toast[0];
00353    fds[1] = fromast[1];
00354    if (efd) {
00355       *efd = audio[1];
00356    }
00357    /* close what we're not using in the parent */
00358    close(toast[1]);
00359    close(fromast[0]);
00360 
00361    if (efd)
00362       close(audio[0]);
00363 
00364    *opid = pid;
00365    return AGI_RESULT_SUCCESS;
00366 }

static int load_module void   )  [static]
 

Definition at line 2137 of file res_agi.c.

References agi_exec(), app, ast_cli_register_multiple(), ast_register_application(), cli_agi, deadagi_exec(), deadapp, deadsynopsis, descrip, eagi_exec(), eapp, esynopsis, and synopsis.

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

Definition at line 1736 of file res_agi.c.

References ast_log(), LOG_WARNING, and MAX_ARGS.

01737 {
01738    int x=0;
01739    int quoted=0;
01740    int escaped=0;
01741    int whitespace=1;
01742    char *cur;
01743 
01744    cur = s;
01745    while(*s) {
01746       switch(*s) {
01747       case '"':
01748          /* If it's escaped, put a literal quote */
01749          if (escaped) 
01750             goto normal;
01751          else 
01752             quoted = !quoted;
01753          if (quoted && whitespace) {
01754             /* If we're starting a quote, coming off white space start a new word, too */
01755             argv[x++] = cur;
01756             whitespace=0;
01757          }
01758          escaped = 0;
01759       break;
01760       case ' ':
01761       case '\t':
01762          if (!quoted && !escaped) {
01763             /* If we're not quoted, mark this as whitespace, and
01764                end the previous argument */
01765             whitespace = 1;
01766             *(cur++) = '\0';
01767          } else
01768             /* Otherwise, just treat it as anything else */ 
01769             goto normal;
01770          break;
01771       case '\\':
01772          /* If we're escaped, print a literal, otherwise enable escaping */
01773          if (escaped) {
01774             goto normal;
01775          } else {
01776             escaped=1;
01777          }
01778          break;
01779       default:
01780 normal:
01781          if (whitespace) {
01782             if (x >= MAX_ARGS -1) {
01783                ast_log(LOG_WARNING, "Too many arguments, truncating\n");
01784                break;
01785             }
01786             /* Coming off of whitespace, start the next argument */
01787             argv[x++] = cur;
01788             whitespace=0;
01789          }
01790          *(cur++) = *s;
01791          escaped=0;
01792       }
01793       s++;
01794    }
01795    /* Null terminate */
01796    *(cur++) = '\0';
01797    argv[x] = NULL;
01798    *max = x;
01799    return 0;
01800 }

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

Definition at line 1834 of file res_agi.c.

References agi_handle_command(), AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, agidebug, AST_FRAME_VOICE, ast_frfree(), ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_verbose(), ast_waitfor_nandfds(), agi_state::audio, agi_state::ctrl, ast_frame::data, ast_frame::datalen, agi_state::fd, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, RETRY, setup_env(), and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

01835 {
01836    struct ast_channel *c;
01837    int outfd;
01838    int ms;
01839    enum agi_result returnstatus = AGI_RESULT_SUCCESS;
01840    struct ast_frame *f;
01841    char buf[2048];
01842    FILE *readf;
01843    /* how many times we'll retry if ast_waitfor_nandfs will return without either 
01844      channel or file descriptor in case select is interrupted by a system call (EINTR) */
01845    int retry = RETRY;
01846 
01847    if (!(readf = fdopen(agi->ctrl, "r"))) {
01848       ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n");
01849       if (pid > -1)
01850          kill(pid, SIGHUP);
01851       close(agi->ctrl);
01852       return AGI_RESULT_FAILURE;
01853    }
01854    setlinebuf(readf);
01855    setup_env(chan, request, agi->fd, (agi->audio > -1), argc, argv);
01856    for (;;) {
01857       ms = -1;
01858       c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
01859       if (c) {
01860          retry = RETRY;
01861          /* Idle the channel until we get a command */
01862          f = ast_read(c);
01863          if (!f) {
01864             if (option_debug)
01865                ast_log(LOG_DEBUG, "%s hungup\n", chan->name);
01866             returnstatus = AGI_RESULT_HANGUP;
01867             break;
01868          } else {
01869             /* If it's voice, write it to the audio pipe */
01870             if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) {
01871                /* Write, ignoring errors */
01872                write(agi->audio, f->data, f->datalen);
01873             }
01874             ast_frfree(f);
01875          }
01876       } else if (outfd > -1) {
01877          retry = RETRY;
01878          if (!fgets(buf, sizeof(buf), readf)) {
01879             /* Program terminated */
01880             if (returnstatus)
01881                returnstatus = -1;
01882             if (option_verbose > 2) 
01883                ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus);
01884             if (pid > 0)
01885                waitpid(pid, status, 0);
01886             /* No need to kill the pid anymore, since they closed us */
01887             pid = -1;
01888             break;
01889          }
01890          /* get rid of trailing newline, if any */
01891          if (*buf && buf[strlen(buf) - 1] == '\n')
01892             buf[strlen(buf) - 1] = 0;
01893          if (agidebug)
01894             ast_verbose("AGI Rx << %s\n", buf);
01895          returnstatus |= agi_handle_command(chan, agi, buf);
01896          /* If the handle_command returns -1, we need to stop */
01897          if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
01898             break;
01899          }
01900       } else {
01901          if (--retry <= 0) {
01902             ast_log(LOG_WARNING, "No channel, no fd?\n");
01903             returnstatus = AGI_RESULT_FAILURE;
01904             break;
01905          }
01906       }
01907    }
01908    /* Notify process */
01909    if (pid > -1) {
01910       const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
01911       if (ast_strlen_zero(sighup) || !ast_false(sighup)) {
01912          if (kill(pid, SIGHUP))
01913             ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno));
01914       }
01915    }
01916    fclose(readf);
01917    return returnstatus;
01918 }

static void setup_env struct ast_channel chan,
char *  request,
int  fd,
int  enhanced,
int  argc,
char *  argv[]
[static]
 

Definition at line 368 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().

00369 {
00370    int count;
00371 
00372    /* Print initial environment, with agi_request always being the first
00373       thing */
00374    fdprintf(fd, "agi_request: %s\n", request);
00375    fdprintf(fd, "agi_channel: %s\n", chan->name);
00376    fdprintf(fd, "agi_language: %s\n", chan->language);
00377    fdprintf(fd, "agi_type: %s\n", chan->tech->type);
00378    fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid);
00379 
00380    /* ANI/DNIS */
00381    fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown"));
00382    fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown"));
00383    fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres);
00384    fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2);
00385    fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton);
00386    fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns);
00387    fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown"));
00388    fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown"));
00389 
00390    /* Context information */
00391    fdprintf(fd, "agi_context: %s\n", chan->context);
00392    fdprintf(fd, "agi_extension: %s\n", chan->exten);
00393    fdprintf(fd, "agi_priority: %d\n", chan->priority);
00394    fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
00395 
00396    /* User information */
00397    fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
00398     
00399    /* Send any parameters to the fastagi server that have been passed via the agi application */
00400    /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */
00401    for(count = 1; count < argc; count++)
00402       fdprintf(fd, "agi_arg_%d: %s\n", count, argv[count]);
00403 
00404    /* End with empty return */
00405    fdprintf(fd, "\n");
00406 }

static int unload_module void   )  [static]
 

Definition at line 2128 of file res_agi.c.

References app, ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_unregister_application(), cli_agi, deadapp, and eapp.


Variable Documentation

int agidebug = 0 [static]
 

Definition at line 103 of file res_agi.c.

Referenced by run_agi().

char* app = "AGI" [static]
 

Definition at line 74 of file res_agi.c.

struct ast_cli_entry cli_agi[] [static]
 

Definition at line 2110 of file res_agi.c.

Referenced by load_module(), and unload_module().

agi_command commands[MAX_COMMANDS] [static]
 

Definition at line 1610 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 78 of file res_agi.c.

Referenced by load_module(), and unload_module().

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

Definition at line 82 of file res_agi.c.

Referenced by load_module().

const char debug_usage[] [static]
 

Initial value:

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

Definition at line 1321 of file res_agi.c.

char* descrip [static]
 

Definition at line 84 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 2106 of file res_agi.c.

char* eapp = "EAGI" [static]
 

Definition at line 76 of file res_agi.c.

Referenced by load_module(), and unload_module().

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

Definition at line 81 of file res_agi.c.

Referenced by load_module().

const char no_debug_usage[] [static]
 

Initial value:

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

Definition at line 1325 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 2099 of file res_agi.c.

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

Definition at line 80 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 1445 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 1600 of file res_agi.c.

char usage_channelstatus[] [static]
 

Definition at line 1417 of file res_agi.c.

char usage_controlstreamfile[] [static]
 

Definition at line 1501 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 1383 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 1389 of file res_agi.c.

char usage_dbget[] [static]
 

Definition at line 1375 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 1369 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 1435 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 1570 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 1511 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 1401 of file res_agi.c.

char usage_getvariablefull[] [static]
 

Definition at line 1407 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 1440 of file res_agi.c.

char usage_noop[] [static]
 

Initial value:

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

Definition at line 1606 of file res_agi.c.

char usage_recordfile[] [static]
 

Definition at line 1588 of file res_agi.c.

char usage_recvchar[] [static]
 

Definition at line 1465 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 1473 of file res_agi.c.

char usage_sayalpha[] [static]
 

Definition at line 1529 of file res_agi.c.

char usage_saydate[] [static]
 

Definition at line 1536 of file res_agi.c.

char usage_saydatetime[] [static]
 

Definition at line 1552 of file res_agi.c.

char usage_saydigits[] [static]
 

Definition at line 1522 of file res_agi.c.

char usage_saynumber[] [static]
 

Definition at line 1515 of file res_agi.c.

char usage_sayphonetic[] [static]
 

Definition at line 1563 of file res_agi.c.

char usage_saytime[] [static]
 

Definition at line 1544 of file res_agi.c.

char usage_sendimage[] [static]
 

Definition at line 1484 of file res_agi.c.

char usage_sendtext[] [static]
 

Definition at line 1457 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 1431 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 1575 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 1579 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 1363 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 1583 of file res_agi.c.

char usage_setvariable[] [static]
 

Initial value:

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

Definition at line 1414 of file res_agi.c.

char usage_streamfile[] [static]
 

Definition at line 1491 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 1479 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 1395 of file res_agi.c.

char usage_waitfordigit[] [static]
 

Definition at line 1450 of file res_agi.c.


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen