Wed Feb 11 12:00:30 2009

Asterisk developer's documentation


res_agi.c File Reference

AGI - the Asterisk Gateway Interface. More...

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

Go to the source code of this file.

Defines

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

Enumerations

enum  agi_result { AGI_RESULT_FAILURE = -1, AGI_RESULT_SUCCESS, AGI_RESULT_SUCCESS_FAST, AGI_RESULT_HANGUP }

Functions

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

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "Asterisk Gateway Interface (AGI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, }
static int agidebug = 0
static char * app = "AGI"
static const struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_agi []
static struct ast_cli_entry cli_agi_no_debug_deprecated
static struct ast_cli_entry cli_dump_agihtml_deprecated
static struct ast_cli_entry cli_show_agi_deprecated
static agi_command commands [MAX_COMMANDS]
static char * deadapp = "DeadAGI"
static char * deadsynopsis = "Executes AGI on a hungup channel"
static char debug_usage []
static char * descrip
static char dumpagihtml_help []
static char * eapp = "EAGI"
static char * esynopsis = "Executes an EAGI compliant application"
static char no_debug_usage []
static char showagi_help []
static char * synopsis = "Executes an AGI compliant application"
static char usage_answer []
static char usage_autohangup []
static char usage_channelstatus []
static char usage_controlstreamfile []
static char usage_dbdel []
static char usage_dbdeltree []
static char usage_dbget []
static char usage_dbput []
static char usage_exec []
static char usage_getdata []
static char usage_getoption []
static char usage_getvariable []
static char usage_getvariablefull []
static char usage_hangup []
static char usage_noop []
static char usage_recordfile []
static char usage_recvchar []
static char usage_recvtext []
static char usage_sayalpha []
static char usage_saydate []
static char usage_saydatetime []
static char usage_saydigits []
static char usage_saynumber []
static char usage_sayphonetic []
static char usage_saytime []
static char usage_sendimage []
static char usage_sendtext []
static char usage_setcallerid []
static char usage_setcontext []
static char usage_setextension []
static char usage_setmusic []
static char usage_setpriority []
static char usage_setvariable []
static char usage_streamfile []
static char usage_tddmode []
static char usage_verbose []
static char usage_waitfordigit []


Detailed Description

AGI - the Asterisk Gateway Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file res_agi.c.


Define Documentation

#define AGI_BUF_LEN   2048

Definition at line 72 of file res_agi.c.

Referenced by agi_exec_full(), and run_agi().

#define AGI_NANDFS_RETRY   3

Definition at line 71 of file res_agi.c.

Referenced by run_agi().

#define AGI_PORT   4573

Definition at line 113 of file res_agi.c.

Referenced by launch_netscript().

#define fdprintf   agi_debug_cli

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

Referenced by launch_netscript().

#define MAX_ARGS   128

Definition at line 69 of file res_agi.c.

#define MAX_COMMANDS   128

Definition at line 70 of file res_agi.c.

Referenced by ast_agi_register().

#define TONE_BLOCK_SIZE   200

Definition at line 108 of file res_agi.c.


Enumeration Type Documentation

enum agi_result

Enumerator:
AGI_RESULT_FAILURE 
AGI_RESULT_SUCCESS 
AGI_RESULT_SUCCESS_FAST 
AGI_RESULT_HANGUP 

Definition at line 115 of file res_agi.c.

