Sat Mar 24 23:30:04 2007

Asterisk developer's documentation


res_agi.c File Reference

AGI - the Asterisk Gateway Interface. More...

#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 "asterisk.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/manager.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

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 agi_register (agi_command *agi)
void agi_unregister (agi_command *agi)
static int deadagi_exec (struct ast_channel *chan, void *data)
char * description (void)
 Provides a description of the module.
static int eagi_exec (struct ast_channel *chan, void *data)
static agi_commandfind_command (char *cmds[], int exact)
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_dumpagihtml (int fd, 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 void join (char *s, size_t len, char *w[])
char * key ()
 Returns the ASTERISK_GPL_KEY.
static int launch_netscript (char *agiurl, char *argv[], int *fds, int *efd, int *opid)
static int launch_script (char *script, char *argv[], int *fds, int *efd, int *opid)
int load_module (void)
 Initialize the module.
static int parse_args (char *s, int *max, char *argv[])
static int run_agi (struct ast_channel *chan, char *request, AGI *agi, int pid, int dead)
static void setup_env (struct ast_channel *chan, char *request, int fd, int enhanced)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static int agidebug = 0
static char * app = "AGI"
static struct ast_cli_entry cli_debug
static struct ast_cli_entry cli_no_debug
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 struct ast_cli_entry dumpagihtml
static char dumpagihtml_help []
static char * eapp = "EAGI"
static char * esynopsis = "Executes an EAGI compliant application"
 LOCAL_USER_DECL
static char no_debug_usage []
static struct ast_cli_entry showagi
static char showagi_help []
 STANDARD_LOCAL_USER
static char * synopsis = "Executes an AGI compliant application"
static char * tdesc = "Asterisk Gateway Interface (AGI)"
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 []


Detailed Description

AGI - the Asterisk Gateway Interface.

Definition in file res_agi.c.


Define Documentation

#define AGI_PORT   4573
 

Definition at line 109 of file res_agi.c.

Referenced by launch_netscript().

#define fdprintf   agi_debug_cli
 

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

Referenced by launch_netscript().

#define MAX_ARGS   128
 

Definition at line 67 of file res_agi.c.

#define MAX_COMMANDS   128
 

Definition at line 68 of file res_agi.c.

Referenced by agi_register(), and agi_unregister().

#define RETRY   3
 

Definition at line 1844 of file res_agi.c.

Referenced by run_agi().

#define TONE_BLOCK_SIZE   200
 

Definition at line 104 of file res_agi.c.


Function Documentation

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

Definition at line 111 of file res_agi.c.

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

00112 {
00113    char *stuff;
00114    int res = 0;
00115 
00116    va_list ap;
00117    va_start(ap, fmt);
00118    res = vasprintf(&stuff, fmt, ap);
00119    va_end(ap);
00120    if (res == -1) {
00121       ast_log(LOG_ERROR, "Out of memory\n");
00122    } else {
00123       if (agidebug)
00124          ast_verbose("AGI Tx >> %s", stuff);
00125       ast_carefulwrite(fd, stuff, strlen(stuff), 100);
00126       free(stuff);
00127    }
00128 }

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

Definition at line 1304 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01305 {
01306    if (argc != 2)
01307       return RESULT_SHOWUSAGE;
01308    agidebug = 1;
01309    ast_cli(fd, "AGI Debugging Enabled\n");
01310    return RESULT_SUCCESS;
01311 }

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

Definition at line 2053 of file res_agi.c.

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

Referenced by load_module().

02054 {
02055    if (chan->_softhangup)
02056       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02057    return agi_exec_full(chan, data, 0, 0);
02058 }

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

Definition at line 2004 of file res_agi.c.

References ast_channel::_state, ast_answer(), ast_log(), AST_STATE_UP, ast_strlen_zero(), localuser::chan, launch_script(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, MAX_ARGS, run_agi(), and strsep().

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

02005 {
02006    int res=0;
02007    struct localuser *u;
02008    char *argv[MAX_ARGS];
02009    char buf[2048]="";
02010    char *tmp = (char *)buf;
02011    int argc = 0;
02012    int fds[2];
02013    int efd = -1;
02014    int pid;
02015         char *stringp;
02016    AGI agi;
02017 
02018    if (ast_strlen_zero(data)) {
02019       ast_log(LOG_WARNING, "AGI requires an argument (script)\n");
02020       return -1;
02021    }
02022    ast_copy_string(buf, data, sizeof(buf));
02023 
02024    memset(&agi, 0, sizeof(agi));
02025         while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS - 1)
02026       argv[argc++] = stringp;
02027    argv[argc] = NULL;
02028 
02029    LOCAL_USER_ADD(u);
02030 #if 0
02031     /* Answer if need be */
02032         if (chan->_state != AST_STATE_UP) {
02033       if (ast_answer(chan)) {
02034          LOCAL_USER_REMOVE(u);
02035          return -1;
02036       }
02037    }
02038 #endif
02039    res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid);
02040    if (!res) {
02041       agi.fd = fds[1];
02042       agi.ctrl = fds[0];
02043       agi.audio = efd;
02044       res = run_agi(chan, argv[0], &agi, pid, dead);
02045       close(fds[1]);
02046       if (efd > -1)
02047          close(efd);
02048    }
02049    LOCAL_USER_REMOVE(u);
02050    return res;
02051 }

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

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

