Mon Sep 18 09:15:35 2006

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"

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().

#define RETRY   3

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

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01315 {
01316    if (argc != 2)
01317       return RESULT_SHOWUSAGE;
01318    agidebug = 1;
01319    ast_cli(fd, "AGI Debugging Enabled\n");
01320    return RESULT_SUCCESS;
01321 }

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

Definition at line 2059 of file res_agi.c.

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

Referenced by load_module().

02060 {
02061    if (chan->_softhangup)
02062       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02063    return agi_exec_full(chan, data, 0, 0);
02064 }

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

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

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

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

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

01818 {
01819    char *argv[MAX_ARGS];
01820    int argc = 0;
01821    int res;
01822    agi_command *c;
01823    argc = MAX_ARGS;
01824 
01825    parse_args(buf, &argc, argv);
01826    c = find_command(argv, 0);
01827    if (c) {
01828       res = c->handler(chan, agi, argc, argv);
01829       switch(res) {
01830       case RESULT_SHOWUSAGE:
01831          fdprintf(agi->fd, "520-Invalid command syntax.  Proper usage follows:\n");
01832          fdprintf(agi->fd, c->usage);
01833          fdprintf(agi->fd, "520 End of proper usage.\n");
01834          break;
01835       case AST_PBX_KEEPALIVE:
01836          /* We've been asked to keep alive, so do so */
01837          return AST_PBX_KEEPALIVE;
01838          break;
01839       case RESULT_FAILURE:
01840          /* They've already given the failure.  We've been hung up on so handle this
01841             appropriately */
01842          return -1;
01843       }
01844    } else {
01845       fdprintf(agi->fd, "510 Invalid or unknown command\n");
01846    }
01847    return 0;
01848 }

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

Definition at line 1323 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01324 {
01325    if (argc != 3)
01326       return RESULT_SHOWUSAGE;
01327    agidebug = 0;
01328    ast_cli(fd, "AGI Debugging Disabled\n");
01329    return RESULT_SUCCESS;
01330 }

int agi_register ( agi_command agi  ) 

Definition at line 1688 of file res_agi.c.

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

01689 {
01690    int x;
01691    for (x=0; x<MAX_COMMANDS - 1; x++) {
01692       if (commands[x].cmda[0] == agi->cmda[0]) {
01693          ast_log(LOG_WARNING, "Command already registered!\n");
01694          return -1;
01695       }
01696    }
01697    for (x=0; x<MAX_COMMANDS - 1; x++) {
01698       if (!commands[x].cmda[0]) {
01699          commands[x] = *agi;
01700          return 0;
01701       }
01702    }
01703    ast_log(LOG_WARNING, "No more room for new commands!\n");
01704    return -1;
01705 }

void agi_unregister ( agi_command agi  ) 

Definition at line 1707 of file res_agi.c.

References agi_command::cmda, and commands.

01708 {
01709    int x;
01710    for (x=0; x<MAX_COMMANDS - 1; x++) {
01711       if (commands[x].cmda[0] == agi->cmda[0]) {
01712          memset(&commands[x], 0, sizeof(agi_command));
01713       }
01714    }
01715 }

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

Definition at line 2087 of file res_agi.c.

References agi_exec_full(), and localuser::chan.

Referenced by load_module().