00115                 {
00116    AGI_RESULT_FAILURE = -1,
00117    AGI_RESULT_SUCCESS,
00118    AGI_RESULT_SUCCESS_FAST,
00119    AGI_RESULT_HANGUP
00120 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 2226 of file res_agi.c.

static void __unreg_module ( void   )  [static]

Definition at line 2226 of file res_agi.c.

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

Definition at line 122 of file res_agi.c.

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

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

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

Definition at line 1341 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01342 {
01343    if (argc != 2)
01344       return RESULT_SHOWUSAGE;
01345    agidebug = 1;
01346    ast_cli(fd, "AGI Debugging Enabled\n");
01347    return RESULT_SUCCESS;
01348 }

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

Definition at line 2127 of file res_agi.c.

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

Referenced by load_module().

02128 {
02129    if (chan->_softhangup)
02130       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02131    return agi_exec_full(chan, data, 0, 0);
02132 }

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

Definition at line 2056 of file res_agi.c.

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

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

02057 {
02058    enum agi_result res;
02059    struct ast_module_user *u;
02060    char *argv[MAX_ARGS];
02061    char buf[AGI_BUF_LEN] = "";
02062    char *tmp = (char *)buf;
02063    int argc = 0;
02064    int fds[2];
02065    int efd = -1;
02066    int pid;
02067    char *stringp;
02068    AGI agi;
02069 
02070    if (ast_strlen_zero(data)) {
02071       ast_log(LOG_WARNING, "AGI requires an argument (script)\n");
02072       return -1;
02073    }
02074    ast_copy_string(buf, data, sizeof(buf));
02075 
02076    memset(&agi, 0, sizeof(agi));
02077         while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1)
02078       argv[argc++] = stringp;
02079    argv[argc] = NULL;
02080 
02081    u = ast_module_user_add(chan);
02082 #if 0
02083     /* Answer if need be */
02084         if (chan->_state != AST_STATE_UP) {
02085       if (ast_answer(chan)) {
02086          LOCAL_USER_REMOVE(u);
02087          return -1;
02088       }
02089    }
02090 #endif
02091    ast_replace_sigchld();
02092    res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid);
02093    if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) {
02094       int status = 0;
02095       agi.fd = fds[1];
02096       agi.ctrl = fds[0];
02097       agi.audio = efd;
02098       agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0;
02099       res = run_agi(chan, argv[0], &agi, pid, &status, dead);
02100       /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */
02101       if ((res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) && status)
02102          res = AGI_RESULT_FAILURE;
02103       if (fds[1] != fds[0])
02104          close(fds[1]);
02105       if (efd > -1)
02106          close(efd);
02107    }
02108    ast_unreplace_sigchld();
02109    ast_module_user_remove(u);
02110 
02111    switch (res) {
02112    case AGI_RESULT_SUCCESS:
02113    case AGI_RESULT_SUCCESS_FAST:
02114       pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS");
02115       break;
02116    case AGI_RESULT_FAILURE:
02117       pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE");
02118       break;
02119    case AGI_RESULT_HANGUP:
02120       pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP");
02121       return -1;
02122    }
02123 
02124    return 0;
02125 }

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

Definition at line 1823 of file res_agi.c.

References ast_cdr_setapp(), ast_check_hangup(), AST_PBX_KEEPALIVE, ast_channel::cdr, 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().

01824 {
01825    char *argv[MAX_ARGS];
01826    int argc = MAX_ARGS;
01827    int res;
01828    agi_command *c;
01829 
01830    parse_args(buf, &argc, argv);
01831    c = find_command(argv, 0);
01832    if (c) {
01833       /* If the AGI command being executed is an actual application (using agi exec)
01834       the app field will be updated in pbx_exec via handle_exec */
01835       if (chan->cdr && !ast_check_hangup(chan) && strcasecmp(argv[0], "EXEC"))
01836          ast_cdr_setapp(chan->cdr, "AGI", buf);
01837 
01838       res = c->handler(chan, agi, argc, argv);
01839       switch(res) {
01840       case RESULT_SHOWUSAGE:
01841          fdprintf(agi->fd, "520-Invalid command syntax.  Proper usage follows:\n");
01842          fdprintf(agi->fd, "%s", c->usage);
01843          fdprintf(agi->fd, "520 End of proper usage.\n");
01844          break;
01845       case AST_PBX_KEEPALIVE:
01846          /* We've been asked to keep alive, so do so */
01847          return AST_PBX_KEEPALIVE;
01848          break;
01849       case RESULT_FAILURE:
01850          /* They've already given the failure.  We've been hung up on so handle this
01851             appropriately */
01852          return -1;
01853       }
01854    } else {
01855       fdprintf(agi->fd, "510 Invalid or unknown command\n");
01856    }
01857    return 0;
01858 }

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

Definition at line 1359 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01360 {
01361    if (argc != 3)
01362       return RESULT_SHOWUSAGE;
01363    agidebug = 0;
01364    ast_cli(fd, "AGI Debugging Disabled\n");
01365    return RESULT_SUCCESS;
01366 }

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