01808 {
01809    char *argv[MAX_ARGS];
01810    int argc = 0;
01811    int res;
01812    agi_command *c;
01813    argc = MAX_ARGS;
01814 
01815    parse_args(buf, &argc, argv);
01816 #if   0
01817    { int x;
01818    for (x=0; x<argc; x++) 
01819       fprintf(stderr, "Got Arg%d: %s\n", x, argv[x]); }
01820 #endif
01821    c = find_command(argv, 0);
01822    if (c) {
01823       res = c->handler(chan, agi, argc, argv);
01824       switch(res) {
01825       case RESULT_SHOWUSAGE:
01826          fdprintf(agi->fd, "520-Invalid command syntax.  Proper usage follows:\n");
01827          fdprintf(agi->fd, c->usage);
01828          fdprintf(agi->fd, "520 End of proper usage.\n");
01829          break;
01830       case AST_PBX_KEEPALIVE:
01831          /* We've been asked to keep alive, so do so */
01832          return AST_PBX_KEEPALIVE;
01833          break;
01834       case RESULT_FAILURE:
01835          /* They've already given the failure.  We've been hung up on so handle this
01836             appropriately */
01837          return -1;
01838       }
01839    } else {
01840       fdprintf(agi->fd, "510 Invalid or unknown command\n");
01841    }
01842    return 0;
01843 }

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

Definition at line 1313 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01314 {
01315    if (argc != 3)
01316       return RESULT_SHOWUSAGE;
01317    agidebug = 0;
01318    ast_cli(fd, "AGI Debugging Disabled\n");
01319    return RESULT_SUCCESS;
01320 }

int agi_register agi_command agi  ) 
 

Definition at line 1678 of file res_agi.c.

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

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

void agi_unregister agi_command agi  ) 
 

Definition at line 1697 of file res_agi.c.

References agi_command::cmda, commands, and MAX_COMMANDS.

01698 {
01699    int x;
01700    for (x=0; x<MAX_COMMANDS - 1; x++) {
01701       if (commands[x].cmda[0] == agi->cmda[0]) {
01702          memset(&commands[x], 0, sizeof(agi_command));
01703       }
01704    }
01705 }

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

Definition at line 2081 of file res_agi.c.

References agi_exec_full(), and localuser::chan.

Referenced by load_module().

02082 {
02083    return agi_exec_full(chan, data, 0, 1);
02084 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 2126 of file res_agi.c.

References tdesc.

02127 {
02128    return tdesc;
02129 }

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

Definition at line 2060 of file res_agi.c.

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

Referenced by load_module().

02061 {
02062    int readformat;
02063    int res;
02064 
02065    if (chan->_softhangup)
02066       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02067    readformat = chan->readformat;
02068    if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
02069       ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
02070       return -1;
02071    }
02072    res = agi_exec_full(chan, data, 1, 0);
02073    if (!res) {
02074       if (ast_set_read_format(chan, readformat)) {
02075          ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
02076       }
02077    }
02078    return res;
02079 }

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

Definition at line 1707 of file res_agi.c.

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

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

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

Definition at line 362 of file res_agi.c.

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

00363 {
00364    int res;
00365    res = 0;
00366    if (chan->_state != AST_STATE_UP) {
00367       /* Answer the chan */
00368       res = ast_answer(chan);
00369    }
00370    fdprintf(agi->fd, "200 result=%d\n", res);
00371    if (res >= 0)
00372       return RESULT_SUCCESS;
00373    else
00374       return RESULT_FAILURE;
00375 }

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

Definition at line 1031 of file res_agi.c.

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

01032 {
01033    int timeout;
01034 
01035    if (argc != 3)
01036       return RESULT_SHOWUSAGE;
01037    if (sscanf(argv[2], "%d", &timeout) != 1)
01038       return RESULT_SHOWUSAGE;
01039    if (timeout < 0)
01040       timeout = 0;
01041    if (timeout)
01042       chan->whentohangup = time(NULL) + timeout;
01043    else
01044       chan->whentohangup = 0;
01045    fdprintf(agi->fd, "200 result=0\n");
01046    return RESULT_SUCCESS;
01047 }

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

Definition at line 1120 of file res_agi.c.

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

01121 {
01122    struct ast_channel *c;
01123    if (argc == 2) {
01124       /* no argument: supply info on the current channel */
01125       fdprintf(agi->fd, "200 result=%d\n", chan->_state);
01126       return RESULT_SUCCESS;
01127    } else if (argc == 3) {
01128       /* one argument: look for info on the specified channel */
01129       c = ast_get_channel_by_name_locked(argv[2]);
01130       if (c) {
01131          fdprintf(agi->fd, "200 result=%d\n", c->_state);
01132          ast_mutex_unlock(&c->lock);
01133          return RESULT_SUCCESS;
01134       }
01135       /* if we get this far no channel name matched the argument given */
01136       fdprintf(agi->fd, "200 result=-1\n");
01137       return RESULT_SUCCESS;
01138    } else {
01139       return RESULT_SHOWUSAGE;
01140    }
01141 }

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

Definition at line 485 of file res_agi.c.

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

00486 {
00487    int res = 0;
00488    int skipms = 3000;
00489    char *fwd = NULL;
00490    char *rev = NULL;
00491    char *pause = NULL;
00492    char *stop = NULL;
00493 
00494    if (argc < 5 || argc > 9)
00495       return RESULT_SHOWUSAGE;
00496 
00497    if (!ast_strlen_zero(argv[4]))
00498       stop = argv[4];
00499    else
00500       stop = NULL;
00501    
00502    if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1))
00503       return RESULT_SHOWUSAGE;
00504 
00505    if (argc > 6 && !ast_strlen_zero(argv[8]))
00506       fwd = argv[6];
00507    else
00508       fwd = "#";
00509 
00510    if (argc > 7 && !ast_strlen_zero(argv[8]))
00511       rev = argv[7];
00512    else
00513       rev = "*";
00514    
00515    if (argc > 8 && !ast_strlen_zero(argv[8]))
00516       pause = argv[8];
00517    else
00518       pause = NULL;
00519    
00520    res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms);
00521    
00522    fdprintf(agi->fd, "200 result=%d\n", res);
00523 
00524    if (res >= 0)
00525       return RESULT_SUCCESS;
00526    else
00527       return RESULT_FAILURE;
00528 }

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