02088 {
02089    return agi_exec_full(chan, data, 0, 1);
02090 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 2132 of file res_agi.c.

02133 {
02134    return tdesc;
02135 }

static int eagi_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_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().

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

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

Definition at line 1717 of file res_agi.c.

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

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

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

Definition at line 367 of file res_agi.c.

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

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

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

Definition at line 1041 of file res_agi.c.

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

01042 {
01043    int timeout;
01044 
01045    if (argc != 3)
01046       return RESULT_SHOWUSAGE;
01047    if (sscanf(argv[2], "%d", &timeout) != 1)
01048       return RESULT_SHOWUSAGE;
01049    if (timeout < 0)
01050       timeout = 0;
01051    if (timeout)
01052       chan->whentohangup = time(NULL) + timeout;
01053    else
01054       chan->whentohangup = 0;
01055    fdprintf(agi->fd, "200 result=0\n");
01056    return RESULT_SUCCESS;
01057 }

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

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

01131 {
01132    struct ast_channel *c;
01133    if (argc == 2) {
01134       /* no argument: supply info on the current channel */
01135       fdprintf(agi->fd, "200 result=%d\n", chan->_state);
01136       return RESULT_SUCCESS;
01137    } else if (argc == 3) {
01138       /* one argument: look for info on the specified channel */
01139       c = ast_get_channel_by_name_locked(argv[2]);
01140       if (c) {
01141          fdprintf(agi->fd, "200 result=%d\n", c->_state);
01142          ast_mutex_unlock(&c->lock);
01143          return RESULT_SUCCESS;
01144       }
01145       /* if we get this far no channel name matched the argument given */
01146       fdprintf(agi->fd, "200 result=-1\n");
01147       return RESULT_SUCCESS;
01148    } else {
01149       return RESULT_SHOWUSAGE;
01150    }
01151 }

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

Definition at line 490 of file res_agi.c.

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

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

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

Definition at line 1274 of file res_agi.c.

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

01275 {
01276    int res;
01277 
01278    if (argc != 4)
01279       return RESULT_SHOWUSAGE;
01280    res = ast_db_del(argv[2], argv[3]);
01281    if (res) 
01282       fdprintf(agi->fd, "200 result=0\n");
01283    else
01284       fdprintf(agi->fd, "200 result=1\n");
01285 
01286    return RESULT_SUCCESS;
01287 }

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

Definition at line 1289 of file res_agi.c.

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

01290 {
01291    int res;
01292    if ((argc < 3) || (argc > 4))
01293       return RESULT_SHOWUSAGE;
01294    if (argc == 4)
01295       res = ast_db_deltree(argv[2], argv[3]);
01296    else
01297       res = ast_db_deltree(argv[2], NULL);
01298 
01299    if (res) 
01300       fdprintf(agi->fd, "200 result=0\n");
01301    else
01302       fdprintf(agi->fd, "200 result=1\n");
01303    return RESULT_SUCCESS;
01304 }

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

Definition at line 1243 of file res_agi.c.

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

01244 {
01245    int res;
01246    char tmp[256];
01247 
01248    if (argc != 4)
01249       return RESULT_SHOWUSAGE;
01250    res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
01251    if (res) 
01252       fdprintf(agi->fd, "200 result=0\n");
01253    else
01254       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01255 
01256    return RESULT_SUCCESS;
01257 }

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

Definition at line 1259 of file res_agi.c.

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

01260 {
01261    int res;
01262 
01263    if (argc != 5)
01264       return RESULT_SHOWUSAGE;
01265    res = ast_db_put(argv[2], argv[3], argv[4]);
01266    if (res) 
01267       fdprintf(agi->fd, "200 result=0\n");
01268    else
01269       fdprintf(agi->fd, "200 result=1\n");
01270 
01271    return RESULT_SUCCESS;
01272 }

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

Definition at line 1953 of file res_agi.c.

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

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

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

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

01086 {
01087    int res;
01088    struct ast_app *app;
01089 
01090    if (argc < 2)
01091       return RESULT_SHOWUSAGE;
01092 
01093    if (option_verbose > 2)
01094       ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]);
01095 
01096    app = pbx_findapp(argv[1]);
01097 
01098    if (app) {
01099       res = pbx_exec(chan, app, argv[2], 1);
01100    } else {
01101       ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
01102       res = -2;
01103    }
01104    fdprintf(agi->fd, "200 result=%d\n", res);
01105 
01106    return res;
01107 }

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

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

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

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

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

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

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

Definition at line 1162 of file res_agi.c.

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

01163 {
01164    char *ret;
01165    char tempstr[1024];
01166 
01167    if (argc != 3)
01168       return RESULT_SHOWUSAGE;
01169 
01170    /* check if we want to execute an ast_custom_function */
01171    if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
01172       ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr));
01173    } else {
01174       pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
01175    }
01176 
01177    if (ret)
01178       fdprintf(agi->fd, "200 result=1 (%s)\n", ret);
01179    else
01180       fdprintf(agi->fd, "200 result=0\n");
01181 
01182    return RESULT_SUCCESS;
01183 }

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

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

01186 {
01187    char tmp[4096] = "";
01188    struct ast_channel *chan2=NULL;
01189 
01190    if ((argc != 4) && (argc != 5))
01191       return RESULT_SHOWUSAGE;
01192    if (argc == 5) {
01193       chan2 = ast_get_channel_by_name_locked(argv[4]);
01194    } else {
01195       chan2 = chan;
01196    }
01197    if (chan) { /* XXX isn't this chan2 ? */
01198       pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1);
01199       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01200    } else {
01201       fdprintf(agi->fd, "200 result=0\n");
01202    }
01203    if (chan2 && (chan2 != chan))
01204       ast_mutex_unlock(&chan2->lock);
01205    return RESULT_SUCCESS;
01206 }

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

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