Definition at line 1350 of file res_agi.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01351 {
01352    if (argc != 3)
01353       return RESULT_SHOWUSAGE;
01354    agidebug = 0;
01355    ast_cli(fd, "AGI Debugging Disabled\n");
01356    return RESULT_SUCCESS;
01357 }

int ast_agi_register ( agi_command agi  ) 

Definition at line 1694 of file res_agi.c.

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

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

void ast_agi_unregister ( agi_command agi  ) 

Definition at line 1713 of file res_agi.c.

References agi_command::cmda, and commands.

01714 {
01715    int x;
01716    for (x=0; x<MAX_COMMANDS - 1; x++) {
01717       if (commands[x].cmda[0] == agi->cmda[0]) {
01718          memset(&commands[x], 0, sizeof(agi_command));
01719       }
01720    }
01721 }

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

Definition at line 2155 of file res_agi.c.

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

Referenced by load_module().

02156 {
02157    if (!ast_check_hangup(chan))
02158       ast_log(LOG_WARNING,"Running DeadAGI on a live channel will cause problems, please use AGI\n");
02159    return agi_exec_full(chan, data, 0, 1);
02160 }

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

Definition at line 2134 of file res_agi.c.

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

Referenced by load_module().

02135 {
02136    int readformat;
02137    int res;
02138 
02139    if (chan->_softhangup)
02140       ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
02141    readformat = chan->readformat;
02142    if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
02143       ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
02144       return -1;
02145    }
02146    res = agi_exec_full(chan, data, 1, 0);
02147    if (!res) {
02148       if (ast_set_read_format(chan, readformat)) {
02149          ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
02150       }
02151    }
02152    return res;
02153 }

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

Definition at line 1723 of file res_agi.c.

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

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

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

Definition at line 2002 of file res_agi.c.

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

02003 {
02004    struct agi_command *e;
02005    char fullcmd[80];
02006    int x;
02007    FILE *htmlfile;
02008 
02009    if ((argc < 3))
02010       return RESULT_SHOWUSAGE;
02011 
02012    if (!(htmlfile = fopen(argv[2], "wt"))) {
02013       ast_cli(fd, "Could not create file '%s'\n", argv[2]);
02014       return RESULT_SHOWUSAGE;
02015    }
02016 
02017    fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n");
02018    fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n");
02019 
02020 
02021    fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n");
02022 
02023    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
02024       char *stringp, *tempstr;
02025 
02026       e = &commands[x]; 
02027       if (!e->cmda[0])  /* end ? */
02028          break;
02029       /* Hide commands that start with '_' */
02030       if ((e->cmda[0])[0] == '_')
02031          continue;
02032       ast_join(fullcmd, sizeof(fullcmd), e->cmda);
02033 
02034       fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n");
02035       fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TH></TR>\n", fullcmd,e->summary);
02036 
02037       stringp=e->usage;
02038       tempstr = strsep(&stringp, "\n");
02039 
02040       fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr);
02041       
02042       fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n");
02043       while ((tempstr = strsep(&stringp, "\n")) != NULL)
02044          fprintf(htmlfile, "%s<BR>\n",tempstr);
02045       fprintf(htmlfile, "</TD></TR>\n");
02046       fprintf(htmlfile, "</TABLE></TD></TR>\n\n");
02047 
02048    }
02049 
02050    fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n");
02051    fclose(htmlfile);
02052    ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]);
02053    return RESULT_SUCCESS;
02054 }

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

Definition at line 407 of file res_agi.c.

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

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

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

Definition at line 1056 of file res_agi.c.

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

01057 {
01058    int timeout;
01059 
01060    if (argc != 3)
01061       return RESULT_SHOWUSAGE;
01062    if (sscanf(argv[2], "%d", &timeout) != 1)
01063       return RESULT_SHOWUSAGE;
01064    if (timeout < 0)
01065       timeout = 0;
01066    if (timeout)
01067       chan->whentohangup = time(NULL) + timeout;
01068    else
01069       chan->whentohangup = 0;
01070    fdprintf(agi->fd, "200 result=0\n");
01071    return RESULT_SUCCESS;
01072 }

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