Definition at line 1264 of file res_agi.c.

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

01265 {
01266    int res;
01267 
01268    if (argc != 4)
01269       return RESULT_SHOWUSAGE;
01270    res = ast_db_del(argv[2], argv[3]);
01271    if (res) 
01272       fdprintf(agi->fd, "200 result=0\n");
01273    else
01274       fdprintf(agi->fd, "200 result=1\n");
01275 
01276    return RESULT_SUCCESS;
01277 }

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

Definition at line 1279 of file res_agi.c.

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

01280 {
01281    int res;
01282    if ((argc < 3) || (argc > 4))
01283       return RESULT_SHOWUSAGE;
01284    if (argc == 4)
01285       res = ast_db_deltree(argv[2], argv[3]);
01286    else
01287       res = ast_db_deltree(argv[2], NULL);
01288 
01289    if (res) 
01290       fdprintf(agi->fd, "200 result=0\n");
01291    else
01292       fdprintf(agi->fd, "200 result=1\n");
01293    return RESULT_SUCCESS;
01294 }

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

Definition at line 1233 of file res_agi.c.

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

01234 {
01235    int res;
01236    char tmp[256];
01237 
01238    if (argc != 4)
01239       return RESULT_SHOWUSAGE;
01240    res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
01241    if (res) 
01242       fdprintf(agi->fd, "200 result=0\n");
01243    else
01244       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01245 
01246    return RESULT_SUCCESS;
01247 }

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

Definition at line 1249 of file res_agi.c.

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

01250 {
01251    int res;
01252 
01253    if (argc != 5)
01254       return RESULT_SHOWUSAGE;
01255    res = ast_db_put(argv[2], argv[3], argv[4]);
01256    if (res) 
01257       fdprintf(agi->fd, "200 result=0\n");
01258    else
01259       fdprintf(agi->fd, "200 result=1\n");
01260 
01261    return RESULT_SUCCESS;
01262 }

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

Definition at line 1948 of file res_agi.c.

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

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

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

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

01076 {
01077    int res;
01078    struct ast_app *app;
01079 
01080    if (argc < 2)
01081       return RESULT_SHOWUSAGE;
01082 
01083    if (option_verbose > 2)
01084       ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]);
01085 
01086    app = pbx_findapp(argv[1]);
01087 
01088    if (app) {
01089       res = pbx_exec(chan, app, argv[2], 1);
01090    } else {
01091       ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
01092       res = -2;
01093    }
01094    fdprintf(agi->fd, "200 result=%d\n", res);
01095 
01096    return res;
01097 }

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

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

00798 {
00799    int res;
00800    char data[1024];
00801    int max;
00802    int timeout;
00803 
00804    if (argc < 3)
00805       return RESULT_SHOWUSAGE;
00806    if (argc >= 4)
00807       timeout = atoi(argv[3]); 
00808    else
00809       timeout = 0;
00810    if (argc >= 5) 
00811       max = atoi(argv[4]); 
00812    else
00813       max = 1024;
00814    res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
00815    if (res == 2)        /* New command */
00816       return RESULT_SUCCESS;
00817    else if (res == 1)
00818       fdprintf(agi->fd, "200 result=%s (timeout)\n", data);
00819    else if (res < 0 )
00820       fdprintf(agi->fd, "200 result=-1\n");
00821    else
00822       fdprintf(agi->fd, "200 result=%s\n", data);
00823    return RESULT_SUCCESS;
00824 }

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

Definition at line 578 of file res_agi.c.

References ast_applystream(), ast_log(), ast_openstream(), 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, ast_channel::language, LOG_WARNING, option_verbose, ast_channel::pbx, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, and VERBOSE_PREFIX_3.

00579 {
00580         int res;
00581         struct ast_filestream *fs;
00582         long sample_offset = 0;
00583         long max_length;
00584    int timeout = 0;
00585    char *edigits = NULL;
00586 
00587    if ( argc < 4 || argc > 5 )
00588       return RESULT_SHOWUSAGE;
00589 
00590    if ( argv[3] ) 
00591       edigits = argv[3];
00592 
00593    if ( argc == 5 )
00594       timeout = atoi(argv[4]);
00595    else if (chan->pbx->dtimeout) {
00596       /* by default dtimeout is set to 5sec */
00597       timeout = chan->pbx->dtimeout * 1000; /* in msec */
00598    }
00599 
00600         fs = ast_openstream(chan, argv[2], chan->language);
00601         if (!fs){
00602                 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
00603                 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]);
00604       return RESULT_SUCCESS;
00605         }
00606    if (option_verbose > 2)
00607       ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout);
00608 
00609         ast_seekstream(fs, 0, SEEK_END);
00610         max_length = ast_tellstream(fs);
00611         ast_seekstream(fs, sample_offset, SEEK_SET);
00612         res = ast_applystream(chan, fs);
00613         res = ast_playstream(fs);
00614         if (res) {
00615                 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00616                 if (res >= 0)
00617                         return RESULT_SHOWUSAGE;
00618                 else
00619                         return RESULT_FAILURE;
00620         }
00621         res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
00622         /* this is to check for if ast_waitstream closed the stream, we probably are at
00623          * the end of the stream, return that amount, else check for the amount */
00624         sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
00625         ast_stopstream(chan);
00626         if (res == 1) {
00627                 /* Stop this command, don't print a result line, as there is a new command */
00628                 return RESULT_SUCCESS;
00629         }
00630 
00631    /* If the user didnt press a key, wait for digitTimeout*/
00632    if (res == 0 ) {
00633       res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
00634       /* Make sure the new result is in the escape digits of the GET OPTION */
00635       if ( !strchr(edigits,res) )
00636                   res=0;
00637    }
00638 
00639         fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00640         if (res >= 0)
00641                 return RESULT_SUCCESS;
00642         else
00643                 return RESULT_FAILURE;
00644 }

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

