#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/stat.h>
#include <sys/wait.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/astdb.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/options.h"
#include "asterisk/image.h"
#include "asterisk/say.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/strings.h"
#include "asterisk/agi.h"
Include dependency graph for res_agi.c:
Go to the source code of this file.
Defines | |
#define | AGI_PORT 4573 |
#define | fdprintf agi_debug_cli |
#define | MAX_AGI_CONNECT 2000 |
#define | MAX_ARGS 128 |
#define | MAX_COMMANDS 128 |
#define | RETRY 3 |
#define | TONE_BLOCK_SIZE 200 |
Enumerations | |
enum | agi_result { AGI_RESULT_SUCCESS, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP } |
Functions | |
static int | agi_debug_cli (int fd, char *fmt,...) |
static int | agi_do_debug (int fd, int argc, char *argv[]) |
static int | agi_exec (struct ast_channel *chan, void *data) |
static int | agi_exec_full (struct ast_channel *chan, void *data, int enhanced, int dead) |
static int | agi_handle_command (struct ast_channel *chan, AGI *agi, char *buf) |
static int | agi_no_debug (int fd, int argc, char *argv[]) |
static int | agi_no_debug_deprecated (int fd, int argc, char *argv[]) |
int | ast_agi_register (agi_command *agi) |
void | ast_agi_unregister (agi_command *agi) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Asterisk Gateway Interface (AGI)",.load=load_module,.unload=unload_module,) | |
static int | deadagi_exec (struct ast_channel *chan, void *data) |
static int | eagi_exec (struct ast_channel *chan, void *data) |
static agi_command * | find_command (char *cmds[], int exact) |
static int | handle_agidumphtml (int fd, int argc, char *argv[]) |
static int | handle_answer (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_autohangup (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_channelstatus (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_controlstreamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_dbdel (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_dbdeltree (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_dbget (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_dbput (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_exec (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_getdata (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_getoption (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_getvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_getvariablefull (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_hangup (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_noop (struct ast_channel *chan, AGI *agi, int arg, char *argv[]) |
static int | handle_recordfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_recvchar (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_recvtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sayalpha (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saydate (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saydatetime (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saydigits (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saynumber (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sayphonetic (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saytime (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sendimage (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sendtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_setcallerid (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_setcontext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_setextension (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_setmusic (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_setpriority (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_setvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_showagi (int fd, int argc, char *argv[]) |
static int | handle_streamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_tddmode (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_verbose (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_waitfordigit (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | help_workhorse (int fd, char *match[]) |
static enum agi_result | launch_netscript (char *agiurl, char *argv[], int *fds, int *efd, int *opid) |
static enum agi_result | launch_script (char *script, char *argv[], int *fds, int *efd, int *opid) |
static int | load_module (void) |
static int | parse_args (char *s, int *max, char *argv[]) |
static enum agi_result | run_agi (struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead, int argc, char *argv[]) |
static void | setup_env (struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]) |
static int | unload_module (void) |
Variables | |
static int | agidebug = 0 |
static char * | app = "AGI" |
static struct ast_cli_entry | cli_agi [] |
static 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 [] |
Definition in file res_agi.c.
#define AGI_PORT 4573 |
#define fdprintf agi_debug_cli |
Definition at line 73 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 |
#define MAX_COMMANDS 128 |
enum agi_result |
Definition at line 113 of file res_agi.c.
00113 { 00114 AGI_RESULT_SUCCESS, 00115 AGI_RESULT_FAILURE, 00116 AGI_RESULT_HANGUP 00117 };
static int agi_debug_cli | ( | int | fd, | |
char * | fmt, | |||
... | ||||
) | [static] |
Definition at line 119 of file res_agi.c.
References ast_carefulwrite(), ast_log(), ast_verbose(), free, LOG_ERROR, ast_variable::stuff, and vasprintf.
00120 { 00121 char *stuff; 00122 int res = 0; 00123 00124 va_list ap; 00125 va_start(ap, fmt); 00126 res = vasprintf(&stuff, fmt, ap); 00127 va_end(ap); 00128 if (res == -1) { 00129 ast_log(LOG_ERROR, "Out of memory\n"); 00130 } else { 00131 if (agidebug) 00132 ast_verbose("AGI Tx >> %s", stuff); /* \n provided by caller */ 00133 res = ast_carefulwrite(fd, stuff, strlen(stuff), 100); 00134 free(stuff); 00135 } 00136 00137 return res; 00138 }
static int agi_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1332 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01333 { 01334 if (argc != 2) 01335 return RESULT_SHOWUSAGE; 01336 agidebug = 1; 01337 ast_cli(fd, "AGI Debugging Enabled\n"); 01338 return RESULT_SUCCESS; 01339 }
static int agi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2078 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().
02079 { 02080 if (chan->_softhangup) 02081 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02082 return agi_exec_full(chan, data, 0, 0); 02083 }
static int agi_exec_full | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | enhanced, | |||
int | dead | |||
) | [static] |
Definition at line 2010 of file res_agi.c.
References ast_channel::_state, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strlen_zero(), ast_unreplace_sigchld(), ast_module_user::chan, launch_script(), LOG_WARNING, MAX_ARGS, pbx_builtin_setvar_helper(), run_agi(), and strsep().
Referenced by agi_exec(), deadagi_exec(), and eagi_exec().
02011 { 02012 enum agi_result res; 02013 struct ast_module_user *u; 02014 char *argv[MAX_ARGS]; 02015 char buf[2048]=""; 02016 char *tmp = (char *)buf; 02017 int argc = 0; 02018 int fds[2]; 02019 int efd = -1; 02020 int pid; 02021 char *stringp; 02022 AGI agi; 02023 02024 if (ast_strlen_zero(data)) { 02025 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02026 return -1; 02027 } 02028 ast_copy_string(buf, data, sizeof(buf)); 02029 02030 memset(&agi, 0, sizeof(agi)); 02031 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1) 02032 argv[argc++] = stringp; 02033 argv[argc] = NULL; 02034 02035 u = ast_module_user_add(chan); 02036 #if 0 02037 /* Answer if need be */ 02038 if (chan->_state != AST_STATE_UP) { 02039 if (ast_answer(chan)) { 02040 LOCAL_USER_REMOVE(u); 02041 return -1; 02042 } 02043 } 02044 #endif 02045 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); 02046 if (res == AGI_RESULT_SUCCESS) { 02047 int status = 0; 02048 agi.fd = fds[1]; 02049 agi.ctrl = fds[0]; 02050 agi.audio = efd; 02051 res = run_agi(chan, argv[0], &agi, pid, &status, dead, argc, argv); 02052 /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */ 02053 if (res == AGI_RESULT_SUCCESS && status) 02054 res = AGI_RESULT_FAILURE; 02055 if (fds[1] != fds[0]) 02056 close(fds[1]); 02057 if (efd > -1) 02058 close(efd); 02059 ast_unreplace_sigchld(); 02060 } 02061 ast_module_user_remove(u); 02062 02063 switch (res) { 02064 case AGI_RESULT_SUCCESS: 02065 pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS"); 02066 break; 02067 case AGI_RESULT_FAILURE: 02068 pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE"); 02069 break; 02070 case AGI_RESULT_HANGUP: 02071 pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP"); 02072 return -1; 02073 } 02074 02075 return 0; 02076 }
static int agi_handle_command | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
char * | buf | |||
) | [static] |
Definition at line 1814 of file res_agi.c.
References AST_PBX_KEEPALIVE, agi_state::fd, fdprintf, find_command(), agi_command::handler, MAX_ARGS, parse_args(), RESULT_FAILURE, RESULT_SHOWUSAGE, and agi_command::usage.
Referenced by run_agi().
01815 { 01816 char *argv[MAX_ARGS]; 01817 int argc = MAX_ARGS; 01818 int res; 01819 agi_command *c; 01820 01821 parse_args(buf, &argc, argv); 01822 c = find_command(argv, 0); 01823 if (c) { 01824 res = c->handler(chan, agi, argc, argv); 01825 switch(res) { 01826 case RESULT_SHOWUSAGE: 01827 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01828 fdprintf(agi->fd, c->usage); 01829 fdprintf(agi->fd, "520 End of proper usage.\n"); 01830 break; 01831 case AST_PBX_KEEPALIVE: 01832 /* We've been asked to keep alive, so do so */ 01833 return AST_PBX_KEEPALIVE; 01834 break; 01835 case RESULT_FAILURE: 01836 /* They've already given the failure. We've been hung up on so handle this 01837 appropriately */ 01838 return -1; 01839 } 01840 } else { 01841 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01842 } 01843 return 0; 01844 }
static int agi_no_debug | ( | 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 }
static int agi_no_debug_deprecated | ( | 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 != 3) 01344 return RESULT_SHOWUSAGE; 01345 agidebug = 0; 01346 ast_cli(fd, "AGI Debugging Disabled\n"); 01347 return RESULT_SUCCESS; 01348 }
int ast_agi_register | ( | agi_command * | agi | ) |
Definition at line 1685 of file res_agi.c.
References ast_log(), agi_command::cmda, commands, LOG_WARNING, and MAX_COMMANDS.
01686 { 01687 int x; 01688 for (x=0; x<MAX_COMMANDS - 1; x++) { 01689 if (commands[x].cmda[0] == agi->cmda[0]) { 01690 ast_log(LOG_WARNING, "Command already registered!\n"); 01691 return -1; 01692 } 01693 } 01694 for (x=0; x<MAX_COMMANDS - 1; x++) { 01695 if (!commands[x].cmda[0]) { 01696 commands[x] = *agi; 01697 return 0; 01698 } 01699 } 01700 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01701 return -1; 01702 }
void ast_agi_unregister | ( | agi_command * | agi | ) |
Definition at line 1704 of file res_agi.c.
References agi_command::cmda, and commands.
01705 { 01706 int x; 01707 for (x=0; x<MAX_COMMANDS - 1; x++) { 01708 if (commands[x].cmda[0] == agi->cmda[0]) { 01709 memset(&commands[x], 0, sizeof(agi_command)); 01710 } 01711 } 01712 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_GLOBAL_SYMBOLS | , | |||
"Asterisk Gateway Interface (AGI)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module | |||
) |
static int deadagi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2106 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().
02107 { 02108 if (!ast_check_hangup(chan)) 02109 ast_log(LOG_WARNING,"Running DeadAGI on a live channel will cause problems, please use AGI\n"); 02110 return agi_exec_full(chan, data, 0, 1); 02111 }
static int eagi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2085 of file res_agi.c.
References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), ast_module_user::chan, LOG_WARNING, and ast_channel::readformat.
Referenced by load_module().
02086 { 02087 int readformat; 02088 int res; 02089 02090 if (chan->_softhangup) 02091 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02092 readformat = chan->readformat; 02093 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02094 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02095 return -1; 02096 } 02097 res = agi_exec_full(chan, data, 1, 0); 02098 if (!res) { 02099 if (ast_set_read_format(chan, readformat)) { 02100 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02101 } 02102 } 02103 return res; 02104 }
static agi_command* find_command | ( | char * | cmds[], | |
int | exact | |||
) | [static] |
Definition at line 1714 of file res_agi.c.
References agi_command::cmda, commands, and match().
01715 { 01716 int x; 01717 int y; 01718 int match; 01719 01720 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01721 if (!commands[x].cmda[0]) 01722 break; 01723 /* start optimistic */ 01724 match = 1; 01725 for (y=0; match && cmds[y]; y++) { 01726 /* If there are no more words in the command (and we're looking for 01727 an exact match) or there is a difference between the two words, 01728 then this is not a match */ 01729 if (!commands[x].cmda[y] && !exact) 01730 break; 01731 /* don't segfault if the next part of a command doesn't exist */ 01732 if (!commands[x].cmda[y]) 01733 return NULL; 01734 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01735 match = 0; 01736 } 01737 /* If more words are needed to complete the command then this is not 01738 a candidate (unless we're looking for a really inexact answer */ 01739 if ((exact > -1) && commands[x].cmda[y]) 01740 match = 0; 01741 if (match) 01742 return &commands[x]; 01743 } 01744 return NULL; 01745 }
static int handle_agidumphtml | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1956 of file res_agi.c.
References ast_cli(), ast_join(), agi_command::cmda, commands, RESULT_SHOWUSAGE, RESULT_SUCCESS, strsep(), agi_command::summary, and agi_command::usage.
01957 { 01958 struct agi_command *e; 01959 char fullcmd[80]; 01960 int x; 01961 FILE *htmlfile; 01962 01963 if ((argc < 3)) 01964 return RESULT_SHOWUSAGE; 01965 01966 if (!(htmlfile = fopen(argv[2], "wt"))) { 01967 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 01968 return RESULT_SHOWUSAGE; 01969 } 01970 01971 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 01972 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 01973 01974 01975 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 01976 01977 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01978 char *stringp, *tempstr; 01979 01980 e = &commands[x]; 01981 if (!e->cmda[0]) /* end ? */ 01982 break; 01983 /* Hide commands that start with '_' */ 01984 if ((e->cmda[0])[0] == '_') 01985 continue; 01986 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01987 01988 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 01989 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TH></TR>\n", fullcmd,e->summary); 01990 01991 stringp=e->usage; 01992 tempstr = strsep(&stringp, "\n"); 01993 01994 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 01995 01996 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 01997 while ((tempstr = strsep(&stringp, "\n")) != NULL) 01998 fprintf(htmlfile, "%s<BR>\n",tempstr); 01999 fprintf(htmlfile, "</TD></TR>\n"); 02000 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 02001 02002 } 02003 02004 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 02005 fclose(htmlfile); 02006 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 02007 return RESULT_SUCCESS; 02008 }
static int handle_answer | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 420 of file res_agi.c.
References ast_channel::_state, ast_answer(), AST_STATE_UP, agi_state::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS.
00421 { 00422 int res; 00423 res = 0; 00424 if (chan->_state != AST_STATE_UP) { 00425 /* Answer the chan */ 00426 res = ast_answer(chan); 00427 } 00428 fdprintf(agi->fd, "200 result=%d\n", res); 00429 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00430 }
static int handle_autohangup | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1069 of file res_agi.c.
References agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, timeout, and ast_channel::whentohangup.
01070 { 01071 int timeout; 01072 01073 if (argc != 3) 01074 return RESULT_SHOWUSAGE; 01075 if (sscanf(argv[2], "%d", &timeout) != 1) 01076 return RESULT_SHOWUSAGE; 01077 if (timeout < 0) 01078 timeout = 0; 01079 if (timeout) 01080 chan->whentohangup = time(NULL) + timeout; 01081 else 01082 chan->whentohangup = 0; 01083 fdprintf(agi->fd, "200 result=0\n"); 01084 return RESULT_SUCCESS; 01085 }
static int handle_channelstatus | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1159 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.
01160 { 01161 struct ast_channel *c; 01162 if (argc == 2) { 01163 /* no argument: supply info on the current channel */ 01164 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01165 return RESULT_SUCCESS; 01166 } else if (argc == 3) { 01167 /* one argument: look for info on the specified channel */ 01168 c = ast_get_channel_by_name_locked(argv[2]); 01169 if (c) { 01170 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01171 ast_channel_unlock(c); 01172 return RESULT_SUCCESS; 01173 } 01174 /* if we get this far no channel name matched the argument given */ 01175 fdprintf(agi->fd, "200 result=-1\n"); 01176 return RESULT_SUCCESS; 01177 } else { 01178 return RESULT_SHOWUSAGE; 01179 } 01180 }
static int handle_controlstreamfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 531 of file res_agi.c.
References ast_control_streamfile(), ast_strlen_zero(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and skipms.
00532 { 00533 int res = 0; 00534 int skipms = 3000; 00535 char *fwd = NULL; 00536 char *rev = NULL; 00537 char *pause = NULL; 00538 char *stop = NULL; 00539 00540 if (argc < 5 || argc > 9) 00541 return RESULT_SHOWUSAGE; 00542 00543 if (!ast_strlen_zero(argv[4])) 00544 stop = argv[4]; 00545 else 00546 stop = NULL; 00547 00548 if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) 00549 return RESULT_SHOWUSAGE; 00550 00551 if (argc > 6 && !ast_strlen_zero(argv[6])) 00552 fwd = argv[6]; 00553 else 00554 fwd = "#"; 00555 00556 if (argc > 7 && !ast_strlen_zero(argv[7])) 00557 rev = argv[7]; 00558 else 00559 rev = "*"; 00560 00561 if (argc > 8 && !ast_strlen_zero(argv[8])) 00562 pause = argv[8]; 00563 else 00564 pause = NULL; 00565 00566 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); 00567 00568 fdprintf(agi->fd, "200 result=%d\n", res); 00569 00570 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00571 }
static int handle_dbdel | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1299 of file res_agi.c.
References ast_db_del(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01300 { 01301 int res; 01302 01303 if (argc != 4) 01304 return RESULT_SHOWUSAGE; 01305 res = ast_db_del(argv[2], argv[3]); 01306 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01307 return RESULT_SUCCESS; 01308 }
static int handle_dbdeltree | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1310 of file res_agi.c.
References ast_db_deltree(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01311 { 01312 int res; 01313 if ((argc < 3) || (argc > 4)) 01314 return RESULT_SHOWUSAGE; 01315 if (argc == 4) 01316 res = ast_db_deltree(argv[2], argv[3]); 01317 else 01318 res = ast_db_deltree(argv[2], NULL); 01319 01320 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01321 return RESULT_SUCCESS; 01322 }
static int handle_dbget | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1272 of file res_agi.c.
References ast_db_get(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01273 { 01274 int res; 01275 char tmp[256]; 01276 01277 if (argc != 4) 01278 return RESULT_SHOWUSAGE; 01279 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01280 if (res) 01281 fdprintf(agi->fd, "200 result=0\n"); 01282 else 01283 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01284 01285 return RESULT_SUCCESS; 01286 }
static int handle_dbput | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1288 of file res_agi.c.
References ast_db_put(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01289 { 01290 int res; 01291 01292 if (argc != 5) 01293 return RESULT_SHOWUSAGE; 01294 res = ast_db_put(argv[2], argv[3], argv[4]); 01295 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01296 return RESULT_SUCCESS; 01297 }
static int handle_exec | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1113 of file res_agi.c.
References app, ast_log(), ast_verbose(), agi_state::fd, fdprintf, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), RESULT_SHOWUSAGE, and VERBOSE_PREFIX_3.
01114 { 01115 int res; 01116 struct ast_app *app; 01117 01118 if (argc < 2) 01119 return RESULT_SHOWUSAGE; 01120 01121 if (option_verbose > 2) 01122 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01123 01124 app = pbx_findapp(argv[1]); 01125 01126 if (app) { 01127 res = pbx_exec(chan, app, argv[2]); 01128 } else { 01129 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01130 res = -2; 01131 } 01132 fdprintf(agi->fd, "200 result=%d\n", res); 01133 01134 /* Even though this is wrong, users are depending upon this result. */ 01135 return res; 01136 }
static int handle_getdata | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 828 of file res_agi.c.
References ast_app_getdata_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and timeout.
00829 { 00830 int res; 00831 char data[1024]; 00832 int max; 00833 int timeout; 00834 00835 if (argc < 3) 00836 return RESULT_SHOWUSAGE; 00837 if (argc >= 4) 00838 timeout = atoi(argv[3]); 00839 else 00840 timeout = 0; 00841 if (argc >= 5) 00842 max = atoi(argv[4]); 00843 else 00844 max = 1024; 00845 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00846 if (res == 2) /* New command */ 00847 return RESULT_SUCCESS; 00848 else if (res == 1) 00849 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00850 else if (res < 0 ) 00851 fdprintf(agi->fd, "200 result=-1\n"); 00852 else 00853 fdprintf(agi->fd, "200 result=%s\n", data); 00854 return RESULT_SUCCESS; 00855 }
static int handle_getoption | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 629 of file res_agi.c.
References ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_verbose(), ast_waitfordigit_full(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, ast_pbx::dtimeout, agi_state::fd, fdprintf, LOG_DEBUG, LOG_WARNING, option_verbose, ast_channel::pbx, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, timeout, VERBOSE_PREFIX_3, and ast_filestream::vfs.
00630 { 00631 int res; 00632 int vres; 00633 struct ast_filestream *fs; 00634 struct ast_filestream *vfs; 00635 long sample_offset = 0; 00636 long max_length; 00637 int timeout = 0; 00638 char *edigits = ""; 00639 00640 if ( argc < 4 || argc > 5 ) 00641 return RESULT_SHOWUSAGE; 00642 00643 if ( argv[3] ) 00644 edigits = argv[3]; 00645 00646 if ( argc == 5 ) 00647 timeout = atoi(argv[4]); 00648 else if (chan->pbx->dtimeout) { 00649 /* by default dtimeout is set to 5sec */ 00650 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00651 } 00652 00653 fs = ast_openstream(chan, argv[2], chan->language); 00654 if (!fs) { 00655 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00656 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00657 return RESULT_SUCCESS; 00658 } 00659 vfs = ast_openvstream(chan, argv[2], chan->language); 00660 if (vfs) 00661 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00662 00663 if (option_verbose > 2) 00664 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00665 00666 ast_seekstream(fs, 0, SEEK_END); 00667 max_length = ast_tellstream(fs); 00668 ast_seekstream(fs, sample_offset, SEEK_SET); 00669 res = ast_applystream(chan, fs); 00670 if (vfs) 00671 vres = ast_applystream(chan, vfs); 00672 ast_playstream(fs); 00673 if (vfs) 00674 ast_playstream(vfs); 00675 00676 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00677 /* this is to check for if ast_waitstream closed the stream, we probably are at 00678 * the end of the stream, return that amount, else check for the amount */ 00679 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00680 ast_stopstream(chan); 00681 if (res == 1) { 00682 /* Stop this command, don't print a result line, as there is a new command */ 00683 return RESULT_SUCCESS; 00684 } 00685 00686 /* If the user didnt press a key, wait for digitTimeout*/ 00687 if (res == 0 ) { 00688 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00689 /* Make sure the new result is in the escape digits of the GET OPTION */ 00690 if ( !strchr(edigits,res) ) 00691 res=0; 00692 } 00693 00694 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00695 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00696 }
static int handle_getvariable | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1191 of file res_agi.c.
References ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01192 { 01193 char *ret; 01194 char tempstr[1024]; 01195 01196 if (argc != 3) 01197 return RESULT_SHOWUSAGE; 01198 01199 /* check if we want to execute an ast_custom_function */ 01200 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01201 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr; 01202 } else { 01203 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01204 } 01205 01206 if (ret) 01207 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01208 else 01209 fdprintf(agi->fd, "200 result=0\n"); 01210 01211 return RESULT_SUCCESS; 01212 }
static int handle_getvariablefull | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1214 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.
01215 { 01216 char tmp[4096] = ""; 01217 struct ast_channel *chan2=NULL; 01218 01219 if ((argc != 4) && (argc != 5)) 01220 return RESULT_SHOWUSAGE; 01221 if (argc == 5) { 01222 chan2 = ast_get_channel_by_name_locked(argv[4]); 01223 } else { 01224 chan2 = chan; 01225 } 01226 if (chan) { /* XXX isn't this chan2 ? */ 01227 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01228 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01229 } else { 01230 fdprintf(agi->fd, "200 result=0\n"); 01231 } 01232 if (chan2 && (chan2 != chan)) 01233 ast_channel_unlock(chan2); 01234 return RESULT_SUCCESS; 01235 }
static int handle_hangup | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1087 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.
01088 { 01089 struct ast_channel *c; 01090 if (argc == 1) { 01091 /* no argument: hangup the current channel */ 01092 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01093 fdprintf(agi->fd, "200 result=1\n"); 01094 return RESULT_SUCCESS; 01095 } else if (argc == 2) { 01096 /* one argument: look for info on the specified channel */ 01097 c = ast_get_channel_by_name_locked(argv[1]); 01098 if (c) { 01099 /* we have a matching channel */ 01100 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01101 fdprintf(agi->fd, "200 result=1\n"); 01102 ast_channel_unlock(c); 01103 return RESULT_SUCCESS; 01104 } 01105 /* if we get this far no channel name matched the argument given */ 01106 fdprintf(agi->fd, "200 result=-1\n"); 01107 return RESULT_SUCCESS; 01108 } else { 01109 return RESULT_SHOWUSAGE; 01110 } 01111 }
static int handle_noop | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | arg, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1359 of file res_agi.c.
References agi_state::fd, fdprintf, and RESULT_SUCCESS.
01360 { 01361 fdprintf(agi->fd, "200 result=0\n"); 01362 return RESULT_SUCCESS; 01363 }
static int handle_recordfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 892 of file res_agi.c.
References ast_applystream(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), ast_seekstream(), ast_set_read_format(), ast_stream_rewind(), ast_streamfile(), ast_tellstream(), ast_truncstream(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), f, agi_state::fd, fdprintf, LOG_WARNING, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, and ast_dsp::totalsilence.
00893 { 00894 struct ast_filestream *fs; 00895 struct ast_frame *f; 00896 struct timeval start; 00897 long sample_offset = 0; 00898 int res = 0; 00899 int ms; 00900 00901 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00902 int totalsilence = 0; 00903 int dspsilence = 0; 00904 int silence = 0; /* amount of silence to allow */ 00905 int gotsilence = 0; /* did we timeout for silence? */ 00906 char *silencestr=NULL; 00907 int rfmt=0; 00908 00909 00910 /* XXX EAGI FIXME XXX */ 00911 00912 if (argc < 6) 00913 return RESULT_SHOWUSAGE; 00914 if (sscanf(argv[5], "%d", &ms) != 1) 00915 return RESULT_SHOWUSAGE; 00916 00917 if (argc > 6) 00918 silencestr = strchr(argv[6],'s'); 00919 if ((argc > 7) && (!silencestr)) 00920 silencestr = strchr(argv[7],'s'); 00921 if ((argc > 8) && (!silencestr)) 00922 silencestr = strchr(argv[8],'s'); 00923 00924 if (silencestr) { 00925 if (strlen(silencestr) > 2) { 00926 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00927 silencestr++; 00928 silencestr++; 00929 if (silencestr) 00930 silence = atoi(silencestr); 00931 if (silence > 0) 00932 silence *= 1000; 00933 } 00934 } 00935 } 00936 00937 if (silence > 0) { 00938 rfmt = chan->readformat; 00939 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00940 if (res < 0) { 00941 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00942 return -1; 00943 } 00944 sildet = ast_dsp_new(); 00945 if (!sildet) { 00946 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00947 return -1; 00948 } 00949 ast_dsp_set_threshold(sildet, 256); 00950 } 00951 00952 /* backward compatibility, if no offset given, arg[6] would have been 00953 * caught below and taken to be a beep, else if it is a digit then it is a 00954 * offset */ 00955 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00956 res = ast_streamfile(chan, "beep", chan->language); 00957 00958 if ((argc > 7) && (!strchr(argv[7], '='))) 00959 res = ast_streamfile(chan, "beep", chan->language); 00960 00961 if (!res) 00962 res = ast_waitstream(chan, argv[4]); 00963 if (res) { 00964 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00965 } else { 00966 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644); 00967 if (!fs) { 00968 res = -1; 00969 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 00970 if (sildet) 00971 ast_dsp_free(sildet); 00972 return RESULT_FAILURE; 00973 } 00974 00975 /* Request a video update */ 00976 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00977 00978 chan->stream = fs; 00979 ast_applystream(chan,fs); 00980 /* really should have checks */ 00981 ast_seekstream(fs, sample_offset, SEEK_SET); 00982 ast_truncstream(fs); 00983 00984 start = ast_tvnow(); 00985 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 00986 res = ast_waitfor(chan, -1); 00987 if (res < 0) { 00988 ast_closestream(fs); 00989 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 00990 if (sildet) 00991 ast_dsp_free(sildet); 00992 return RESULT_FAILURE; 00993 } 00994 f = ast_read(chan); 00995 if (!f) { 00996 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset); 00997 ast_closestream(fs); 00998 if (sildet) 00999 ast_dsp_free(sildet); 01000 return RESULT_FAILURE; 01001 } 01002 switch(f->frametype) { 01003 case AST_FRAME_DTMF: 01004 if (strchr(argv[4], f->subclass)) { 01005 /* This is an interrupting chracter, so rewind to chop off any small 01006 amount of DTMF that may have been recorded 01007 */ 01008 ast_stream_rewind(fs, 200); 01009 ast_truncstream(fs); 01010 sample_offset = ast_tellstream(fs); 01011 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 01012 ast_closestream(fs); 01013 ast_frfree(f); 01014 if (sildet) 01015 ast_dsp_free(sildet); 01016 return RESULT_SUCCESS; 01017 } 01018 break; 01019 case AST_FRAME_VOICE: 01020 ast_writestream(fs, f); 01021 /* this is a safe place to check progress since we know that fs 01022 * is valid after a write, and it will then have our current 01023 * location */ 01024 sample_offset = ast_tellstream(fs); 01025 if (silence > 0) { 01026 dspsilence = 0; 01027 ast_dsp_silence(sildet, f, &dspsilence); 01028 if (dspsilence) { 01029 totalsilence = dspsilence; 01030 } else { 01031 totalsilence = 0; 01032 } 01033 if (totalsilence > silence) { 01034 /* Ended happily with silence */ 01035 gotsilence = 1; 01036 break; 01037 } 01038 } 01039 break; 01040 case AST_FRAME_VIDEO: 01041 ast_writestream(fs, f); 01042 default: 01043 /* Ignore all other frames */ 01044 break; 01045 } 01046 ast_frfree(f); 01047 if (gotsilence) 01048 break; 01049 } 01050 01051 if (gotsilence) { 01052 ast_stream_rewind(fs, silence-1000); 01053 ast_truncstream(fs); 01054 sample_offset = ast_tellstream(fs); 01055 } 01056 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01057 ast_closestream(fs); 01058 } 01059 01060 if (silence > 0) { 01061 res = ast_set_read_format(chan, rfmt); 01062 if (res) 01063 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01064 ast_dsp_free(sildet); 01065 } 01066 return RESULT_SUCCESS; 01067 }
static int handle_recvchar | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 462 of file res_agi.c.
References ast_recvchar(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00463 { 00464 int res; 00465 if (argc != 3) 00466 return RESULT_SHOWUSAGE; 00467 res = ast_recvchar(chan,atoi(argv[2])); 00468 if (res == 0) { 00469 fdprintf(agi->fd, "200 result=%d (timeout)\n", res); 00470 return RESULT_SUCCESS; 00471 } 00472 if (res > 0) { 00473 fdprintf(agi->fd, "200 result=%d\n", res); 00474 return RESULT_SUCCESS; 00475 } 00476 else { 00477 fdprintf(agi->fd, "200 result=%d (hangup)\n", res); 00478 return RESULT_FAILURE; 00479 } 00480 }
static int handle_recvtext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 482 of file res_agi.c.
References ast_recvtext(), agi_state::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00483 { 00484 char *buf; 00485 00486 if (argc != 3) 00487 return RESULT_SHOWUSAGE; 00488 buf = ast_recvtext(chan,atoi(argv[2])); 00489 if (buf) { 00490 fdprintf(agi->fd, "200 result=1 (%s)\n", buf); 00491 free(buf); 00492 } else { 00493 fdprintf(agi->fd, "200 result=-1\n"); 00494 } 00495 return RESULT_SUCCESS; 00496 }
static int handle_sayalpha | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 736 of file res_agi.c.
References ast_say_character_str_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00737 { 00738 int res; 00739 00740 if (argc != 4) 00741 return RESULT_SHOWUSAGE; 00742 00743 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00744 if (res == 1) /* New command */ 00745 return RESULT_SUCCESS; 00746 fdprintf(agi->fd, "200 result=%d\n", res); 00747 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00748 }
static int handle_saydate | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 750 of file res_agi.c.
References ast_say_date, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00751 { 00752 int res; 00753 int num; 00754 if (argc != 4) 00755 return RESULT_SHOWUSAGE; 00756 if (sscanf(argv[2], "%d", &num) != 1) 00757 return RESULT_SHOWUSAGE; 00758 res = ast_say_date(chan, num, argv[3], chan->language); 00759 if (res == 1) 00760 return RESULT_SUCCESS; 00761 fdprintf(agi->fd, "200 result=%d\n", res); 00762 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00763 }
static int handle_saydatetime | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 780 of file res_agi.c.
References ast_get_time_t(), ast_say_date_with_format, ast_strlen_zero(), agi_state::fd, fdprintf, format, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00781 { 00782 int res=0; 00783 time_t unixtime; 00784 char *format, *zone=NULL; 00785 00786 if (argc < 4) 00787 return RESULT_SHOWUSAGE; 00788 00789 if (argc > 4) { 00790 format = argv[4]; 00791 } else { 00792 /* XXX this doesn't belong here, but in the 'say' module */ 00793 if (!strcasecmp(chan->language, "de")) { 00794 format = "A dBY HMS"; 00795 } else { 00796 format = "ABdY 'digits/at' IMp"; 00797 } 00798 } 00799 00800 if (argc > 5 && !ast_strlen_zero(argv[5])) 00801 zone = argv[5]; 00802 00803 if (ast_get_time_t(argv[2], &unixtime, 0, NULL)) 00804 return RESULT_SHOWUSAGE; 00805 00806 res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone); 00807 if (res == 1) 00808 return RESULT_SUCCESS; 00809 00810 fdprintf(agi->fd, "200 result=%d\n", res); 00811 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00812 }
static int handle_saydigits | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 719 of file res_agi.c.
References ast_say_digit_str_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00720 { 00721 int res; 00722 int num; 00723 00724 if (argc != 4) 00725 return RESULT_SHOWUSAGE; 00726 if (sscanf(argv[2], "%d", &num) != 1) 00727 return RESULT_SHOWUSAGE; 00728 00729 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00730 if (res == 1) /* New command */ 00731 return RESULT_SUCCESS; 00732 fdprintf(agi->fd, "200 result=%d\n", res); 00733 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00734 }
static int handle_saynumber | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 704 of file res_agi.c.
References ast_say_number_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00705 { 00706 int res; 00707 int num; 00708 if (argc != 4) 00709 return RESULT_SHOWUSAGE; 00710 if (sscanf(argv[2], "%d", &num) != 1) 00711 return RESULT_SHOWUSAGE; 00712 res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl); 00713 if (res == 1) 00714 return RESULT_SUCCESS; 00715 fdprintf(agi->fd, "200 result=%d\n", res); 00716 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00717 }
static int handle_sayphonetic | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 814 of file res_agi.c.
References ast_say_phonetic_str_full, agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00815 { 00816 int res; 00817 00818 if (argc != 4) 00819 return RESULT_SHOWUSAGE; 00820 00821 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00822 if (res == 1) /* New command */ 00823 return RESULT_SUCCESS; 00824 fdprintf(agi->fd, "200 result=%d\n", res); 00825 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00826 }
static int handle_saytime | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 765 of file res_agi.c.
References ast_say_time, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00766 { 00767 int res; 00768 int num; 00769 if (argc != 4) 00770 return RESULT_SHOWUSAGE; 00771 if (sscanf(argv[2], "%d", &num) != 1) 00772 return RESULT_SHOWUSAGE; 00773 res = ast_say_time(chan, num, argv[3], chan->language); 00774 if (res == 1) 00775 return RESULT_SUCCESS; 00776 fdprintf(agi->fd, "200 result=%d\n", res); 00777 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00778 }
static int handle_sendimage | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 519 of file res_agi.c.
References ast_check_hangup(), ast_send_image(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00520 { 00521 int res; 00522 if (argc != 3) 00523 return RESULT_SHOWUSAGE; 00524 res = ast_send_image(chan, argv[2]); 00525 if (!ast_check_hangup(chan)) 00526 res = 0; 00527 fdprintf(agi->fd, "200 result=%d\n", res); 00528 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00529 }
static int handle_sendtext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 445 of file res_agi.c.
References ast_sendtext(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00446 { 00447 int res; 00448 if (argc != 3) 00449 return RESULT_SHOWUSAGE; 00450 /* At the moment, the parser (perhaps broken) returns with 00451 the last argument PLUS the newline at the end of the input 00452 buffer. This probably needs to be fixed, but I wont do that 00453 because other stuff may break as a result. The right way 00454 would probably be to strip off the trailing newline before 00455 parsing, then here, add a newline at the end of the string 00456 before sending it to ast_sendtext --DUDE */ 00457 res = ast_sendtext(chan, argv[2]); 00458 fdprintf(agi->fd, "200 result=%d\n", res); 00459 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00460 }
static int handle_setcallerid | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1138 of file res_agi.c.
References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, fdprintf, and RESULT_SUCCESS.
01139 { 01140 char tmp[256]=""; 01141 char *l = NULL, *n = NULL; 01142 01143 if (argv[2]) { 01144 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01145 ast_callerid_parse(tmp, &n, &l); 01146 if (l) 01147 ast_shrink_phone_number(l); 01148 else 01149 l = ""; 01150 if (!n) 01151 n = ""; 01152 ast_set_callerid(chan, l, n, NULL); 01153 } 01154 01155 fdprintf(agi->fd, "200 result=1\n"); 01156 return RESULT_SUCCESS; 01157 }
static int handle_setcontext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 857 of file res_agi.c.
References ast_channel::context, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00858 { 00859 00860 if (argc != 3) 00861 return RESULT_SHOWUSAGE; 00862 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00863 fdprintf(agi->fd, "200 result=0\n"); 00864 return RESULT_SUCCESS; 00865 }
static int handle_setextension | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 867 of file res_agi.c.
References ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00868 { 00869 if (argc != 3) 00870 return RESULT_SHOWUSAGE; 00871 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00872 fdprintf(agi->fd, "200 result=0\n"); 00873 return RESULT_SUCCESS; 00874 }
static int handle_setmusic | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1365 of file res_agi.c.
References ast_moh_start(), ast_moh_stop(), agi_state::fd, fdprintf, and RESULT_SUCCESS.
01366 { 01367 if (!strncasecmp(argv[2], "on", 2)) 01368 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL); 01369 else if (!strncasecmp(argv[2], "off", 3)) 01370 ast_moh_stop(chan); 01371 fdprintf(agi->fd, "200 result=0\n"); 01372 return RESULT_SUCCESS; 01373 }
static int handle_setpriority | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 876 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.
00877 { 00878 int pri; 00879 if (argc != 3) 00880 return RESULT_SHOWUSAGE; 00881 00882 if (sscanf(argv[2], "%d", &pri) != 1) { 00883 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00884 return RESULT_SHOWUSAGE; 00885 } 00886 00887 ast_explicit_goto(chan, NULL, NULL, pri); 00888 fdprintf(agi->fd, "200 result=0\n"); 00889 return RESULT_SUCCESS; 00890 }
static int handle_setvariable | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1182 of file res_agi.c.
References agi_state::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS.
01183 { 01184 if (argv[3]) 01185 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01186 01187 fdprintf(agi->fd, "200 result=1\n"); 01188 return RESULT_SUCCESS; 01189 }
static int handle_showagi | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1932 of file res_agi.c.
References ast_cli(), ast_join(), find_command(), help_workhorse(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage.
01933 { 01934 struct agi_command *e; 01935 char fullcmd[80]; 01936 if ((argc < 2)) 01937 return RESULT_SHOWUSAGE; 01938 if (argc > 2) { 01939 e = find_command(argv + 2, 1); 01940 if (e) 01941 ast_cli(fd, e->usage); 01942 else { 01943 if (find_command(argv + 2, -1)) { 01944 return help_workhorse(fd, argv + 1); 01945 } else { 01946 ast_join(fullcmd, sizeof(fullcmd), argv+1); 01947 ast_cli(fd, "No such command '%s'.\n", fullcmd); 01948 } 01949 } 01950 } else { 01951 return help_workhorse(fd, NULL); 01952 } 01953 return RESULT_SUCCESS; 01954 }
static int handle_streamfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 573 of file res_agi.c.
References ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_verbose(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, LOG_DEBUG, option_verbose, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.
00574 { 00575 int res; 00576 int vres; 00577 struct ast_filestream *fs; 00578 struct ast_filestream *vfs; 00579 long sample_offset = 0; 00580 long max_length; 00581 char *edigits = ""; 00582 00583 if (argc < 4 || argc > 5) 00584 return RESULT_SHOWUSAGE; 00585 00586 if (argv[3]) 00587 edigits = argv[3]; 00588 00589 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00590 return RESULT_SHOWUSAGE; 00591 00592 fs = ast_openstream(chan, argv[2], chan->language); 00593 00594 if (!fs) { 00595 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00596 return RESULT_SUCCESS; 00597 } 00598 vfs = ast_openvstream(chan, argv[2], chan->language); 00599 if (vfs) 00600 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00601 00602 if (option_verbose > 2) 00603 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset); 00604 00605 ast_seekstream(fs, 0, SEEK_END); 00606 max_length = ast_tellstream(fs); 00607 ast_seekstream(fs, sample_offset, SEEK_SET); 00608 res = ast_applystream(chan, fs); 00609 if (vfs) 00610 vres = ast_applystream(chan, vfs); 00611 ast_playstream(fs); 00612 if (vfs) 00613 ast_playstream(vfs); 00614 00615 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00616 /* this is to check for if ast_waitstream closed the stream, we probably are at 00617 * the end of the stream, return that amount, else check for the amount */ 00618 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00619 ast_stopstream(chan); 00620 if (res == 1) { 00621 /* Stop this command, don't print a result line, as there is a new command */ 00622 return RESULT_SUCCESS; 00623 } 00624 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00625 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00626 }
static int handle_tddmode | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 498 of file res_agi.c.
References ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00499 { 00500 int res,x; 00501 if (argc != 3) 00502 return RESULT_SHOWUSAGE; 00503 if (!strncasecmp(argv[2],"on",2)) 00504 x = 1; 00505 else 00506 x = 0; 00507 if (!strncasecmp(argv[2],"mate",4)) 00508 x = 2; 00509 if (!strncasecmp(argv[2],"tdd",3)) 00510 x = 1; 00511 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0); 00512 if (res != RESULT_SUCCESS) 00513 fdprintf(agi->fd, "200 result=0\n"); 00514 else 00515 fdprintf(agi->fd, "200 result=1\n"); 00516 return RESULT_SUCCESS; 00517 }
static int handle_verbose | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1237 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.
01238 { 01239 int level = 0; 01240 char *prefix; 01241 01242 if (argc < 2) 01243 return RESULT_SHOWUSAGE; 01244 01245 if (argv[2]) 01246 sscanf(argv[2], "%d", &level); 01247 01248 switch (level) { 01249 case 4: 01250 prefix = VERBOSE_PREFIX_4; 01251 break; 01252 case 3: 01253 prefix = VERBOSE_PREFIX_3; 01254 break; 01255 case 2: 01256 prefix = VERBOSE_PREFIX_2; 01257 break; 01258 case 1: 01259 default: 01260 prefix = VERBOSE_PREFIX_1; 01261 break; 01262 } 01263 01264 if (level <= option_verbose) 01265 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01266 01267 fdprintf(agi->fd, "200 result=1\n"); 01268 01269 return RESULT_SUCCESS; 01270 }
static int handle_waitfordigit | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 432 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.
00433 { 00434 int res; 00435 int to; 00436 if (argc != 4) 00437 return RESULT_SHOWUSAGE; 00438 if (sscanf(argv[3], "%d", &to) != 1) 00439 return RESULT_SHOWUSAGE; 00440 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); 00441 fdprintf(agi->fd, "200 result=%d\n", res); 00442 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00443 }
static int help_workhorse | ( | int | fd, | |
char * | match[] | |||
) | [static] |
Definition at line 1662 of file res_agi.c.
References ast_cli(), ast_join(), agi_command::cmda, commands, and agi_command::summary.
01663 { 01664 char fullcmd[80]; 01665 char matchstr[80]; 01666 int x; 01667 struct agi_command *e; 01668 if (match) 01669 ast_join(matchstr, sizeof(matchstr), match); 01670 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01671 e = &commands[x]; 01672 if (!e->cmda[0]) 01673 break; 01674 /* Hide commands that start with '_' */ 01675 if ((e->cmda[0])[0] == '_') 01676 continue; 01677 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01678 if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr))) 01679 continue; 01680 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01681 } 01682 return 0; 01683 }
static enum agi_result launch_netscript | ( | char * | agiurl, | |
char * | argv[], | |||
int * | fds, | |||
int * | efd, | |||
int * | opid | |||
) | [static] |
Definition at line 142 of file res_agi.c.
References AGI_PORT, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ahp, ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), pollfd::events, pollfd::fd, fdprintf, hp, LOG_DEBUG, LOG_WARNING, MAX_AGI_CONNECT, option_debug, poll(), POLLOUT, and s.
Referenced by launch_script().
00143 { 00144 int s; 00145 int flags; 00146 struct pollfd pfds[1]; 00147 char *host; 00148 char *c; int port = AGI_PORT; 00149 char *script=""; 00150 struct sockaddr_in sin; 00151 struct hostent *hp; 00152 struct ast_hostent ahp; 00153 int res; 00154 00155 /* agiusl is "agi://host.domain[:port][/script/name]" */ 00156 host = ast_strdupa(agiurl + 6); /* Remove agi:// */ 00157 /* Strip off any script name */ 00158 if ((c = strchr(host, '/'))) { 00159 *c = '\0'; 00160 c++; 00161 script = c; 00162 } 00163 if ((c = strchr(host, ':'))) { 00164 *c = '\0'; 00165 c++; 00166 port = atoi(c); 00167 } 00168 if (efd) { 00169 ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n"); 00170 return -1; 00171 } 00172 hp = ast_gethostbyname(host, &ahp); 00173 if (!hp) { 00174 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host); 00175 return -1; 00176 } 00177 s = socket(AF_INET, SOCK_STREAM, 0); 00178 if (s < 0) { 00179 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 00180 return -1; 00181 } 00182 flags = fcntl(s, F_GETFL); 00183 if (flags < 0) { 00184 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno)); 00185 close(s); 00186 return -1; 00187 } 00188 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { 00189 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno)); 00190 close(s); 00191 return -1; 00192 } 00193 memset(&sin, 0, sizeof(sin)); 00194 sin.sin_family = AF_INET; 00195 sin.sin_port = htons(port); 00196 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00197 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) { 00198 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno)); 00199 close(s); 00200 return AGI_RESULT_FAILURE; 00201 } 00202 00203 pfds[0].fd = s; 00204 pfds[0].events = POLLOUT; 00205 while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) { 00206 if (errno != EINTR) { 00207 if (!res) { 00208 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n", 00209 agiurl, MAX_AGI_CONNECT); 00210 } else 00211 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00212 close(s); 00213 return AGI_RESULT_FAILURE; 00214 } 00215 } 00216 00217 if (fdprintf(s, "agi_network: yes\n") < 0) { 00218 if (errno != EINTR) { 00219 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00220 close(s); 00221 return AGI_RESULT_FAILURE; 00222 } 00223 } 00224 00225 /* If we have a script parameter, relay it to the fastagi server */ 00226 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */ 00227 if (!ast_strlen_zero(script)) 00228 fdprintf(s, "agi_network_script: %s\n", script); 00229 00230 if (option_debug > 3) 00231 ast_log(LOG_DEBUG, "Wow, connected!\n"); 00232 fds[0] = s; 00233 fds[1] = s; 00234 *opid = -1; 00235 return AGI_RESULT_SUCCESS; 00236 }
static enum agi_result launch_script | ( | char * | script, | |
char * | argv[], | |||
int * | fds, | |||
int * | efd, | |||
int * | opid | |||
) | [static] |
Definition at line 238 of file res_agi.c.
References AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_MONITOR_DIR, ast_config_AST_RUN_DIR, ast_config_AST_SPOOL_DIR, ast_config_AST_VAR_DIR, ast_log(), ast_set_priority(), ast_verbose(), launch_netscript(), LOG_WARNING, option_verbose, setenv(), and VERBOSE_PREFIX_3.
Referenced by agi_exec_full().
00239 { 00240 char tmp[256]; 00241 int pid; 00242 int toast[2]; 00243 int fromast[2]; 00244 int audio[2]; 00245 int x; 00246 int res; 00247 sigset_t signal_set, old_set; 00248 struct stat statbuf; 00249 00250 if (!strncasecmp(script, "agi://", 6)) 00251 return launch_netscript(script, argv, fds, efd, opid); 00252 00253 if (script[0] != '/') { 00254 snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script); 00255 script = tmp; 00256 } 00257 if (stat(script, &statbuf) < 0) { 00258 ast_log(LOG_WARNING, "Unable to execute %s: File does not exist\n", script); 00259 return -1; 00260 } 00261 if (!(statbuf.st_mode & S_IXUSR)) { 00262 ast_log(LOG_WARNING, "Unable to execute %s: File is not executable\n", script); 00263 return -1; 00264 } 00265 if (pipe(toast)) { 00266 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno)); 00267 return AGI_RESULT_FAILURE; 00268 } 00269 if (pipe(fromast)) { 00270 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno)); 00271 close(toast[0]); 00272 close(toast[1]); 00273 return AGI_RESULT_FAILURE; 00274 } 00275 if (efd) { 00276 if (pipe(audio)) { 00277 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00278 close(fromast[0]); 00279 close(fromast[1]); 00280 close(toast[0]); 00281 close(toast[1]); 00282 return AGI_RESULT_FAILURE; 00283 } 00284 res = fcntl(audio[1], F_GETFL); 00285 if (res > -1) 00286 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK); 00287 if (res < 0) { 00288 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00289 close(fromast[0]); 00290 close(fromast[1]); 00291 close(toast[0]); 00292 close(toast[1]); 00293 close(audio[0]); 00294 close(audio[1]); 00295 return AGI_RESULT_FAILURE; 00296 } 00297 } 00298 00299 /* Block SIGHUP during the fork - prevents a race */ 00300 sigfillset(&signal_set); 00301 pthread_sigmask(SIG_BLOCK, &signal_set, &old_set); 00302 pid = fork(); 00303 if (pid < 0) { 00304 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); 00305 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00306 return AGI_RESULT_FAILURE; 00307 } 00308 if (!pid) { 00309 /* Pass paths to AGI via environmental variables */ 00310 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1); 00311 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1); 00312 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1); 00313 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1); 00314 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1); 00315 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1); 00316 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1); 00317 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1); 00318 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1); 00319 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1); 00320 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1); 00321 00322 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ 00323 ast_set_priority(0); 00324 00325 /* Redirect stdin and out, provide enhanced audio channel if desired */ 00326 dup2(fromast[0], STDIN_FILENO); 00327 dup2(toast[1], STDOUT_FILENO); 00328 if (efd) { 00329 dup2(audio[0], STDERR_FILENO + 1); 00330 } else { 00331 close(STDERR_FILENO + 1); 00332 } 00333 00334 /* Before we unblock our signals, return our trapped signals back to the defaults */ 00335 signal(SIGHUP, SIG_DFL); 00336 signal(SIGCHLD, SIG_DFL); 00337 signal(SIGINT, SIG_DFL); 00338 signal(SIGURG, SIG_DFL); 00339 signal(SIGTERM, SIG_DFL); 00340 signal(SIGPIPE, SIG_DFL); 00341 signal(SIGXFSZ, SIG_DFL); 00342 00343 /* unblock important signal handlers */ 00344 if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { 00345 ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); 00346 _exit(1); 00347 } 00348 00349 /* Close everything but stdin/out/error */ 00350 for (x=STDERR_FILENO + 2;x<1024;x++) 00351 close(x); 00352 00353 /* Execute script */ 00354 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */ 00355 execv(script, argv); 00356 /* Can't use ast_log since FD's are closed */ 00357 fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno)); 00358 fflush(stdout); 00359 _exit(1); 00360 } 00361 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00362 if (option_verbose > 2) 00363 ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); 00364 fds[0] = toast[0]; 00365 fds[1] = fromast[1]; 00366 if (efd) { 00367 *efd = audio[1]; 00368 } 00369 /* close what we're not using in the parent */ 00370 close(toast[1]); 00371 close(fromast[0]); 00372 00373 if (efd) 00374 close(audio[0]); 00375 00376 *opid = pid; 00377 return AGI_RESULT_SUCCESS; 00378 }
static int load_module | ( | void | ) | [static] |
Definition at line 2166 of file res_agi.c.
References agi_exec(), ast_cli_register_multiple(), ast_register_application(), cli_agi, deadagi_exec(), and eagi_exec().
02167 { 02168 ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02169 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02170 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02171 return ast_register_application(app, agi_exec, synopsis, descrip); 02172 }
static int parse_args | ( | char * | s, | |
int * | max, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1748 of file res_agi.c.
References ast_log(), LOG_WARNING, and MAX_ARGS.
01749 { 01750 int x=0; 01751 int quoted=0; 01752 int escaped=0; 01753 int whitespace=1; 01754 char *cur; 01755 01756 cur = s; 01757 while(*s) { 01758 switch(*s) { 01759 case '"': 01760 /* If it's escaped, put a literal quote */ 01761 if (escaped) 01762 goto normal; 01763 else 01764 quoted = !quoted; 01765 if (quoted && whitespace) { 01766 /* If we're starting a quote, coming off white space start a new word, too */ 01767 argv[x++] = cur; 01768 whitespace=0; 01769 } 01770 escaped = 0; 01771 break; 01772 case ' ': 01773 case '\t': 01774 if (!quoted && !escaped) { 01775 /* If we're not quoted, mark this as whitespace, and 01776 end the previous argument */ 01777 whitespace = 1; 01778 *(cur++) = '\0'; 01779 } else 01780 /* Otherwise, just treat it as anything else */ 01781 goto normal; 01782 break; 01783 case '\\': 01784 /* If we're escaped, print a literal, otherwise enable escaping */ 01785 if (escaped) { 01786 goto normal; 01787 } else { 01788 escaped=1; 01789 } 01790 break; 01791 default: 01792 normal: 01793 if (whitespace) { 01794 if (x >= MAX_ARGS -1) { 01795 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01796 break; 01797 } 01798 /* Coming off of whitespace, start the next argument */ 01799 argv[x++] = cur; 01800 whitespace=0; 01801 } 01802 *(cur++) = *s; 01803 escaped=0; 01804 } 01805 s++; 01806 } 01807 /* Null terminate */ 01808 *(cur++) = '\0'; 01809 argv[x] = NULL; 01810 *max = x; 01811 return 0; 01812 }
static enum agi_result run_agi | ( | struct ast_channel * | chan, | |
char * | request, | |||
AGI * | agi, | |||
int | pid, | |||
int * | status, | |||
int | dead, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1846 of file res_agi.c.
References agi_handle_command(), 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, f, agi_state::fd, LOG_DEBUG, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), RETRY, setup_env(), and VERBOSE_PREFIX_3.
Referenced by agi_exec_full().
01847 { 01848 struct ast_channel *c; 01849 int outfd; 01850 int ms; 01851 enum agi_result returnstatus = AGI_RESULT_SUCCESS; 01852 struct ast_frame *f; 01853 char buf[2048]; 01854 FILE *readf; 01855 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01856 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01857 int retry = RETRY; 01858 01859 if (!(readf = fdopen(agi->ctrl, "r"))) { 01860 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01861 if (pid > -1) 01862 kill(pid, SIGHUP); 01863 close(agi->ctrl); 01864 return AGI_RESULT_FAILURE; 01865 } 01866 setlinebuf(readf); 01867 setup_env(chan, request, agi->fd, (agi->audio > -1), argc, argv); 01868 for (;;) { 01869 ms = -1; 01870 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01871 if (c) { 01872 retry = RETRY; 01873 /* Idle the channel until we get a command */ 01874 f = ast_read(c); 01875 if (!f) { 01876 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01877 returnstatus = AGI_RESULT_HANGUP; 01878 break; 01879 } else { 01880 /* If it's voice, write it to the audio pipe */ 01881 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01882 /* Write, ignoring errors */ 01883 write(agi->audio, f->data, f->datalen); 01884 } 01885 ast_frfree(f); 01886 } 01887 } else if (outfd > -1) { 01888 retry = RETRY; 01889 buf[0] = '\0'; 01890 if (!fgets(buf, sizeof(buf), readf)) { 01891 /* Program terminated */ 01892 if (returnstatus) 01893 returnstatus = -1; 01894 if (option_verbose > 2) 01895 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01896 if (pid > 0) 01897 waitpid(pid, status, 0); 01898 /* No need to kill the pid anymore, since they closed us */ 01899 pid = -1; 01900 break; 01901 } 01902 /* get rid of trailing newline, if any */ 01903 if (*buf && buf[strlen(buf) - 1] == '\n') 01904 buf[strlen(buf) - 1] = 0; 01905 if (agidebug) 01906 ast_verbose("AGI Rx << %s\n", buf); 01907 returnstatus |= agi_handle_command(chan, agi, buf); 01908 /* If the handle_command returns -1, we need to stop */ 01909 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01910 break; 01911 } 01912 } else { 01913 if (--retry <= 0) { 01914 ast_log(LOG_WARNING, "No channel, no fd?\n"); 01915 returnstatus = AGI_RESULT_FAILURE; 01916 break; 01917 } 01918 } 01919 } 01920 /* Notify process */ 01921 if (pid > -1) { 01922 const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP"); 01923 if (ast_strlen_zero(sighup) || !ast_false(sighup)) { 01924 if (kill(pid, SIGHUP)) 01925 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 01926 } 01927 } 01928 fclose(readf); 01929 return returnstatus; 01930 }
static void setup_env | ( | struct ast_channel * | chan, | |
char * | request, | |||
int | fd, | |||
int | enhanced, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 380 of file res_agi.c.
References ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, fdprintf, ast_channel::priority, S_OR, ast_channel::tech, and ast_channel_tech::type.
Referenced by run_agi().
00381 { 00382 int count; 00383 00384 /* Print initial environment, with agi_request always being the first 00385 thing */ 00386 fdprintf(fd, "agi_request: %s\n", request); 00387 fdprintf(fd, "agi_channel: %s\n", chan->name); 00388 fdprintf(fd, "agi_language: %s\n", chan->language); 00389 fdprintf(fd, "agi_type: %s\n", chan->tech->type); 00390 fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid); 00391 00392 /* ANI/DNIS */ 00393 fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown")); 00394 fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown")); 00395 fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres); 00396 fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2); 00397 fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton); 00398 fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns); 00399 fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown")); 00400 fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown")); 00401 00402 /* Context information */ 00403 fdprintf(fd, "agi_context: %s\n", chan->context); 00404 fdprintf(fd, "agi_extension: %s\n", chan->exten); 00405 fdprintf(fd, "agi_priority: %d\n", chan->priority); 00406 fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0"); 00407 00408 /* User information */ 00409 fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); 00410 00411 /* Send any parameters to the fastagi server that have been passed via the agi application */ 00412 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */ 00413 for(count = 1; count < argc; count++) 00414 fdprintf(fd, "agi_arg_%d: %s\n", count, argv[count]); 00415 00416 /* End with empty return */ 00417 fdprintf(fd, "\n"); 00418 }
static int unload_module | ( | void | ) | [static] |
Definition at line 2157 of file res_agi.c.
References ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_unregister_application(), and cli_agi.
02158 { 02159 ast_module_user_hangup_all(); 02160 ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02161 ast_unregister_application(eapp); 02162 ast_unregister_application(deadapp); 02163 return ast_unregister_application(app); 02164 }
struct ast_cli_entry cli_agi[] [static] |
struct ast_cli_entry cli_agi_no_debug_deprecated [static] |
Initial value:
{ { "agi", "no", "debug", NULL }, agi_no_debug_deprecated, NULL, NULL }
struct ast_cli_entry cli_dump_agihtml_deprecated [static] |
Initial value:
{ { "dump", "agihtml", NULL }, handle_agidumphtml, NULL, NULL }
struct ast_cli_entry cli_show_agi_deprecated [static] |
Initial value:
{ { "show", "agi", NULL }, handle_showagi, NULL, NULL }
agi_command commands[MAX_COMMANDS] [static] |
Definition at line 1622 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* deadsynopsis = "Executes AGI on a hungup channel" [static] |
char debug_usage[] [static] |
char dumpagihtml_help[] [static] |
char* esynopsis = "Executes an EAGI compliant application" [static] |
char no_debug_usage[] [static] |
char showagi_help[] [static] |
char usage_answer[] [static] |
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"
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] |
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"
char usage_sayalpha[] [static] |
char usage_saydate[] [static] |
char usage_saydatetime[] [static] |
char usage_saydigits[] [static] |
char usage_saynumber[] [static] |
char usage_sayphonetic[] [static] |
char usage_saytime[] [static] |
char usage_sendimage[] [static] |
char usage_sendtext[] [static] |
char usage_setcallerid[] [static] |
char usage_setcontext[] [static] |
char usage_setextension[] [static] |
char usage_setmusic[] [static] |
char usage_setpriority[] [static] |
char usage_setvariable[] [static] |
char usage_streamfile[] [static] |
char usage_tddmode[] [static] |
char usage_verbose[] [static] |
char usage_waitfordigit[] [static] |