Definition at line 1149 of file res_agi.c.

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

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

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

Definition at line 518 of file res_agi.c.

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

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

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

Definition at line 1308 of file res_agi.c.

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

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

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

Definition at line 1319 of file res_agi.c.

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

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

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

Definition at line 1262 of file res_agi.c.

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

01263 {
01264    int res;
01265    size_t bufsize = 16;
01266    char *buf, *tmp;
01267 
01268    if (argc != 4)
01269       return RESULT_SHOWUSAGE;
01270 
01271    if (!(buf = ast_malloc(bufsize))) {
01272       fdprintf(agi->fd, "200 result=-1\n");
01273       return RESULT_SUCCESS;
01274    }
01275 
01276    do {
01277       res = ast_db_get(argv[2], argv[3], buf, bufsize);
01278       if (strlen(buf) < bufsize - 1) {
01279          break;
01280       }
01281       bufsize *= 2;
01282       if (!(tmp = ast_realloc(buf, bufsize))) {
01283          break;
01284       }
01285       buf = tmp;
01286    } while (1);
01287    
01288    if (res) 
01289       fdprintf(agi->fd, "200 result=0\n");
01290    else
01291       fdprintf(agi->fd, "200 result=1 (%s)\n", buf);
01292 
01293    ast_free(buf);
01294    return RESULT_SUCCESS;
01295 }

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

Definition at line 1297 of file res_agi.c.

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

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

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

Definition at line 1100 of file res_agi.c.

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

01101 {
01102    int res;
01103    struct ast_app *app;
01104 
01105    if (argc < 2)
01106       return RESULT_SHOWUSAGE;
01107 
01108    if (option_verbose > 2)
01109       ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]);
01110 
01111    app = pbx_findapp(argv[1]);
01112 
01113    if (app) {
01114       if(!strcasecmp(argv[1], PARK_APP_NAME)) {
01115          ast_masq_park_call(chan, NULL, 0, NULL);
01116       }
01117       res = pbx_exec(chan, app, argv[2]);
01118    } else {
01119       ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]);
01120       res = -2;
01121    }
01122    fdprintf(agi->fd, "200 result=%d\n", res);
01123 
01124    /* Even though this is wrong, users are depending upon this result. */
01125    return res;
01126 }

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

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

00816 {
00817    int res;
00818    char data[1024];
00819    int max;
00820    int timeout;
00821 
00822    if (argc < 3)
00823       return RESULT_SHOWUSAGE;
00824    if (argc >= 4)
00825       timeout = atoi(argv[3]); 
00826    else
00827       timeout = 0;
00828    if (argc >= 5) 
00829       max = atoi(argv[4]); 
00830    else
00831       max = 1024;
00832    res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
00833    if (res == 2)        /* New command */
00834       return RESULT_SUCCESS;
00835    else if (res == 1)
00836       fdprintf(agi->fd, "200 result=%s (timeout)\n", data);
00837    else if (res < 0 )
00838       fdprintf(agi->fd, "200 result=-1\n");
00839    else
00840       fdprintf(agi->fd, "200 result=%s\n", data);
00841    return RESULT_SUCCESS;
00842 }

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

Definition at line 616 of file res_agi.c.

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

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

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

Definition at line 1181 of file res_agi.c.

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

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

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

Definition at line 1204 of file res_agi.c.

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

01205 {
01206    char tmp[4096] = "";
01207    struct ast_channel *chan2=NULL;
01208 
01209    if ((argc != 4) && (argc != 5))
01210       return RESULT_SHOWUSAGE;
01211    if (argc == 5) {
01212       chan2 = ast_get_channel_by_name_locked(argv[4]);
01213    } else {
01214       chan2 = chan;
01215    }
01216    if (chan2) {
01217       pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1);
01218       fdprintf(agi->fd, "200 result=1 (%s)\n", tmp);
01219    } else {
01220       fdprintf(agi->fd, "200 result=0\n");
01221    }
01222    if (chan2 && (chan2 != chan))
01223       ast_channel_unlock(chan2);
01224    return RESULT_SUCCESS;
01225 }

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

Definition at line 1074 of file res_agi.c.

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