01060 {
01061    struct ast_channel *c;
01062    if (argc == 1) {
01063       /* no argument: hangup the current channel */
01064       ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
01065       fdprintf(agi->fd, "200 result=1\n");
01066       return RESULT_SUCCESS;
01067    } else if (argc == 2) {
01068       /* one argument: look for info on the specified channel */
01069       c = ast_get_channel_by_name_locked(argv[1]);
01070       if (c) {
01071          /* we have a matching channel */
01072          ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
01073          fdprintf(agi->fd, "200 result=1\n");
01074          ast_mutex_unlock(&c->lock);
01075          return RESULT_SUCCESS;
01076       }
01077       /* if we get this far no channel name matched the argument given */
01078       fdprintf(agi->fd, "200 result=-1\n");
01079       return RESULT_SUCCESS;
01080    } else {
01081       return RESULT_SHOWUSAGE;
01082    }
01083 }

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

Definition at line 1338 of file res_agi.c.

References agi_state::fd, fdprintf, and RESULT_SUCCESS.

01339 {
01340    fdprintf(agi->fd, "200 result=0\n");
01341    return RESULT_SUCCESS;
01342 }

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

Definition at line 866 of file res_agi.c.

References ast_applystream(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), ast_seekstream(), ast_set_read_format(), ast_stream_rewind(), ast_streamfile(), ast_tellstream(), ast_truncstream(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), 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.

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

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

Definition at line 418 of file res_agi.c.

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

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

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

Definition at line 438 of file res_agi.c.

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

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

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

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

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

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

Definition at line 712 of file res_agi.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 730 of file res_agi.c.

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

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

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

Definition at line 475 of file res_agi.c.

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

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

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

Definition at line 398 of file res_agi.c.

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

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

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

Definition at line 1109 of file res_agi.c.

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

01110 {
01111    char tmp[256]="";
01112    char *l = NULL, *n = NULL;
01113 
01114    if (argv[2]) {
01115       ast_copy_string(tmp, argv[2], sizeof(tmp));
01116       ast_callerid_parse(tmp, &n, &l);
01117       if (l)
01118          ast_shrink_phone_number(l);
01119       else
01120          l = "";
01121       if (!n)
01122          n = "";
01123       ast_set_callerid(chan, l, n, NULL);
01124    }
01125 
01126    fdprintf(agi->fd, "200 result=1\n");
01127    return RESULT_SUCCESS;
01128 }

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

Definition at line 831 of file res_agi.c.

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

00832 {
00833 
00834    if (argc != 3)
00835       return RESULT_SHOWUSAGE;
00836    ast_copy_string(chan->context, argv[2], sizeof(chan->context));
00837    fdprintf(agi->fd, "200 result=0\n");
00838    return RESULT_SUCCESS;
00839 }

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

Definition at line 841 of file res_agi.c.

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

00842 {
00843    if (argc != 3)
00844       return RESULT_SHOWUSAGE;
00845    ast_copy_string(chan->exten, argv[2], sizeof(chan->exten));
00846    fdprintf(agi->fd, "200 result=0\n");
00847    return RESULT_SUCCESS;
00848 }

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

Definition at line 1344 of file res_agi.c.

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

01345 {
01346    if (!strncasecmp(argv[2],"on",2)) {
01347       if (argc > 3)
01348          ast_moh_start(chan, argv[3]);
01349       else
01350          ast_moh_start(chan, NULL);
01351    }
01352    if (!strncasecmp(argv[2],"off",3)) {
01353       ast_moh_stop(chan);
01354    }
01355    fdprintf(agi->fd, "200 result=0\n");
01356    return RESULT_SUCCESS;
01357 }

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

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

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

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

Definition at line 1153 of file res_agi.c.

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

01154 {
01155    if (argv[3])
01156       pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
01157 
01158    fdprintf(agi->fd, "200 result=1\n");
01159    return RESULT_SUCCESS;
01160 }

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

Definition at line 1930 of file res_agi.c.

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

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

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

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

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

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

Definition at line 454 of file res_agi.c.

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

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

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

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

01209 {
01210    int level = 0;
01211    char *prefix;
01212 
01213    if (argc < 2)
01214       return RESULT_SHOWUSAGE;
01215 
01216    if (argv[2])
01217       sscanf(argv[2], "%d", &level);
01218 
01219    switch (level) {
01220       case 4:
01221          prefix = VERBOSE_PREFIX_4;
01222          break;
01223       case 3:
01224          prefix = VERBOSE_PREFIX_3;
01225          break;
01226       case 2:
01227          prefix = VERBOSE_PREFIX_2;
01228          break;
01229       case 1:
01230       default:
01231          prefix = VERBOSE_PREFIX_1;
01232          break;
01233    }
01234 
01235    if (level <= option_verbose)
01236       ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]);
01237    
01238    fdprintf(agi->fd, "200 result=1\n");
01239    
01240    return RESULT_SUCCESS;
01241 }

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

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

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

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