Definition at line 1152 of file res_agi.c.

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

01153 {
01154    char *ret;
01155    char tempstr[1024];
01156 
01157    if (argc != 3)
01158       return RESULT_SHOWUSAGE;
01159 
01160    /* check if we want to execute an ast_custom_function */
01161    if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
01162       ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr));
01163    } else {
01164       pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
01165    }
01166 
01167    if (ret)
01168       fdprintf(agi->fd, "200 result=1 (%s)\n", ret);
01169    else
01170       fdprintf(agi->fd, "200 result=0\n");
01171 
01172    return RESULT_SUCCESS;
01173 }

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

Definition at line 1175 of file res_agi.c.

References ast_get_channel_by_name_locked(), ast_mutex_unlock(), agi_state::fd, fdprintf, ast_channel::lock, pbx_substitute_variables_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01176 {
01177    char tmp[4096] = "";
01178    struct ast_channel *chan2=NULL;
01179 
01180    if ((argc != 4) && (argc != 5))
01181       return RESULT_SHOWUSAGE;
01182    if (argc == 5) {
01183       chan2 = ast_get_channel_by_name_locked(argv[4]);
01184    } else {
01185       chan2 = chan;
01186    }
01187    if (chan) { /* XXX isn't this chan2 ? */
01188       pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1);
01189       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01190    } else {
01191       fdprintf(agi->fd, "200 result=0\n");
01192    }
01193    if (chan2 && (chan2 != chan))
01194       ast_mutex_unlock(&chan2->lock);
01195    return RESULT_SUCCESS;
01196 }

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

Definition at line 1049 of file res_agi.c.

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

01050 {
01051    struct ast_channel *c;
01052    if (argc == 1) {
01053       /* no argument: hangup the current channel */
01054       ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
01055       fdprintf(agi->fd, "200 result=1\n");
01056       return RESULT_SUCCESS;
01057    } else if (argc == 2) {
01058       /* one argument: look for info on the specified channel */
01059       c = ast_get_channel_by_name_locked(argv[1]);
01060       if (c) {
01061          /* we have a matching channel */
01062          ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
01063          fdprintf(agi->fd, "200 result=1\n");
01064          ast_mutex_unlock(&c->lock);
01065          return RESULT_SUCCESS;
01066       }
01067       /* if we get this far no channel name matched the argument given */
01068       fdprintf(agi->fd, "200 result=-1\n");
01069       return RESULT_SUCCESS;
01070    } else {
01071       return RESULT_SHOWUSAGE;
01072    }
01073 }

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

Definition at line 1328 of file res_agi.c.

References agi_state::fd, fdprintf, and RESULT_SUCCESS.

01329 {
01330    fdprintf(agi->fd, "200 result=0\n");
01331    return RESULT_SUCCESS;
01332 }

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

Definition at line 861 of file res_agi.c.

References ast_applystream(), ast_closestream(), ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), 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, ast_channel::language, LOG_WARNING, ast_channel::name, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, ast_frame::subclass, and ast_dsp::totalsilence.

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

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

Definition at line 413 of file res_agi.c.

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

00414 {
00415    int res;
00416    if (argc != 3)
00417       return RESULT_SHOWUSAGE;
00418    res = ast_recvchar(chan,atoi(argv[2]));
00419    if (res == 0) {
00420       fdprintf(agi->fd, "200 result=%d (timeout)\n", res);
00421       return RESULT_SUCCESS;
00422    }
00423    if (res > 0) {
00424       fdprintf(agi->fd, "200 result=%d\n", res);
00425       return RESULT_SUCCESS;
00426    }
00427    else {
00428       fdprintf(agi->fd, "200 result=%d (hangup)\n", res);
00429       return RESULT_FAILURE;
00430    }
00431 }

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

Definition at line 433 of file res_agi.c.

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

00434 {
00435    char *buf;
00436    
00437    if (argc != 3)
00438       return RESULT_SHOWUSAGE;
00439    buf = ast_recvtext(chan,atoi(argv[2]));
00440    if (buf) {
00441       fdprintf(agi->fd, "200 result=1 (%s)\n", buf);
00442       free(buf);
00443    } else { 
00444       fdprintf(agi->fd, "200 result=-1\n");
00445    }
00446    return RESULT_SUCCESS;
00447 }

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

Definition at line 690 of file res_agi.c.

References ast_say_character_str_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00691 {
00692    int res;
00693 
00694    if (argc != 4)
00695       return RESULT_SHOWUSAGE;
00696 
00697    res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00698    if (res == 1) /* New command */
00699       return RESULT_SUCCESS;
00700    fdprintf(agi->fd, "200 result=%d\n", res);
00701    if (res >= 0)
00702       return RESULT_SUCCESS;
00703    else
00704       return RESULT_FAILURE;
00705 }

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

Definition at line 707 of file res_agi.c.

References ast_say_date(), agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00708 {
00709    int res;
00710    int num;
00711    if (argc != 4)
00712       return RESULT_SHOWUSAGE;
00713    if (sscanf(argv[2], "%d", &num) != 1)
00714       return RESULT_SHOWUSAGE;
00715    res = ast_say_date(chan, num, argv[3], chan->language);
00716    if (res == 1)
00717       return RESULT_SUCCESS;
00718    fdprintf(agi->fd, "200 result=%d\n", res);
00719    if (res >= 0)
00720       return RESULT_SUCCESS;
00721    else
00722       return RESULT_FAILURE;
00723 }

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