01075 {
01076    struct ast_channel *c;
01077    if (argc == 1) {
01078       /* no argument: hangup the current channel */
01079       ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT);
01080       fdprintf(agi->fd, "200 result=1\n");
01081       return RESULT_SUCCESS;
01082    } else if (argc == 2) {
01083       /* one argument: look for info on the specified channel */
01084       c = ast_get_channel_by_name_locked(argv[1]);
01085       if (c) {
01086          /* we have a matching channel */
01087          ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
01088          fdprintf(agi->fd, "200 result=1\n");
01089          ast_channel_unlock(c);
01090          return RESULT_SUCCESS;
01091       }
01092       /* if we get this far no channel name matched the argument given */
01093       fdprintf(agi->fd, "200 result=-1\n");
01094       return RESULT_SUCCESS;
01095    } else {
01096       return RESULT_SHOWUSAGE;
01097    }
01098 }

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

Definition at line 1368 of file res_agi.c.

References agi_state::fd, fdprintf, and RESULT_SUCCESS.

01369 {
01370    fdprintf(agi->fd, "200 result=0\n");
01371    return RESULT_SUCCESS;
01372 }

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

Definition at line 879 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_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), f, agi_state::fd, fdprintf, ast_channel::language, LOG_WARNING, ast_channel::name, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, and ast_dsp::totalsilence.

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

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

Definition at line 449 of file res_agi.c.

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

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

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

Definition at line 469 of file res_agi.c.

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

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

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

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

00724 {
00725    int res;
00726 
00727    if (argc != 4)
00728       return RESULT_SHOWUSAGE;
00729 
00730    res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00731    if (res == 1) /* New command */
00732       return RESULT_SUCCESS;
00733    fdprintf(agi->fd, "200 result=%d\n", res);
00734    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00735 }

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

Definition at line 737 of file res_agi.c.

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

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

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

Definition at line 767 of file res_agi.c.

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

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

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

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

00707 {
00708    int res;
00709    int num;
00710 
00711    if (argc != 4)
00712       return RESULT_SHOWUSAGE;
00713    if (sscanf(argv[2], "%d", &num) != 1)
00714       return RESULT_SHOWUSAGE;
00715 
00716    res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00717    if (res == 1) /* New command */
00718       return RESULT_SUCCESS;
00719    fdprintf(agi->fd, "200 result=%d\n", res);
00720    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00721 }

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

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

00692 {
00693    int res;
00694    int num;
00695    if (argc != 4)
00696       return RESULT_SHOWUSAGE;
00697    if (sscanf(argv[2], "%d", &num) != 1)
00698       return RESULT_SHOWUSAGE;
00699    res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl);
00700    if (res == 1)
00701       return RESULT_SUCCESS;
00702    fdprintf(agi->fd, "200 result=%d\n", res);
00703    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00704 }

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

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

00802 {
00803    int res;
00804 
00805    if (argc != 4)
00806       return RESULT_SHOWUSAGE;
00807 
00808    res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
00809    if (res == 1) /* New command */
00810       return RESULT_SUCCESS;
00811    fdprintf(agi->fd, "200 result=%d\n", res);
00812    return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
00813 }

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

Definition at line 752 of file res_agi.c.

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

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

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

Definition at line 506 of file res_agi.c.

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

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

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

Definition at line 432 of file res_agi.c.

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

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

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

Definition at line 1128 of file res_agi.c.

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

01129 {
01130    char tmp[256]="";
01131    char *l = NULL, *n = NULL;
01132 
01133    if (argv[2]) {
01134       ast_copy_string(tmp, argv[2], sizeof(tmp));
01135       ast_callerid_parse(tmp, &n, &l);
01136       if (l)
01137          ast_shrink_phone_number(l);
01138       else
01139          l = "";
01140       if (!n)
01141          n = "";
01142       ast_set_callerid(chan, l, n, NULL);
01143    }
01144 
01145    fdprintf(agi->fd, "200 result=1\n");
01146    return RESULT_SUCCESS;
01147 }

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

Definition at line 844 of file res_agi.c.

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

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

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

Definition at line 854 of file res_agi.c.

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

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

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

Definition at line 1374 of file res_agi.c.

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