Definition at line 1662 of file res_agi.c.

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

01663 {
01664    char fullcmd[80];
01665    char matchstr[80];
01666    int x;
01667    struct agi_command *e;
01668    if (match)
01669       join(matchstr, sizeof(matchstr), match);
01670    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
01671       if (!commands[x].cmda[0]) break;
01672       e = &commands[x]; 
01673       if (e)
01674          join(fullcmd, sizeof(fullcmd), e->cmda);
01675       /* Hide commands that start with '_' */
01676       if (fullcmd[0] == '_')
01677          continue;
01678       if (match) {
01679          if (strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
01680             continue;
01681          }
01682       }
01683       ast_cli(fd, "%20.20s   %s\n", fullcmd, e->summary);
01684    }
01685    return 0;
01686 }

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

Definition at line 1646 of file res_agi.c.

01647 {
01648    int x;
01649 
01650    /* Join words into a string */
01651    if (!s) {
01652       return;
01653    }
01654    s[0] = '\0';
01655    for (x=0; w[x]; x++) {
01656       if (x)
01657          strncat(s, " ", len - strlen(s) - 1);
01658       strncat(s, w[x], len - strlen(s) - 1);
01659    }
01660 }

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 2144 of file res_agi.c.

References ASTERISK_GPL_KEY.

02145 {
02146    return ASTERISK_GPL_KEY;
02147 }

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

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

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

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

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 2121 of file res_agi.c.

References agi_exec(), ast_cli_register(), ast_register_application(), cli_debug, cli_no_debug, deadagi_exec(), dumpagihtml, eagi_exec(), and showagi.

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

Definition at line 1751 of file res_agi.c.

References ast_log(), LOG_WARNING, and MAX_ARGS.

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

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

Definition at line 1850 of file res_agi.c.

References agi_handle_command(), 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().

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

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

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

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

int unload_module ( void   ) 

Cleanup all module structures, sockets, etc.

Standard module functions ...

Definition at line 2109 of file res_agi.c.

References ast_cli_unregister(), ast_unregister_application(), cli_debug, cli_no_debug, dumpagihtml, 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 2137 of file res_agi.c.

References STANDARD_USECOUNT.

02138 {
02139    int res;
02140    STANDARD_USECOUNT(res);
02141    return res;
02142 }


Variable Documentation

int agidebug = 0 [static]

Definition at line 97 of file res_agi.c.

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 1332 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 1335 of file res_agi.c.

agi_command commands[MAX_COMMANDS] [static]

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

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

Definition at line 83 of file res_agi.c.

char debug_usage[] [static]

Initial value:

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

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

char* eapp = "EAGI" [static]

Definition at line 77 of file res_agi.c.

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

Definition at line 82 of file res_agi.c.

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 1310 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 2103 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 2092 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 1441 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 1596 of file res_agi.c.

char usage_channelstatus[] [static]

Definition at line 1413 of file res_agi.c.

char usage_controlstreamfile[] [static]

Definition at line 1497 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 1379 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 1385 of file res_agi.c.

char usage_dbget[] [static]

Definition at line 1371 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 1365 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 1431 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 1566 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 1507 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 1397 of file res_agi.c.

char usage_getvariablefull[] [static]

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

char usage_noop[] [static]

Initial value:

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

Definition at line 1602 of file res_agi.c.

char usage_recordfile[] [static]

Definition at line 1584 of file res_agi.c.

char usage_recvchar[] [static]

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

char usage_sayalpha[] [static]

Definition at line 1525 of file res_agi.c.

char usage_saydate[] [static]

Definition at line 1532 of file res_agi.c.

char usage_saydatetime[] [static]

Definition at line 1548 of file res_agi.c.

char usage_saydigits[] [static]

Definition at line 1518 of file res_agi.c.

char usage_saynumber[] [static]

Definition at line 1511 of file res_agi.c.

char usage_sayphonetic[] [static]

Definition at line 1559 of file res_agi.c.

char usage_saytime[] [static]

Definition at line 1540 of file res_agi.c.

char usage_sendimage[] [static]

Definition at line 1480 of file res_agi.c.

char usage_sendtext[] [static]

Definition at line 1453 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 1427 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 1571 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 1575 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 1359 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 1579 of file res_agi.c.

char usage_setvariable[] [static]

Initial value:

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

Definition at line 1410 of file res_agi.c.

char usage_streamfile[] [static]

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

char usage_waitfordigit[] [static]

Definition at line 1446 of file res_agi.c.


Generated on Mon Sep 18 09:15:37 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7