Definition at line 743 of file res_agi.c.

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

00744 {
00745    int res=0;
00746    long unixtime;
00747    char *format, *zone=NULL;
00748    
00749    if (argc < 4)
00750       return RESULT_SHOWUSAGE;
00751 
00752    if (argc > 4) {
00753       format = argv[4];
00754    } else {
00755       if (!strcasecmp(chan->language, "de")) {
00756          format = "A dBY HMS";
00757       } else {
00758          format = "ABdY 'digits/at' IMp"; 
00759       }
00760    }
00761 
00762    if (argc > 5 && !ast_strlen_zero(argv[5]))
00763       zone = argv[5];
00764 
00765    if (sscanf(argv[2], "%ld", &unixtime) != 1)
00766       return RESULT_SHOWUSAGE;
00767 
00768    res = ast_say_date_with_format(chan, (time_t) unixtime, argv[3], chan->language, format, zone);
00769    if (res == 1)
00770       return RESULT_SUCCESS;
00771 
00772    fdprintf(agi->fd, "200 result=%d\n", res);
00773 
00774    if (res >= 0)
00775       return RESULT_SUCCESS;
00776    else
00777       return RESULT_FAILURE;
00778 }

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

Definition at line 670 of file res_agi.c.

References ast_say_digit_str_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00671 {
00672    int res;
00673    int num;
00674 
00675    if (argc != 4)
00676       return RESULT_SHOWUSAGE;
00677    if (sscanf(argv[2], "%d", &num) != 1)
00678       return RESULT_SHOWUSAGE;
00679 
00680    res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00681    if (res == 1) /* New command */
00682       return RESULT_SUCCESS;
00683    fdprintf(agi->fd, "200 result=%d\n", res);
00684    if (res >= 0)
00685       return RESULT_SUCCESS;
00686    else
00687       return RESULT_FAILURE;
00688 }

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

Definition at line 652 of file res_agi.c.

References ast_say_number_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00653 {
00654    int res;
00655    int num;
00656    if (argc != 4)
00657       return RESULT_SHOWUSAGE;
00658    if (sscanf(argv[2], "%d", &num) != 1)
00659       return RESULT_SHOWUSAGE;
00660    res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl);
00661    if (res == 1)
00662       return RESULT_SUCCESS;
00663    fdprintf(agi->fd, "200 result=%d\n", res);
00664    if (res >= 0)
00665       return RESULT_SUCCESS;
00666    else
00667       return RESULT_FAILURE;
00668 }

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

Definition at line 780 of file res_agi.c.

References ast_say_phonetic_str_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00781 {
00782    int res;
00783 
00784    if (argc != 4)
00785       return RESULT_SHOWUSAGE;
00786 
00787    res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00788    if (res == 1) /* New command */
00789       return RESULT_SUCCESS;
00790    fdprintf(agi->fd, "200 result=%d\n", res);
00791    if (res >= 0)
00792       return RESULT_SUCCESS;
00793    else
00794       return RESULT_FAILURE;
00795 }

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

Definition at line 725 of file res_agi.c.

References ast_say_time(), agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00726 {
00727    int res;
00728    int num;
00729    if (argc != 4)
00730       return RESULT_SHOWUSAGE;
00731    if (sscanf(argv[2], "%d", &num) != 1)
00732       return RESULT_SHOWUSAGE;
00733    res = ast_say_time(chan, num, argv[3], chan->language);
00734    if (res == 1)
00735       return RESULT_SUCCESS;
00736    fdprintf(agi->fd, "200 result=%d\n", res);
00737    if (res >= 0)
00738       return RESULT_SUCCESS;
00739    else
00740       return RESULT_FAILURE;
00741 }

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

Definition at line 470 of file res_agi.c.

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

00471 {
00472    int res;
00473    if (argc != 3)
00474       return RESULT_SHOWUSAGE;
00475    res = ast_send_image(chan, argv[2]);
00476    if (!ast_check_hangup(chan))
00477       res = 0;
00478    fdprintf(agi->fd, "200 result=%d\n", res);
00479    if (res >= 0)
00480       return RESULT_SUCCESS;
00481    else
00482       return RESULT_FAILURE;
00483 }

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

Definition at line 393 of file res_agi.c.

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

00394 {
00395    int res;
00396    if (argc != 3)
00397       return RESULT_SHOWUSAGE;
00398    /* At the moment, the parser (perhaps broken) returns with
00399       the last argument PLUS the newline at the end of the input
00400       buffer. This probably needs to be fixed, but I wont do that
00401       because other stuff may break as a result. The right way
00402       would probably be to strip off the trailing newline before
00403       parsing, then here, add a newline at the end of the string
00404       before sending it to ast_sendtext --DUDE */
00405    res = ast_sendtext(chan, argv[2]);
00406    fdprintf(agi->fd, "200 result=%d\n", res);
00407    if (res >= 0)
00408       return RESULT_SUCCESS;
00409    else
00410       return RESULT_FAILURE;
00411 }

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

Definition at line 1099 of file res_agi.c.

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

01100 {
01101    char tmp[256]="";
01102    char *l = NULL, *n = NULL;
01103 
01104    if (argv[2]) {
01105       ast_copy_string(tmp, argv[2], sizeof(tmp));
01106       ast_callerid_parse(tmp, &n, &l);
01107       if (l)
01108          ast_shrink_phone_number(l);
01109       else
01110          l = "";
01111       if (!n)
01112          n = "";
01113       ast_set_callerid(chan, l, n, NULL);
01114    }
01115 
01116    fdprintf(agi->fd, "200 result=1\n");
01117    return RESULT_SUCCESS;
01118 }

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