01375 {
01376    if (!strncasecmp(argv[2], "on", 2))
01377       ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
01378    else if (!strncasecmp(argv[2], "off", 3))
01379       ast_moh_stop(chan);
01380    fdprintf(agi->fd, "200 result=0\n");
01381    return RESULT_SUCCESS;
01382 }

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

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

00864 {
00865    int pri;
00866    if (argc != 3)
00867       return RESULT_SHOWUSAGE;   
00868 
00869    if (sscanf(argv[2], "%d", &pri) != 1) {
00870       if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
00871          return RESULT_SHOWUSAGE;
00872    }
00873 
00874    ast_explicit_goto(chan, NULL, NULL, pri);
00875    fdprintf(agi->fd, "200 result=0\n");
00876    return RESULT_SUCCESS;
00877 }

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

Definition at line 1172 of file res_agi.c.

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

01173 {
01174    if (argv[3])
01175       pbx_builtin_setvar_helper(chan, argv[2], argv[3]);
01176 
01177    fdprintf(agi->fd, "200 result=1\n");
01178    return RESULT_SUCCESS;
01179 }

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

Definition at line 1978 of file res_agi.c.

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

01979 {
01980    struct agi_command *e;
01981    char fullcmd[80];
01982    if ((argc < 2))
01983       return RESULT_SHOWUSAGE;
01984    if (argc > 2) {
01985       e = find_command(argv + 2, 1);
01986       if (e) 
01987          ast_cli(fd, "%s", e->usage);
01988       else {
01989          if (find_command(argv + 2, -1)) {
01990             return help_workhorse(fd, argv + 1);
01991          } else {
01992             ast_join(fullcmd, sizeof(fullcmd), argv+1);
01993             ast_cli(fd, "No such command '%s'.\n", fullcmd);
01994          }
01995       }
01996    } else {
01997       return help_workhorse(fd, NULL);
01998    }
01999    return RESULT_SUCCESS;
02000 }

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

Definition at line 560 of file res_agi.c.

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

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

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

Definition at line 485 of file res_agi.c.

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

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

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

Definition at line 1227 of file res_agi.c.

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

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

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

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

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

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

Definition at line 1671 of file res_agi.c.

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

01672 {
01673    char fullcmd[80];
01674    char matchstr[80];
01675    int x;
01676    struct agi_command *e;
01677    if (match)
01678       ast_join(matchstr, sizeof(matchstr), match);
01679    for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) {
01680       e = &commands[x]; 
01681       if (!e->cmda[0])
01682          break;
01683       /* Hide commands that start with '_' */
01684       if ((e->cmda[0])[0] == '_')
01685          continue;
01686       ast_join(fullcmd, sizeof(fullcmd), e->cmda);
01687       if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr)))
01688          continue;
01689       ast_cli(fd, "%20.20s   %s\n", fullcmd, e->summary);
01690    }
01691    return 0;
01692 }

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

Definition at line 145 of file res_agi.c.

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

Referenced by launch_script().

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

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

Definition at line 240 of file res_agi.c.

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

Referenced by agi_exec_full().

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

static int load_module ( void   )  [static]

Definition at line 2215 of file res_agi.c.

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

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

Definition at line 1757 of file res_agi.c.

References ast_log(), LOG_WARNING, and MAX_ARGS.

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

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

Definition at line 1859 of file res_agi.c.

References AGI_BUF_LEN, agi_handle_command(), AGI_NANDFS_RETRY, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ast_false(), AST_FRAME_VOICE, ast_frfree, ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_strlen_zero(), ast_verbose(), ast_waitfor_nandfds(), agi_state::audio, agi_state::ctrl, errno, f, agi_state::fast, agi_state::fd, len(), LOG_DEBUG, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_getvar_helper(), setup_env(), and VERBOSE_PREFIX_3.

Referenced by agi_exec_full().

01860 {
01861    struct ast_channel *c;
01862    int outfd;
01863    int ms;
01864    enum agi_result returnstatus = AGI_RESULT_SUCCESS;
01865    struct ast_frame *f;
01866    char buf[AGI_BUF_LEN];
01867    char *res = NULL;
01868    FILE *readf;
01869    /* how many times we'll retry if ast_waitfor_nandfs will return without either 
01870      channel or file descriptor in case select is interrupted by a system call (EINTR) */
01871    int retry = AGI_NANDFS_RETRY;
01872 
01873    if (!(readf = fdopen(agi->ctrl, "r"))) {
01874       ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n");
01875       if (pid > -1)
01876          kill(pid, SIGHUP);
01877       close(agi->ctrl);
01878       return AGI_RESULT_FAILURE;
01879    }
01880    setlinebuf(readf);
01881    setup_env(chan, request, agi->fd, (agi->audio > -1));
01882    for (;;) {
01883       ms = -1;
01884       c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
01885       if (c) {
01886          retry = AGI_NANDFS_RETRY;
01887          /* Idle the channel until we get a command */
01888          f = ast_read(c);
01889          if (!f) {
01890             ast_log(LOG_DEBUG, "%s hungup\n", chan->name);
01891             returnstatus = AGI_RESULT_HANGUP;
01892             break;
01893          } else {
01894             /* If it's voice, write it to the audio pipe */
01895             if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) {
01896                /* Write, ignoring errors */
01897                if (write(agi->audio, f->data, f->datalen) < 0) {
01898                }
01899             }
01900             ast_frfree(f);
01901          }
01902       } else if (outfd > -1) {
01903          size_t len = sizeof(buf);
01904          size_t buflen = 0;
01905 
01906          retry = AGI_NANDFS_RETRY;
01907          buf[0] = '\0';
01908 
01909          while (buflen < (len - 1)) {
01910             res = fgets(buf + buflen, len, readf);
01911             if (feof(readf)) 
01912                break;
01913             if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN))) 
01914                break;
01915             if (res != NULL && !agi->fast)
01916                break;
01917             buflen = strlen(buf);
01918             if (buflen && buf[buflen - 1] == '\n')
01919                break;
01920             len -= buflen;
01921             if (agidebug)
01922                ast_verbose( "AGI Rx << temp buffer %s - errno %s\n", buf, strerror(errno));
01923          }
01924 
01925          if (!buf[0]) {
01926             /* Program terminated */
01927             if (returnstatus)
01928                returnstatus = -1;
01929             if (option_verbose > 2) 
01930                ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus);
01931             if (pid > 0)
01932                waitpid(pid, status, 0);
01933             /* No need to kill the pid anymore, since they closed us */
01934             pid = -1;
01935             break;
01936          }
01937 
01938          /* Special case for inability to execute child process */
01939          if (*buf && strncasecmp(buf, "failure", 7) == 0) {
01940             returnstatus = AGI_RESULT_FAILURE;
01941             break;
01942          }
01943 
01944          /* get rid of trailing newline, if any */
01945          if (*buf && buf[strlen(buf) - 1] == '\n')
01946             buf[strlen(buf) - 1] = 0;
01947          if (agidebug)
01948             ast_verbose("AGI Rx << %s\n", buf);
01949          returnstatus |= agi_handle_command(chan, agi, buf);
01950          /* If the handle_command returns -1, we need to stop */
01951          if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
01952             break;
01953          }
01954       } else {
01955          if (--retry <= 0) {
01956             ast_log(LOG_WARNING, "No channel, no fd?\n");
01957             returnstatus = AGI_RESULT_FAILURE;
01958             break;
01959          }
01960       }
01961    }
01962    /* Notify process */
01963    if (pid > -1) {
01964       const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
01965       if (ast_strlen_zero(sighup) || !ast_false(sighup)) {
01966          if (kill(pid, SIGHUP)) {
01967             ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno));
01968          } else { /* Give the process a chance to die */
01969             usleep(1);
01970          }
01971       }
01972       waitpid(pid, status, WNOHANG);
01973    }
01974    fclose(readf);
01975    return returnstatus;
01976 }

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

Definition at line 374 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, S_OR, ast_channel::tech, ast_channel_tech::type, and ast_channel::uniqueid.

Referenced by run_agi().