Definition at line 826 of file res_agi.c.

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

00827 {
00828 
00829    if (argc != 3)
00830       return RESULT_SHOWUSAGE;
00831    ast_copy_string(chan->context, argv[2], sizeof(chan->context));
00832    fdprintf(agi->fd, "200 result=0\n");
00833    return RESULT_SUCCESS;
00834 }

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

Definition at line 836 of file res_agi.c.

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

00837 {
00838    if (argc != 3)
00839       return RESULT_SHOWUSAGE;
00840    ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
00841    fdprintf(agi->fd, "200 result=0\n");
00842    return RESULT_SUCCESS;
00843 }

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

Definition at line 1334 of file res_agi.c.

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

01335 {
01336    if (!strncasecmp(argv[2],"on",2)) {
01337       if (argc > 3)
01338          ast_moh_start(chan, argv[3]);
01339       else
01340          ast_moh_start(chan, NULL);
01341    }
01342    if (!strncasecmp(argv[2],"off",3)) {
01343       ast_moh_stop(chan);
01344    }
01345    fdprintf(agi->fd, "200 result=0\n");
01346    return RESULT_SUCCESS;
01347 }

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

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

00846 {
00847    int pri;
00848    if (argc != 3)
00849       return RESULT_SHOWUSAGE;   
00850 
00851    if (sscanf(argv[2], "%d", &pri) != 1) {
00852       if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
00853          return RESULT_SHOWUSAGE;
00854    }
00855 
00856    ast_explicit_goto(chan, NULL, NULL, pri);
00857    fdprintf(agi->fd, "200 result=0\n");
00858    return RESULT_SUCCESS;
00859 }

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

Definition at line 1143 of file res_agi.c.

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

01144 {
01145    if (argv[3])
01146       pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
01147 
01148    fdprintf(agi->fd, "200 result=1\n");
01149    return RESULT_SUCCESS;
01150 }

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

Definition at line 1925 of file res_agi.c.

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

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

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

Definition at line 530 of file res_agi.c.

References ast_applystream(), ast_openstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::stream.

00531 {
00532    int res;
00533    struct ast_filestream *fs;
00534    long sample_offset = 0;
00535    long max_length;
00536 
00537    if (argc < 4)
00538       return RESULT_SHOWUSAGE;
00539    if (argc > 5)
00540       return RESULT_SHOWUSAGE;
00541    if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1))
00542       return RESULT_SHOWUSAGE;
00543    
00544    fs = ast_openstream(chan, argv[2], chan->language);
00545    if (!fs){
00546       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset);
00547       return RESULT_SUCCESS;
00548    }
00549    ast_seekstream(fs, 0, SEEK_END);
00550    max_length = ast_tellstream(fs);
00551    ast_seekstream(fs, sample_offset, SEEK_SET);
00552    res = ast_applystream(chan, fs);
00553    res = ast_playstream(fs);
00554    if (res) {
00555       fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00556       if (res >= 0)
00557          return RESULT_SHOWUSAGE;
00558       else
00559          return RESULT_FAILURE;
00560    }
00561    res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
00562    /* this is to check for if ast_waitstream closed the stream, we probably are at
00563     * the end of the stream, return that amount, else check for the amount */
00564    sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
00565    ast_stopstream(chan);
00566    if (res == 1) {
00567       /* Stop this command, don't print a result line, as there is a new command */
00568       return RESULT_SUCCESS;
00569    }
00570    fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset);
00571    if (res >= 0)
00572       return RESULT_SUCCESS;
00573    else
00574       return RESULT_FAILURE;
00575 }

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

Definition at line 449 of file res_agi.c.

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

00450 {
00451    int res,x;
00452    if (argc != 3)
00453       return RESULT_SHOWUSAGE;
00454    if (!strncasecmp(argv[2],"on",2)) 
00455       x = 1; 
00456    else 
00457       x = 0;
00458    if (!strncasecmp(argv[2],"mate",4)) 
00459       x = 2;
00460    if (!strncasecmp(argv[2],"tdd",3))
00461       x = 1;
00462    res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
00463    if (res != RESULT_SUCCESS)
00464       fdprintf(agi->fd, "200 result=0\n");
00465    else
00466       fdprintf(agi->fd, "200 result=1\n");
00467    return RESULT_SUCCESS;
00468 }

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

Definition at line 1198 of file res_agi.c.

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

01199 {
01200    int level = 0;
01201    char *prefix;
01202 
01203    if (argc < 2)
01204       return RESULT_SHOWUSAGE;
01205 
01206    if (argv[2])
01207       sscanf(argv[2], "%d", &level);
01208 
01209    switch (level) {
01210       case 4:
01211          prefix = VERBOSE_PREFIX_4;
01212          break;
01213       case 3:
01214          prefix = VERBOSE_PREFIX_3;
01215          break;
01216       case 2:
01217          prefix = VERBOSE_PREFIX_2;
01218          break;
01219       case 1:
01220       default:
01221          prefix = VERBOSE_PREFIX_1;
01222          break;
01223    }
01224 
01225    if (level <= option_verbose)
01226       ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]);
01227    
01228    fdprintf(agi->fd, "200 result=1\n");
01229    
01230    return RESULT_SUCCESS;
01231 }

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

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

00378 {
00379    int res;
00380    int to;
00381    if (argc != 4)
00382       return RESULT_SHOWUSAGE;
00383    if (sscanf(argv[3], "%d", &to) != 1)
00384       return RESULT_SHOWUSAGE;
00385    res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
00386    fdprintf(agi->fd, "200 result=%d\n", res);
00387    if (res >= 0)
00388       return RESULT_SUCCESS;
00389    else
00390       return RESULT_FAILURE;
00391 }

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

Definition at line 1652 of file res_agi.c.

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

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

static void join char *  s,
size_t  len,
char *  w[]
[static]
 

Definition at line 1636 of file res_agi.c.

01637 {
01638    int x;
01639 
01640    /* Join words into a string */
01641    if (!s) {
01642       return;
01643    }
01644    s[0] = '\0';
01645    for (x=0; w[x]; x++) {
01646       if (x)
01647          strncat(s, " ", len - strlen(s) - 1);
01648       strncat(s, w[x], len - strlen(s) - 1);
01649    }
01650 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 2138 of file res_agi.c.

References ASTERISK_GPL_KEY.

02139 {
02140    return ASTERISK_GPL_KEY;
02141 }

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

Definition at line 132 of file res_agi.c.

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

Referenced by launch_script().

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

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

Definition at line 223 of file res_agi.c.

References ast_config_AST_AGI_DIR, ast_log(), ast_set_priority(), ast_verbose(), launch_netscript(), LOG_WARNING, option_verbose, and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

00224 {
00225    char tmp[256];
00226    int pid;
00227    int toast[2];
00228    int fromast[2];
00229    int audio[2];
00230    int x;
00231    int res;
00232    sigset_t signal_set;
00233    
00234    if (!strncasecmp(script, "agi://", 6))
00235       return launch_netscript(script, argv, fds, efd, opid);
00236    
00237    if (script[0] != '/') {
00238       snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script);
00239       script = tmp;
00240    }
00241    if (pipe(toast)) {
00242       ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno));
00243       return -1;
00244    }
00245    if (pipe(fromast)) {
00246       ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno));
00247       close(toast[0]);
00248       close(toast[1]);
00249       return -1;
00250    }
00251    if (efd) {
00252       if (pipe(audio)) {
00253          ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
00254          close(fromast[0]);
00255          close(fromast[1]);
00256          close(toast[0]);
00257          close(toast[1]);
00258          return -1;
00259       }
00260       res = fcntl(audio[1], F_GETFL);
00261       if (res > -1) 
00262          res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
00263       if (res < 0) {
00264          ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
00265          close(fromast[0]);
00266          close(fromast[1]);
00267          close(toast[0]);
00268          close(toast[1]);
00269          close(audio[0]);
00270          close(audio[1]);
00271          return -1;
00272       }
00273    }
00274    pid = fork();
00275    if (pid < 0) {
00276       ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
00277       return -1;
00278    }
00279    if (!pid) {
00280       /* Redirect stdin and out, provide enhanced audio channel if desired */
00281       dup2(fromast[0], STDIN_FILENO);
00282       dup2(toast[1], STDOUT_FILENO);
00283       if (efd) {
00284          dup2(audio[0], STDERR_FILENO + 1);
00285       } else {
00286          close(STDERR_FILENO + 1);
00287       }
00288       
00289       /* unblock important signal handlers */
00290       if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
00291          ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
00292          exit(1);
00293       }
00294 
00295       /* Close everything but stdin/out/error */
00296       for (x=STDERR_FILENO + 2;x<1024;x++) 
00297          close(x);
00298 
00299       /* Don't run AGI scripts with realtime priority -- it causes audio stutter */
00300       ast_set_priority(0);
00301 
00302       /* Execute script */
00303       execv(script, argv);
00304       /* Can't use ast_log since FD's are closed */
00305       fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno));
00306       exit(1);
00307    }
00308    if (option_verbose > 2) 
00309       ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
00310    fds[0] = toast[0];
00311    fds[1] = fromast[1];
00312    if (efd) {
00313       *efd = audio[1];
00314    }
00315    /* close what we're not using in the parent */
00316    close(toast[1]);
00317    close(fromast[0]);
00318 
00319    if (efd) {
00320       /* [PHM 12/18/03] */
00321       close(audio[0]);
00322    }
00323 
00324    *opid = pid;
00325    return 0;
00326       
00327 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 2115 of file res_agi.c.

References agi_exec(), app, ast_cli_register(), ast_register_application(), cli_debug, cli_no_debug, deadagi_exec(), deadapp, deadsynopsis, descrip, dumpagihtml, eagi_exec(), eapp, esynopsis, showagi, and synopsis.

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

Definition at line 1741 of file res_agi.c.

References ast_log(), LOG_WARNING, and MAX_ARGS.

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

static int run_agi struct ast_channel chan,
char *  request,
AGI agi,
int  pid,
int  dead
[static]
 

Definition at line 1845 of file res_agi.c.

References agi_handle_command(), 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, ast_channel::name, option_verbose, RETRY, setup_env(), and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

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

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

Definition at line 329 of file res_agi.c.

References ast_channel::accountcode, 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::language, ast_channel::name, ast_channel::priority, ast_channel::type, and ast_channel::uniqueid.

Referenced by run_agi().

00330 {
00331    /* Print initial environment, with agi_request always being the first
00332       thing */
00333    fdprintf(fd, "agi_request: %s\n", request);
00334    fdprintf(fd, "agi_channel: %s\n", chan->name);
00335    fdprintf(fd, "agi_language: %s\n", chan->language);
00336    fdprintf(fd, "agi_type: %s\n", chan->type);
00337    fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid);
00338 
00339    /* ANI/DNIS */
00340    fdprintf(fd, "agi_callerid: %s\n", chan->cid.cid_num ? chan->cid.cid_num : "unknown");
00341    fdprintf(fd, "agi_calleridname: %s\n", chan->cid.cid_name ? chan->cid.cid_name : "unknown");
00342    fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres);
00343    fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2);
00344    fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton);
00345    fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns);
00346    fdprintf(fd, "agi_dnid: %s\n", chan->cid.cid_dnid ? chan->cid.cid_dnid : "unknown");
00347    fdprintf(fd, "agi_rdnis: %s\n", chan->cid.cid_rdnis ? chan->cid.cid_rdnis : "unknown");
00348 
00349    /* Context information */
00350    fdprintf(fd, "agi_context: %s\n", chan->context);
00351    fdprintf(fd, "agi_extension: %s\n", chan->exten);
00352    fdprintf(fd, "agi_priority: %d\n", chan->priority);
00353    fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
00354 
00355    /* User information */
00356    fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
00357     
00358    /* End with empty return */
00359    fdprintf(fd, "\n");
00360 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