00375 {
00376    /* Print initial environment, with agi_request always being the first
00377       thing */
00378    fdprintf(fd, "agi_request: %s\n", request);
00379    fdprintf(fd, "agi_channel: %s\n", chan->name);
00380    fdprintf(fd, "agi_language: %s\n", chan->language);
00381    fdprintf(fd, "agi_type: %s\n", chan->tech->type);
00382    fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid);
00383 
00384    /* ANI/DNIS */
00385    fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown"));
00386    fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown"));
00387    fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres);
00388    fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2);
00389    fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton);
00390    fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns);
00391    fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown"));
00392    fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown"));
00393 
00394    /* Context information */
00395    fdprintf(fd, "agi_context: %s\n", chan->context);
00396    fdprintf(fd, "agi_extension: %s\n", chan->exten);
00397    fdprintf(fd, "agi_priority: %d\n", chan->priority);
00398    fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
00399 
00400    /* User information */
00401    fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
00402     
00403    /* End with empty return */
00404    fdprintf(fd, "\n");
00405 }

static int unload_module ( void   )  [static]

Definition at line 2206 of file res_agi.c.

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


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "Asterisk Gateway Interface (AGI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static]

Definition at line 2226 of file res_agi.c.

int agidebug = 0 [static]

Definition at line 106 of file res_agi.c.

char* app = "AGI" [static]

Definition at line 77 of file res_agi.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 2226 of file res_agi.c.

struct ast_cli_entry cli_agi[] [static]

Definition at line 2188 of file res_agi.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_agi_no_debug_deprecated [static]

Initial value:

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

Definition at line 2183 of file res_agi.c.

struct ast_cli_entry cli_dump_agihtml_deprecated [static]

Initial value:

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

Definition at line 2178 of file res_agi.c.

struct ast_cli_entry cli_show_agi_deprecated [static]

Initial value:

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

Definition at line 2173 of file res_agi.c.

agi_command commands[MAX_COMMANDS] [static]

Definition at line 1631 of file res_agi.c.

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

char* deadapp = "DeadAGI" [static]

Definition at line 81 of file res_agi.c.

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

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

char* descrip [static]

Definition at line 87 of file res_agi.c.

char dumpagihtml_help[] [static]

Initial value:

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

Definition at line 2169 of file res_agi.c.

char* eapp = "EAGI" [static]

Definition at line 79 of file res_agi.c.

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

Definition at line 84 of file res_agi.c.

char no_debug_usage[] [static]

Initial value:

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

Definition at line 1337 of file res_agi.c.

char showagi_help[] [static]

Initial value:

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

Definition at line 2162 of file res_agi.c.

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

Definition at line 83 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 1466 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 1621 of file res_agi.c.

char usage_channelstatus[] [static]

Definition at line 1438 of file res_agi.c.

char usage_controlstreamfile[] [static]

Definition at line 1522 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 1404 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 1410 of file res_agi.c.

char usage_dbget[] [static]

Definition at line 1396 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 1390 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 1456 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 1591 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 1532 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 1422 of file res_agi.c.

char usage_getvariablefull[] [static]

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

char usage_noop[] [static]

Initial value:

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

Definition at line 1627 of file res_agi.c.

char usage_recordfile[] [static]

Definition at line 1609 of file res_agi.c.

char usage_recvchar[] [static]

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

char usage_sayalpha[] [static]

Definition at line 1550 of file res_agi.c.

char usage_saydate[] [static]

Definition at line 1557 of file res_agi.c.

char usage_saydatetime[] [static]

Definition at line 1573 of file res_agi.c.

char usage_saydigits[] [static]

Definition at line 1543 of file res_agi.c.

char usage_saynumber[] [static]

Definition at line 1536 of file res_agi.c.

char usage_sayphonetic[] [static]

Definition at line 1584 of file res_agi.c.

char usage_saytime[] [static]

Definition at line 1565 of file res_agi.c.

char usage_sendimage[] [static]

Definition at line 1505 of file res_agi.c.

char usage_sendtext[] [static]

Definition at line 1478 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 1452 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 1596 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 1600 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 1384 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 1604 of file res_agi.c.

char usage_setvariable[] [static]

Initial value:

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

Definition at line 1435 of file res_agi.c.

char usage_streamfile[] [static]

Definition at line 1512 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 1500 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 1416 of file res_agi.c.

char usage_waitfordigit[] [static]

Definition at line 1471 of file res_agi.c.


Generated on Wed Feb 11 12:00:30 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7