Standard module functions ...

Definition at line 2103 of file res_agi.c.

References app, ast_cli_unregister(), ast_unregister_application(), cli_debug, cli_no_debug, deadapp, dumpagihtml, eapp, showagi, and STANDARD_HANGUP_LOCALUSERS.

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 2131 of file res_agi.c.

References STANDARD_USECOUNT.

02132 {
02133    int res;
02134    STANDARD_USECOUNT(res);
02135    return res;
02136 }


Variable Documentation

int agidebug = 0 [static]
 

Definition at line 97 of file res_agi.c.

Referenced by run_agi().

char* app = "AGI" [static]
 

Definition at line 75 of file res_agi.c.

struct ast_cli_entry cli_debug [static]
 

Initial value:

   { { "agi", "debug", NULL }, agi_do_debug, "Enable AGI debugging", debug_usage }

Definition at line 1322 of file res_agi.c.

struct ast_cli_entry cli_no_debug [static]
 

Initial value:

   { { "agi", "no", "debug", NULL }, agi_no_debug, "Disable AGI debugging", no_debug_usage }

Definition at line 1325 of file res_agi.c.

agi_command commands[MAX_COMMANDS] [static]
 

Definition at line 1596 of file res_agi.c.

Referenced by agi_register(), agi_unregister(), dundi_showframe(), find_command(), handle_dumpagihtml(), and help_workhorse().

char* deadapp = "DeadAGI" [static]
 

Definition at line 79 of file res_agi.c.

Referenced by load_module(), and unload_module().

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

Definition at line 83 of file res_agi.c.

Referenced by load_module().

char debug_usage[] [static]
 

Initial value:

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

Definition at line 1296 of file res_agi.c.

char* descrip [static]
 

Definition at line 85 of file res_agi.c.

struct ast_cli_entry dumpagihtml [static]
 

Initial value:

 
{ { "dump", "agihtml", NULL }, handle_dumpagihtml, "Dumps a list of agi command in html format", dumpagihtml_help }

Definition at line 2100 of file res_agi.c.

Referenced by load_module(), and unload_module().

char dumpagihtml_help[] [static]
 

Initial value:

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

Definition at line 2093 of file res_agi.c.

char* eapp = "EAGI" [static]
 

Definition at line 77 of file res_agi.c.

Referenced by load_module(), and unload_module().

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

Definition at line 82 of file res_agi.c.

Referenced by load_module().

LOCAL_USER_DECL
 

Definition at line 101 of file res_agi.c.

char no_debug_usage[] [static]
 

Initial value:

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

Definition at line 1300 of file res_agi.c.

struct ast_cli_entry showagi [static]
 

Initial value:

 
{ { "show", "agi", NULL }, handle_showagi, "Show AGI commands or specific help", showagi_help }

Definition at line 2097 of file res_agi.c.

Referenced by load_module(), and unload_module().

char showagi_help[] [static]
 

Initial value:

"Usage: show agi [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 2086 of file res_agi.c.

STANDARD_LOCAL_USER
 

Definition at line 99 of file res_agi.c.

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

Definition at line 81 of file res_agi.c.

char* tdesc = "Asterisk Gateway Interface (AGI)" [static]
 

Definition at line 73 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 1431 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 1586 of file res_agi.c.

char usage_channelstatus[] [static]
 

Definition at line 1403 of file res_agi.c.

char usage_controlstreamfile[] [static]
 

Definition at line 1487 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 1369 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 1375 of file res_agi.c.

char usage_dbget[] [static]
 

Definition at line 1361 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 1355 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 1421 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 1556 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 1497 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 1387 of file res_agi.c.

char usage_getvariablefull[] [static]
 

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

char usage_noop[] [static]
 

Initial value:

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

Definition at line 1592 of file res_agi.c.

char usage_recordfile[] [static]
 

Definition at line 1574 of file res_agi.c.

char usage_recvchar[] [static]
 

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

char usage_sayalpha[] [static]
 

Definition at line 1515 of file res_agi.c.

char usage_saydate[] [static]
 

Definition at line 1522 of file res_agi.c.

char usage_saydatetime[] [static]
 

Definition at line 1538 of file res_agi.c.

char usage_saydigits[] [static]
 

Definition at line 1508 of file res_agi.c.

char usage_saynumber[] [static]
 

Definition at line 1501 of file res_agi.c.

char usage_sayphonetic[] [static]
 

Definition at line 1549 of file res_agi.c.

char usage_saytime[] [static]
 

Definition at line 1530 of file res_agi.c.

char usage_sendimage[] [static]
 

Definition at line 1470 of file res_agi.c.

char usage_sendtext[] [static]
 

Definition at line 1443 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 1417 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 1561 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 1565 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 1349 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 1569 of file res_agi.c.

char usage_setvariable[] [static]
 

Initial value:

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

Definition at line 1400 of file res_agi.c.

char usage_streamfile[] [static]
 

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

char usage_waitfordigit[] [static]
 

Definition at line 1436 of file res_agi.c.


Generated on Sat Mar 24 23:30:05 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6