#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"
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_SUCCESS, AGI_RESULT_SUCCESS_FAST, 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 *efd2, 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) |
static int | xagi_exec (struct ast_channel *chan, void *data) |
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 [] |
static char * | xapp = "XAGI" |
static char * | xsynopsis = "Executes an XAGI compliant application" |
Definition in file res_agi.c.
#define AGI_BUF_LEN 2048 |
#define AGI_PORT 4573 |
#define fdprintf agi_debug_cli |
Definition at line 77 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 |
Definition at line 72 of file res_agi.c.
Referenced by ast_agi_register(), and ast_agi_unregister().
enum agi_result |
Definition at line 122 of file res_agi.c.
00122 { 00123 AGI_RESULT_SUCCESS, 00124 AGI_RESULT_SUCCESS_FAST, 00125 AGI_RESULT_FAILURE, 00126 AGI_RESULT_HANGUP 00127 };
static int agi_debug_cli | ( | int | fd, | |
char * | fmt, | |||
... | ||||
) | [static] |
Definition at line 129 of file res_agi.c.
References ast_carefulwrite(), ast_log(), ast_verbose(), free, LOG_ERROR, ast_variable::stuff, and vasprintf.
00130 { 00131 char *stuff; 00132 int res = 0; 00133 00134 va_list ap; 00135 va_start(ap, fmt); 00136 res = vasprintf(&stuff, fmt, ap); 00137 va_end(ap); 00138 if (res == -1) { 00139 ast_log(LOG_ERROR, "Out of memory\n"); 00140 } else { 00141 if (agidebug) 00142 ast_verbose("AGI Tx >> %s", stuff); /* \n provided by caller */ 00143 res = ast_carefulwrite(fd, stuff, strlen(stuff), 100); 00144 free(stuff); 00145 } 00146 00147 return res; 00148 }
static int agi_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1366 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01367 { 01368 if (argc != 2) 01369 return RESULT_SHOWUSAGE; 01370 agidebug = 1; 01371 ast_cli(fd, "AGI Debugging Enabled\n"); 01372 return RESULT_SUCCESS; 01373 }
static int agi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2178 of file res_agi.c.
References ast_channel::_softhangup, agi_exec_full(), ast_log(), and LOG_WARNING.
Referenced by load_module().
02179 { 02180 if (chan->_softhangup) 02181 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02182 return agi_exec_full(chan, data, 0, 0); 02183 }
static int agi_exec_full | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | enhanced, | |||
int | dead | |||
) | [static] |
Definition at line 2103 of file res_agi.c.
References ast_channel::_state, AGI_BUF_LEN, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, AGI_RESULT_SUCCESS_FAST, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, ast_replace_sigchld(), AST_STATE_UP, ast_strlen_zero(), ast_unreplace_sigchld(), agi_state::audio, agi_state::audio_in, agi_state::ctrl, agi_state::fast, agi_state::fd, launch_script(), LOG_WARNING, MAX_ARGS, pbx_builtin_setvar_helper(), run_agi(), and strsep().
Referenced by agi_exec(), deadagi_exec(), eagi_exec(), and xagi_exec().
02104 { 02105 enum agi_result res; 02106 struct ast_module_user *u; 02107 char *argv[MAX_ARGS]; 02108 char buf[AGI_BUF_LEN] = ""; 02109 char *tmp = (char *)buf; 02110 int argc = 0; 02111 int fds[2]; 02112 int efd = -1; 02113 int efd2 = -1; 02114 int pid; 02115 char *stringp; 02116 AGI agi; 02117 02118 if (ast_strlen_zero(data)) { 02119 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02120 return -1; 02121 } 02122 ast_copy_string(buf, data, sizeof(buf)); 02123 02124 memset(&agi, 0, sizeof(agi)); 02125 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1) 02126 argv[argc++] = stringp; 02127 argv[argc] = NULL; 02128 02129 u = ast_module_user_add(chan); 02130 #if 0 02131 /* Answer if need be */ 02132 if (chan->_state != AST_STATE_UP) { 02133 if (ast_answer(chan)) { 02134 LOCAL_USER_REMOVE(u); 02135 return -1; 02136 } 02137 } 02138 #endif 02139 ast_replace_sigchld(); 02140 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, (enhanced == 2) ? &efd2 : NULL, &pid); 02141 if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) { 02142 int status = 0; 02143 agi.fd = fds[1]; 02144 agi.ctrl = fds[0]; 02145 agi.audio = efd; 02146 agi.audio_in = efd2; 02147 agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0; 02148 res = run_agi(chan, argv[0], &agi, pid, &status, dead); 02149 /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */ 02150 if ((res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) && status) 02151 res = AGI_RESULT_FAILURE; 02152 if (fds[1] != fds[0]) 02153 close(fds[1]); 02154 if (efd > -1) 02155 close(efd); 02156 if (efd2 > -1) 02157 close(efd2); 02158 } 02159 ast_unreplace_sigchld(); 02160 ast_module_user_remove(u); 02161 02162 switch (res) { 02163 case AGI_RESULT_SUCCESS: 02164 case AGI_RESULT_SUCCESS_FAST: 02165 pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS"); 02166 break; 02167 case AGI_RESULT_FAILURE: 02168 pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE"); 02169 break; 02170 case AGI_RESULT_HANGUP: 02171 pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP"); 02172 return -1; 02173 } 02174 02175 return 0; 02176 }
static int agi_handle_command | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
char * | buf | |||
) | [static] |
Definition at line 1848 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().
01849 { 01850 char *argv[MAX_ARGS]; 01851 int argc = MAX_ARGS; 01852 int res; 01853 agi_command *c; 01854 01855 parse_args(buf, &argc, argv); 01856 c = find_command(argv, 0); 01857 if (c) { 01858 res = c->handler(chan, agi, argc, argv); 01859 switch(res) { 01860 case RESULT_SHOWUSAGE: 01861 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01862 fdprintf(agi->fd, c->usage); 01863 fdprintf(agi->fd, "520 End of proper usage.\n"); 01864 break; 01865 case AST_PBX_KEEPALIVE: 01866 /* We've been asked to keep alive, so do so */ 01867 return AST_PBX_KEEPALIVE; 01868 break; 01869 case RESULT_FAILURE: 01870 /* They've already given the failure. We've been hung up on so handle this 01871 appropriately */ 01872 return -1; 01873 } 01874 } else { 01875 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01876 } 01877 return 0; 01878 }
static int agi_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1384 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01385 { 01386 if (argc != 3) 01387 return RESULT_SHOWUSAGE; 01388 agidebug = 0; 01389 ast_cli(fd, "AGI Debugging Disabled\n"); 01390 return RESULT_SUCCESS; 01391 }
static int agi_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1375 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01376 { 01377 if (argc != 3) 01378 return RESULT_SHOWUSAGE; 01379 agidebug = 0; 01380 ast_cli(fd, "AGI Debugging Disabled\n"); 01381 return RESULT_SUCCESS; 01382 }
int ast_agi_register | ( | agi_command * | agi | ) |
Definition at line 1719 of file res_agi.c.
References ast_log(), agi_command::cmda, LOG_WARNING, and MAX_COMMANDS.
01720 { 01721 int x; 01722 for (x=0; x<MAX_COMMANDS - 1; x++) { 01723 if (commands[x].cmda[0] == agi->cmda[0]) { 01724 ast_log(LOG_WARNING, "Command already registered!\n"); 01725 return -1; 01726 } 01727 } 01728 for (x=0; x<MAX_COMMANDS - 1; x++) { 01729 if (!commands[x].cmda[0]) { 01730 commands[x] = *agi; 01731 return 0; 01732 } 01733 } 01734 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01735 return -1; 01736 }
void ast_agi_unregister | ( | agi_command * | agi | ) |
Definition at line 1738 of file res_agi.c.
References agi_command::cmda, and MAX_COMMANDS.
01739 { 01740 int x; 01741 for (x=0; x<MAX_COMMANDS - 1; x++) { 01742 if (commands[x].cmda[0] == agi->cmda[0]) { 01743 memset(&commands[x], 0, sizeof(agi_command)); 01744 } 01745 } 01746 }
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 2235 of file res_agi.c.
References agi_exec_full(), ast_check_hangup(), ast_log(), and LOG_WARNING.
Referenced by load_module().
02236 { 02237 if (!ast_check_hangup(chan)) 02238 ast_log(LOG_WARNING,"Running DeadAGI on a live channel will cause problems, please use AGI\n"); 02239 return agi_exec_full(chan, data, 0, 1); 02240 }
static int eagi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2185 of file res_agi.c.
References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), LOG_WARNING, and ast_channel::readformat.
Referenced by load_module().
02186 { 02187 int readformat; 02188 int res; 02189 02190 if (chan->_softhangup) 02191 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02192 readformat = chan->readformat; 02193 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02194 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02195 return -1; 02196 } 02197 res = agi_exec_full(chan, data, 1, 0); 02198 if (!res) { 02199 if (ast_set_read_format(chan, readformat)) { 02200 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02201 } 02202 } 02203 return res; 02204 }
static agi_command* find_command | ( | char * | cmds[], | |
int | exact | |||
) | [static] |
Definition at line 1748 of file res_agi.c.
References agi_command::cmda, and match().
01749 { 01750 int x; 01751 int y; 01752 int match; 01753 01754 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01755 if (!commands[x].cmda[0]) 01756 break; 01757 /* start optimistic */ 01758 match = 1; 01759 for (y=0; match && cmds[y]; y++) { 01760 /* If there are no more words in the command (and we're looking for 01761 an exact match) or there is a difference between the two words, 01762 then this is not a match */ 01763 if (!commands[x].cmda[y] && !exact) 01764 break; 01765 /* don't segfault if the next part of a command doesn't exist */ 01766 if (!commands[x].cmda[y]) 01767 return NULL; 01768 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01769 match = 0; 01770 } 01771 /* If more words are needed to complete the command then this is not 01772 a candidate (unless we're looking for a really inexact answer */ 01773 if ((exact > -1) && commands[x].cmda[y]) 01774 match = 0; 01775 if (match) 01776 return &commands[x]; 01777 } 01778 return NULL; 01779 }
static int handle_agidumphtml | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2049 of file res_agi.c.
References ast_cli(), ast_join(), agi_command::cmda, RESULT_SHOWUSAGE, RESULT_SUCCESS, strsep(), agi_command::summary, and agi_command::usage.
02050 { 02051 struct agi_command *e; 02052 char fullcmd[80]; 02053 int x; 02054 FILE *htmlfile; 02055 02056 if ((argc < 3)) 02057 return RESULT_SHOWUSAGE; 02058 02059 if (!(htmlfile = fopen(argv[2], "wt"))) { 02060 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 02061 return RESULT_SHOWUSAGE; 02062 } 02063 02064 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 02065 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 02066 02067 02068 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 02069 02070 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 02071 char *stringp, *tempstr; 02072 02073 e = &commands[x]; 02074 if (!e->cmda[0]) /* end ? */ 02075 break; 02076 /* Hide commands that start with '_' */ 02077 if ((e->cmda[0])[0] == '_') 02078 continue; 02079 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 02080 02081 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 02082 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TH></TR>\n", fullcmd,e->summary); 02083 02084 stringp=e->usage; 02085 tempstr = strsep(&stringp, "\n"); 02086 02087 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 02088 02089 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 02090 while ((tempstr = strsep(&stringp, "\n")) != NULL) 02091 fprintf(htmlfile, "%s<BR>\n",tempstr); 02092 fprintf(htmlfile, "</TD></TR>\n"); 02093 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 02094 02095 } 02096 02097 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 02098 fclose(htmlfile); 02099 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 02100 return RESULT_SUCCESS; 02101 }
static int handle_answer | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 454 of file res_agi.c.
References ast_channel::_state, ast_answer(), AST_STATE_UP, agi_state::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS.
00455 { 00456 int res; 00457 res = 0; 00458 if (chan->_state != AST_STATE_UP) { 00459 /* Answer the chan */ 00460 res = ast_answer(chan); 00461 } 00462 fdprintf(agi->fd, "200 result=%d\n", res); 00463 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00464 }
static int handle_autohangup | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1103 of file res_agi.c.
References agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::whentohangup.
01104 { 01105 int timeout; 01106 01107 if (argc != 3) 01108 return RESULT_SHOWUSAGE; 01109 if (sscanf(argv[2], "%d", &timeout) != 1) 01110 return RESULT_SHOWUSAGE; 01111 if (timeout < 0) 01112 timeout = 0; 01113 if (timeout) 01114 chan->whentohangup = time(NULL) + timeout; 01115 else 01116 chan->whentohangup = 0; 01117 fdprintf(agi->fd, "200 result=0\n"); 01118 return RESULT_SUCCESS; 01119 }
static int handle_channelstatus | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1193 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.
01194 { 01195 struct ast_channel *c; 01196 if (argc == 2) { 01197 /* no argument: supply info on the current channel */ 01198 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01199 return RESULT_SUCCESS; 01200 } else if (argc == 3) { 01201 /* one argument: look for info on the specified channel */ 01202 c = ast_get_channel_by_name_locked(argv[2]); 01203 if (c) { 01204 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01205 ast_channel_unlock(c); 01206 return RESULT_SUCCESS; 01207 } 01208 /* if we get this far no channel name matched the argument given */ 01209 fdprintf(agi->fd, "200 result=-1\n"); 01210 return RESULT_SUCCESS; 01211 } else { 01212 return RESULT_SHOWUSAGE; 01213 } 01214 }
static int handle_controlstreamfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 565 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.
00566 { 00567 int res = 0; 00568 int skipms = 3000; 00569 char *fwd = NULL; 00570 char *rev = NULL; 00571 char *pause = NULL; 00572 char *stop = NULL; 00573 00574 if (argc < 5 || argc > 9) 00575 return RESULT_SHOWUSAGE; 00576 00577 if (!ast_strlen_zero(argv[4])) 00578 stop = argv[4]; 00579 else 00580 stop = NULL; 00581 00582 if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) 00583 return RESULT_SHOWUSAGE; 00584 00585 if (argc > 6 && !ast_strlen_zero(argv[6])) 00586 fwd = argv[6]; 00587 else 00588 fwd = "#"; 00589 00590 if (argc > 7 && !ast_strlen_zero(argv[7])) 00591 rev = argv[7]; 00592 else 00593 rev = "*"; 00594 00595 if (argc > 8 && !ast_strlen_zero(argv[8])) 00596 pause = argv[8]; 00597 else 00598 pause = NULL; 00599 00600 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); 00601 00602 fdprintf(agi->fd, "200 result=%d\n", res); 00603 00604 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00605 }
static int handle_dbdel | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1333 of file res_agi.c.
References ast_db_del(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01334 { 01335 int res; 01336 01337 if (argc != 4) 01338 return RESULT_SHOWUSAGE; 01339 res = ast_db_del(argv[2], argv[3]); 01340 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01341 return RESULT_SUCCESS; 01342 }
static int handle_dbdeltree | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1344 of file res_agi.c.
References ast_db_deltree(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01345 { 01346 int res; 01347 if ((argc < 3) || (argc > 4)) 01348 return RESULT_SHOWUSAGE; 01349 if (argc == 4) 01350 res = ast_db_deltree(argv[2], argv[3]); 01351 else 01352 res = ast_db_deltree(argv[2], NULL); 01353 01354 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01355 return RESULT_SUCCESS; 01356 }
static int handle_dbget | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1306 of file res_agi.c.
References ast_db_get(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01307 { 01308 int res; 01309 char tmp[256]; 01310 01311 if (argc != 4) 01312 return RESULT_SHOWUSAGE; 01313 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01314 if (res) 01315 fdprintf(agi->fd, "200 result=0\n"); 01316 else 01317 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01318 01319 return RESULT_SUCCESS; 01320 }
static int handle_dbput | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1322 of file res_agi.c.
References ast_db_put(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01323 { 01324 int res; 01325 01326 if (argc != 5) 01327 return RESULT_SHOWUSAGE; 01328 res = ast_db_put(argv[2], argv[3], argv[4]); 01329 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01330 return RESULT_SUCCESS; 01331 }
static int handle_exec | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1147 of file res_agi.c.
References ast_log(), ast_verbose(), agi_state::fd, fdprintf, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), RESULT_SHOWUSAGE, and VERBOSE_PREFIX_3.
01148 { 01149 int res; 01150 struct ast_app *app; 01151 01152 if (argc < 2) 01153 return RESULT_SHOWUSAGE; 01154 01155 if (option_verbose > 2) 01156 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01157 01158 app = pbx_findapp(argv[1]); 01159 01160 if (app) { 01161 res = pbx_exec(chan, app, argv[2]); 01162 } else { 01163 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01164 res = -2; 01165 } 01166 fdprintf(agi->fd, "200 result=%d\n", res); 01167 01168 /* Even though this is wrong, users are depending upon this result. */ 01169 return res; 01170 }
static int handle_getdata | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 862 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.
00863 { 00864 int res; 00865 char data[1024]; 00866 int max; 00867 int timeout; 00868 00869 if (argc < 3) 00870 return RESULT_SHOWUSAGE; 00871 if (argc >= 4) 00872 timeout = atoi(argv[3]); 00873 else 00874 timeout = 0; 00875 if (argc >= 5) 00876 max = atoi(argv[4]); 00877 else 00878 max = 1024; 00879 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00880 if (res == 2) /* New command */ 00881 return RESULT_SUCCESS; 00882 else if (res == 1) 00883 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00884 else if (res < 0 ) 00885 fdprintf(agi->fd, "200 result=-1\n"); 00886 else 00887 fdprintf(agi->fd, "200 result=%s\n", data); 00888 return RESULT_SUCCESS; 00889 }
static int handle_getoption | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 663 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, VERBOSE_PREFIX_3, and ast_filestream::vfs.
00664 { 00665 int res; 00666 int vres; 00667 struct ast_filestream *fs; 00668 struct ast_filestream *vfs; 00669 long sample_offset = 0; 00670 long max_length; 00671 int timeout = 0; 00672 char *edigits = ""; 00673 00674 if ( argc < 4 || argc > 5 ) 00675 return RESULT_SHOWUSAGE; 00676 00677 if ( argv[3] ) 00678 edigits = argv[3]; 00679 00680 if ( argc == 5 ) 00681 timeout = atoi(argv[4]); 00682 else if (chan->pbx->dtimeout) { 00683 /* by default dtimeout is set to 5sec */ 00684 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00685 } 00686 00687 fs = ast_openstream(chan, argv[2], chan->language); 00688 if (!fs) { 00689 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00690 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00691 return RESULT_SUCCESS; 00692 } 00693 vfs = ast_openvstream(chan, argv[2], chan->language); 00694 if (vfs) 00695 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00696 00697 if (option_verbose > 2) 00698 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00699 00700 ast_seekstream(fs, 0, SEEK_END); 00701 max_length = ast_tellstream(fs); 00702 ast_seekstream(fs, sample_offset, SEEK_SET); 00703 res = ast_applystream(chan, fs); 00704 if (vfs) 00705 vres = ast_applystream(chan, vfs); 00706 ast_playstream(fs); 00707 if (vfs) 00708 ast_playstream(vfs); 00709 00710 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00711 /* this is to check for if ast_waitstream closed the stream, we probably are at 00712 * the end of the stream, return that amount, else check for the amount */ 00713 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00714 ast_stopstream(chan); 00715 if (res == 1) { 00716 /* Stop this command, don't print a result line, as there is a new command */ 00717 return RESULT_SUCCESS; 00718 } 00719 00720 /* If the user didnt press a key, wait for digitTimeout*/ 00721 if (res == 0 ) { 00722 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00723 /* Make sure the new result is in the escape digits of the GET OPTION */ 00724 if ( !strchr(edigits,res) ) 00725 res=0; 00726 } 00727 00728 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00729 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00730 }
static int handle_getvariable | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1225 of file res_agi.c.
References ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01226 { 01227 char *ret; 01228 char tempstr[1024]; 01229 01230 if (argc != 3) 01231 return RESULT_SHOWUSAGE; 01232 01233 /* check if we want to execute an ast_custom_function */ 01234 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01235 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr; 01236 } else { 01237 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01238 } 01239 01240 if (ret) 01241 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01242 else 01243 fdprintf(agi->fd, "200 result=0\n"); 01244 01245 return RESULT_SUCCESS; 01246 }
static int handle_getvariablefull | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1248 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.
01249 { 01250 char tmp[4096] = ""; 01251 struct ast_channel *chan2=NULL; 01252 01253 if ((argc != 4) && (argc != 5)) 01254 return RESULT_SHOWUSAGE; 01255 if (argc == 5) { 01256 chan2 = ast_get_channel_by_name_locked(argv[4]); 01257 } else { 01258 chan2 = chan; 01259 } 01260 if (chan2) { 01261 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01262 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01263 } else { 01264 fdprintf(agi->fd, "200 result=0\n"); 01265 } 01266 if (chan2 && (chan2 != chan)) 01267 ast_channel_unlock(chan2); 01268 return RESULT_SUCCESS; 01269 }
static int handle_hangup | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1121 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.
01122 { 01123 struct ast_channel *c; 01124 if (argc == 1) { 01125 /* no argument: hangup the current channel */ 01126 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01127 fdprintf(agi->fd, "200 result=1\n"); 01128 return RESULT_SUCCESS; 01129 } else if (argc == 2) { 01130 /* one argument: look for info on the specified channel */ 01131 c = ast_get_channel_by_name_locked(argv[1]); 01132 if (c) { 01133 /* we have a matching channel */ 01134 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01135 fdprintf(agi->fd, "200 result=1\n"); 01136 ast_channel_unlock(c); 01137 return RESULT_SUCCESS; 01138 } 01139 /* if we get this far no channel name matched the argument given */ 01140 fdprintf(agi->fd, "200 result=-1\n"); 01141 return RESULT_SUCCESS; 01142 } else { 01143 return RESULT_SHOWUSAGE; 01144 } 01145 }
static int handle_noop | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | arg, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1393 of file res_agi.c.
References agi_state::fd, fdprintf, and RESULT_SUCCESS.
01394 { 01395 fdprintf(agi->fd, "200 result=0\n"); 01396 return RESULT_SUCCESS; 01397 }
static int handle_recordfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 926 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, ast_frame::frametype, LOG_WARNING, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, ast_frame::subclass, and ast_dsp::totalsilence.
00927 { 00928 struct ast_filestream *fs; 00929 struct ast_frame *f; 00930 struct timeval start; 00931 long sample_offset = 0; 00932 int res = 0; 00933 int ms; 00934 00935 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00936 int totalsilence = 0; 00937 int dspsilence = 0; 00938 int silence = 0; /* amount of silence to allow */ 00939 int gotsilence = 0; /* did we timeout for silence? */ 00940 char *silencestr=NULL; 00941 int rfmt=0; 00942 00943 00944 /* XXX EAGI FIXME XXX */ 00945 00946 if (argc < 6) 00947 return RESULT_SHOWUSAGE; 00948 if (sscanf(argv[5], "%d", &ms) != 1) 00949 return RESULT_SHOWUSAGE; 00950 00951 if (argc > 6) 00952 silencestr = strchr(argv[6],'s'); 00953 if ((argc > 7) && (!silencestr)) 00954 silencestr = strchr(argv[7],'s'); 00955 if ((argc > 8) && (!silencestr)) 00956 silencestr = strchr(argv[8],'s'); 00957 00958 if (silencestr) { 00959 if (strlen(silencestr) > 2) { 00960 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00961 silencestr++; 00962 silencestr++; 00963 if (silencestr) 00964 silence = atoi(silencestr); 00965 if (silence > 0) 00966 silence *= 1000; 00967 } 00968 } 00969 } 00970 00971 if (silence > 0) { 00972 rfmt = chan->readformat; 00973 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00974 if (res < 0) { 00975 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00976 return -1; 00977 } 00978 sildet = ast_dsp_new(); 00979 if (!sildet) { 00980 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00981 return -1; 00982 } 00983 ast_dsp_set_threshold(sildet, 256); 00984 } 00985 00986 /* backward compatibility, if no offset given, arg[6] would have been 00987 * caught below and taken to be a beep, else if it is a digit then it is a 00988 * offset */ 00989 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00990 res = ast_streamfile(chan, "beep", chan->language); 00991 00992 if ((argc > 7) && (!strchr(argv[7], '='))) 00993 res = ast_streamfile(chan, "beep", chan->language); 00994 00995 if (!res) 00996 res = ast_waitstream(chan, argv[4]); 00997 if (res) { 00998 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00999 } else { 01000 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644); 01001 if (!fs) { 01002 res = -1; 01003 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 01004 if (sildet) 01005 ast_dsp_free(sildet); 01006 return RESULT_FAILURE; 01007 } 01008 01009 /* Request a video update */ 01010 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 01011 01012 chan->stream = fs; 01013 ast_applystream(chan,fs); 01014 /* really should have checks */ 01015 ast_seekstream(fs, sample_offset, SEEK_SET); 01016 ast_truncstream(fs); 01017 01018 start = ast_tvnow(); 01019 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 01020 res = ast_waitfor(chan, -1); 01021 if (res < 0) { 01022 ast_closestream(fs); 01023 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 01024 if (sildet) 01025 ast_dsp_free(sildet); 01026 return RESULT_FAILURE; 01027 } 01028 f = ast_read(chan); 01029 if (!f) { 01030 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", -1, sample_offset); 01031 ast_closestream(fs); 01032 if (sildet) 01033 ast_dsp_free(sildet); 01034 return RESULT_FAILURE; 01035 } 01036 switch(f->frametype) { 01037 case AST_FRAME_DTMF: 01038 if (strchr(argv[4], f->subclass)) { 01039 /* This is an interrupting chracter, so rewind to chop off any small 01040 amount of DTMF that may have been recorded 01041 */ 01042 ast_stream_rewind(fs, 200); 01043 ast_truncstream(fs); 01044 sample_offset = ast_tellstream(fs); 01045 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 01046 ast_closestream(fs); 01047 ast_frfree(f); 01048 if (sildet) 01049 ast_dsp_free(sildet); 01050 return RESULT_SUCCESS; 01051 } 01052 break; 01053 case AST_FRAME_VOICE: 01054 ast_writestream(fs, f); 01055 /* this is a safe place to check progress since we know that fs 01056 * is valid after a write, and it will then have our current 01057 * location */ 01058 sample_offset = ast_tellstream(fs); 01059 if (silence > 0) { 01060 dspsilence = 0; 01061 ast_dsp_silence(sildet, f, &dspsilence); 01062 if (dspsilence) { 01063 totalsilence = dspsilence; 01064 } else { 01065 totalsilence = 0; 01066 } 01067 if (totalsilence > silence) { 01068 /* Ended happily with silence */ 01069 gotsilence = 1; 01070 break; 01071 } 01072 } 01073 break; 01074 case AST_FRAME_VIDEO: 01075 ast_writestream(fs, f); 01076 default: 01077 /* Ignore all other frames */ 01078 break; 01079 } 01080 ast_frfree(f); 01081 if (gotsilence) 01082 break; 01083 } 01084 01085 if (gotsilence) { 01086 ast_stream_rewind(fs, silence-1000); 01087 ast_truncstream(fs); 01088 sample_offset = ast_tellstream(fs); 01089 } 01090 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01091 ast_closestream(fs); 01092 } 01093 01094 if (silence > 0) { 01095 res = ast_set_read_format(chan, rfmt); 01096 if (res) 01097 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01098 ast_dsp_free(sildet); 01099 } 01100 return RESULT_SUCCESS; 01101 }
static int handle_recvchar | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 496 of file res_agi.c.
References ast_recvchar(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00497 { 00498 int res; 00499 if (argc != 3) 00500 return RESULT_SHOWUSAGE; 00501 res = ast_recvchar(chan,atoi(argv[2])); 00502 if (res == 0) { 00503 fdprintf(agi->fd, "200 result=%d (timeout)\n", res); 00504 return RESULT_SUCCESS; 00505 } 00506 if (res > 0) { 00507 fdprintf(agi->fd, "200 result=%d\n", res); 00508 return RESULT_SUCCESS; 00509 } 00510 else { 00511 fdprintf(agi->fd, "200 result=%d (hangup)\n", res); 00512 return RESULT_FAILURE; 00513 } 00514 }
static int handle_recvtext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 516 of file res_agi.c.
References ast_recvtext(), ast_hostent::buf, agi_state::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00517 { 00518 char *buf; 00519 00520 if (argc != 3) 00521 return RESULT_SHOWUSAGE; 00522 buf = ast_recvtext(chan,atoi(argv[2])); 00523 if (buf) { 00524 fdprintf(agi->fd, "200 result=1 (%s)\n", buf); 00525 free(buf); 00526 } else { 00527 fdprintf(agi->fd, "200 result=-1\n"); 00528 } 00529 return RESULT_SUCCESS; 00530 }
static int handle_sayalpha | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 770 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.
00771 { 00772 int res; 00773 00774 if (argc != 4) 00775 return RESULT_SHOWUSAGE; 00776 00777 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00778 if (res == 1) /* New command */ 00779 return RESULT_SUCCESS; 00780 fdprintf(agi->fd, "200 result=%d\n", res); 00781 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00782 }
static int handle_saydate | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 784 of file res_agi.c.
References ast_say_date, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00785 { 00786 int res; 00787 int num; 00788 if (argc != 4) 00789 return RESULT_SHOWUSAGE; 00790 if (sscanf(argv[2], "%d", &num) != 1) 00791 return RESULT_SHOWUSAGE; 00792 res = ast_say_date(chan, num, argv[3], chan->language); 00793 if (res == 1) 00794 return RESULT_SUCCESS; 00795 fdprintf(agi->fd, "200 result=%d\n", res); 00796 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00797 }
static int handle_saydatetime | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 814 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.
00815 { 00816 int res=0; 00817 time_t unixtime; 00818 char *format, *zone=NULL; 00819 00820 if (argc < 4) 00821 return RESULT_SHOWUSAGE; 00822 00823 if (argc > 4) { 00824 format = argv[4]; 00825 } else { 00826 /* XXX this doesn't belong here, but in the 'say' module */ 00827 if (!strcasecmp(chan->language, "de")) { 00828 format = "A dBY HMS"; 00829 } else { 00830 format = "ABdY 'digits/at' IMp"; 00831 } 00832 } 00833 00834 if (argc > 5 && !ast_strlen_zero(argv[5])) 00835 zone = argv[5]; 00836 00837 if (ast_get_time_t(argv[2], &unixtime, 0, NULL)) 00838 return RESULT_SHOWUSAGE; 00839 00840 res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone); 00841 if (res == 1) 00842 return RESULT_SUCCESS; 00843 00844 fdprintf(agi->fd, "200 result=%d\n", res); 00845 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00846 }
static int handle_saydigits | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 753 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.
00754 { 00755 int res; 00756 int num; 00757 00758 if (argc != 4) 00759 return RESULT_SHOWUSAGE; 00760 if (sscanf(argv[2], "%d", &num) != 1) 00761 return RESULT_SHOWUSAGE; 00762 00763 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00764 if (res == 1) /* New command */ 00765 return RESULT_SUCCESS; 00766 fdprintf(agi->fd, "200 result=%d\n", res); 00767 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00768 }
static int handle_saynumber | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 738 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.
00739 { 00740 int res; 00741 int num; 00742 if (argc != 4) 00743 return RESULT_SHOWUSAGE; 00744 if (sscanf(argv[2], "%d", &num) != 1) 00745 return RESULT_SHOWUSAGE; 00746 res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl); 00747 if (res == 1) 00748 return RESULT_SUCCESS; 00749 fdprintf(agi->fd, "200 result=%d\n", res); 00750 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00751 }
static int handle_sayphonetic | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 848 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.
00849 { 00850 int res; 00851 00852 if (argc != 4) 00853 return RESULT_SHOWUSAGE; 00854 00855 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00856 if (res == 1) /* New command */ 00857 return RESULT_SUCCESS; 00858 fdprintf(agi->fd, "200 result=%d\n", res); 00859 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00860 }
static int handle_saytime | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 799 of file res_agi.c.
References ast_say_time, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00800 { 00801 int res; 00802 int num; 00803 if (argc != 4) 00804 return RESULT_SHOWUSAGE; 00805 if (sscanf(argv[2], "%d", &num) != 1) 00806 return RESULT_SHOWUSAGE; 00807 res = ast_say_time(chan, num, argv[3], chan->language); 00808 if (res == 1) 00809 return RESULT_SUCCESS; 00810 fdprintf(agi->fd, "200 result=%d\n", res); 00811 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00812 }
static int handle_sendimage | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 553 of file res_agi.c.
References ast_check_hangup(), ast_send_image(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00554 { 00555 int res; 00556 if (argc != 3) 00557 return RESULT_SHOWUSAGE; 00558 res = ast_send_image(chan, argv[2]); 00559 if (!ast_check_hangup(chan)) 00560 res = 0; 00561 fdprintf(agi->fd, "200 result=%d\n", res); 00562 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00563 }
static int handle_sendtext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 479 of file res_agi.c.
References ast_sendtext(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00480 { 00481 int res; 00482 if (argc != 3) 00483 return RESULT_SHOWUSAGE; 00484 /* At the moment, the parser (perhaps broken) returns with 00485 the last argument PLUS the newline at the end of the input 00486 buffer. This probably needs to be fixed, but I wont do that 00487 because other stuff may break as a result. The right way 00488 would probably be to strip off the trailing newline before 00489 parsing, then here, add a newline at the end of the string 00490 before sending it to ast_sendtext --DUDE */ 00491 res = ast_sendtext(chan, argv[2]); 00492 fdprintf(agi->fd, "200 result=%d\n", res); 00493 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00494 }
static int handle_setcallerid | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1172 of file res_agi.c.
References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, fdprintf, and RESULT_SUCCESS.
01173 { 01174 char tmp[256]=""; 01175 char *l = NULL, *n = NULL; 01176 01177 if (argv[2]) { 01178 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01179 ast_callerid_parse(tmp, &n, &l); 01180 if (l) 01181 ast_shrink_phone_number(l); 01182 else 01183 l = ""; 01184 if (!n) 01185 n = ""; 01186 ast_set_callerid(chan, l, n, NULL); 01187 } 01188 01189 fdprintf(agi->fd, "200 result=1\n"); 01190 return RESULT_SUCCESS; 01191 }
static int handle_setcontext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 891 of file res_agi.c.
References ast_channel::context, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00892 { 00893 00894 if (argc != 3) 00895 return RESULT_SHOWUSAGE; 00896 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00897 fdprintf(agi->fd, "200 result=0\n"); 00898 return RESULT_SUCCESS; 00899 }
static int handle_setextension | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 901 of file res_agi.c.
References ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00902 { 00903 if (argc != 3) 00904 return RESULT_SHOWUSAGE; 00905 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00906 fdprintf(agi->fd, "200 result=0\n"); 00907 return RESULT_SUCCESS; 00908 }
static int handle_setmusic | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1399 of file res_agi.c.
References ast_moh_start(), ast_moh_stop(), agi_state::fd, fdprintf, and RESULT_SUCCESS.
01400 { 01401 if (!strncasecmp(argv[2], "on", 2)) 01402 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL); 01403 else if (!strncasecmp(argv[2], "off", 3)) 01404 ast_moh_stop(chan); 01405 fdprintf(agi->fd, "200 result=0\n"); 01406 return RESULT_SUCCESS; 01407 }
static int handle_setpriority | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 910 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.
00911 { 00912 int pri; 00913 if (argc != 3) 00914 return RESULT_SHOWUSAGE; 00915 00916 if (sscanf(argv[2], "%d", &pri) != 1) { 00917 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00918 return RESULT_SHOWUSAGE; 00919 } 00920 00921 ast_explicit_goto(chan, NULL, NULL, pri); 00922 fdprintf(agi->fd, "200 result=0\n"); 00923 return RESULT_SUCCESS; 00924 }
static int handle_setvariable | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1216 of file res_agi.c.
References agi_state::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS.
01217 { 01218 if (argv[3]) 01219 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01220 01221 fdprintf(agi->fd, "200 result=1\n"); 01222 return RESULT_SUCCESS; 01223 }
static int handle_showagi | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2025 of file res_agi.c.
References ast_cli(), ast_join(), find_command(), help_workhorse(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage.
02026 { 02027 struct agi_command *e; 02028 char fullcmd[80]; 02029 if ((argc < 2)) 02030 return RESULT_SHOWUSAGE; 02031 if (argc > 2) { 02032 e = find_command(argv + 2, 1); 02033 if (e) 02034 ast_cli(fd, e->usage); 02035 else { 02036 if (find_command(argv + 2, -1)) { 02037 return help_workhorse(fd, argv + 1); 02038 } else { 02039 ast_join(fullcmd, sizeof(fullcmd), argv+1); 02040 ast_cli(fd, "No such command '%s'.\n", fullcmd); 02041 } 02042 } 02043 } else { 02044 return help_workhorse(fd, NULL); 02045 } 02046 return RESULT_SUCCESS; 02047 }
static int handle_streamfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 607 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.
00608 { 00609 int res; 00610 int vres; 00611 struct ast_filestream *fs; 00612 struct ast_filestream *vfs; 00613 long sample_offset = 0; 00614 long max_length; 00615 char *edigits = ""; 00616 00617 if (argc < 4 || argc > 5) 00618 return RESULT_SHOWUSAGE; 00619 00620 if (argv[3]) 00621 edigits = argv[3]; 00622 00623 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00624 return RESULT_SHOWUSAGE; 00625 00626 fs = ast_openstream(chan, argv[2], chan->language); 00627 00628 if (!fs) { 00629 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00630 return RESULT_SUCCESS; 00631 } 00632 vfs = ast_openvstream(chan, argv[2], chan->language); 00633 if (vfs) 00634 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00635 00636 if (option_verbose > 2) 00637 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset); 00638 00639 ast_seekstream(fs, 0, SEEK_END); 00640 max_length = ast_tellstream(fs); 00641 ast_seekstream(fs, sample_offset, SEEK_SET); 00642 res = ast_applystream(chan, fs); 00643 if (vfs) 00644 vres = ast_applystream(chan, vfs); 00645 ast_playstream(fs); 00646 if (vfs) 00647 ast_playstream(vfs); 00648 00649 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00650 /* this is to check for if ast_waitstream closed the stream, we probably are at 00651 * the end of the stream, return that amount, else check for the amount */ 00652 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00653 ast_stopstream(chan); 00654 if (res == 1) { 00655 /* Stop this command, don't print a result line, as there is a new command */ 00656 return RESULT_SUCCESS; 00657 } 00658 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00659 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00660 }
static int handle_tddmode | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 532 of file res_agi.c.
References ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00533 { 00534 int res,x; 00535 if (argc != 3) 00536 return RESULT_SHOWUSAGE; 00537 if (!strncasecmp(argv[2],"on",2)) 00538 x = 1; 00539 else 00540 x = 0; 00541 if (!strncasecmp(argv[2],"mate",4)) 00542 x = 2; 00543 if (!strncasecmp(argv[2],"tdd",3)) 00544 x = 1; 00545 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0); 00546 if (res != RESULT_SUCCESS) 00547 fdprintf(agi->fd, "200 result=0\n"); 00548 else 00549 fdprintf(agi->fd, "200 result=1\n"); 00550 return RESULT_SUCCESS; 00551 }
static int handle_verbose | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1271 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.
01272 { 01273 int level = 0; 01274 char *prefix; 01275 01276 if (argc < 2) 01277 return RESULT_SHOWUSAGE; 01278 01279 if (argv[2]) 01280 sscanf(argv[2], "%d", &level); 01281 01282 switch (level) { 01283 case 4: 01284 prefix = VERBOSE_PREFIX_4; 01285 break; 01286 case 3: 01287 prefix = VERBOSE_PREFIX_3; 01288 break; 01289 case 2: 01290 prefix = VERBOSE_PREFIX_2; 01291 break; 01292 case 1: 01293 default: 01294 prefix = VERBOSE_PREFIX_1; 01295 break; 01296 } 01297 01298 if (level <= option_verbose) 01299 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01300 01301 fdprintf(agi->fd, "200 result=1\n"); 01302 01303 return RESULT_SUCCESS; 01304 }
static int handle_waitfordigit | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 466 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.
00467 { 00468 int res; 00469 int to; 00470 if (argc != 4) 00471 return RESULT_SHOWUSAGE; 00472 if (sscanf(argv[3], "%d", &to) != 1) 00473 return RESULT_SHOWUSAGE; 00474 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); 00475 fdprintf(agi->fd, "200 result=%d\n", res); 00476 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00477 }
static int help_workhorse | ( | int | fd, | |
char * | match[] | |||
) | [static] |
Definition at line 1696 of file res_agi.c.
References ast_cli(), ast_join(), agi_command::cmda, and agi_command::summary.
01697 { 01698 char fullcmd[80]; 01699 char matchstr[80]; 01700 int x; 01701 struct agi_command *e; 01702 if (match) 01703 ast_join(matchstr, sizeof(matchstr), match); 01704 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01705 e = &commands[x]; 01706 if (!e->cmda[0]) 01707 break; 01708 /* Hide commands that start with '_' */ 01709 if ((e->cmda[0])[0] == '_') 01710 continue; 01711 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01712 if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr))) 01713 continue; 01714 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01715 } 01716 return 0; 01717 }
static enum agi_result launch_netscript | ( | char * | agiurl, | |
char * | argv[], | |||
int * | fds, | |||
int * | efd, | |||
int * | opid | |||
) | [static] |
Definition at line 152 of file res_agi.c.
References AGI_PORT, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS_FAST, 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().
00153 { 00154 int s; 00155 int flags; 00156 struct pollfd pfds[1]; 00157 char *host; 00158 char *c; int port = AGI_PORT; 00159 char *script=""; 00160 struct sockaddr_in sin; 00161 struct hostent *hp; 00162 struct ast_hostent ahp; 00163 int res; 00164 00165 /* agiusl is "agi://host.domain[:port][/script/name]" */ 00166 host = ast_strdupa(agiurl + 6); /* Remove agi:// */ 00167 /* Strip off any script name */ 00168 if ((c = strchr(host, '/'))) { 00169 *c = '\0'; 00170 c++; 00171 script = c; 00172 } 00173 if ((c = strchr(host, ':'))) { 00174 *c = '\0'; 00175 c++; 00176 port = atoi(c); 00177 } 00178 if (efd) { 00179 ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n"); 00180 return -1; 00181 } 00182 hp = ast_gethostbyname(host, &ahp); 00183 if (!hp) { 00184 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host); 00185 return -1; 00186 } 00187 s = socket(AF_INET, SOCK_STREAM, 0); 00188 if (s < 0) { 00189 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 00190 return -1; 00191 } 00192 flags = fcntl(s, F_GETFL); 00193 if (flags < 0) { 00194 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno)); 00195 close(s); 00196 return -1; 00197 } 00198 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { 00199 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno)); 00200 close(s); 00201 return -1; 00202 } 00203 memset(&sin, 0, sizeof(sin)); 00204 sin.sin_family = AF_INET; 00205 sin.sin_port = htons(port); 00206 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00207 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) { 00208 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno)); 00209 close(s); 00210 return AGI_RESULT_FAILURE; 00211 } 00212 00213 pfds[0].fd = s; 00214 pfds[0].events = POLLOUT; 00215 while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) { 00216 if (errno != EINTR) { 00217 if (!res) { 00218 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n", 00219 agiurl, MAX_AGI_CONNECT); 00220 } else 00221 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00222 close(s); 00223 return AGI_RESULT_FAILURE; 00224 } 00225 } 00226 00227 if (fdprintf(s, "agi_network: yes\n") < 0) { 00228 if (errno != EINTR) { 00229 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00230 close(s); 00231 return AGI_RESULT_FAILURE; 00232 } 00233 } 00234 00235 /* If we have a script parameter, relay it to the fastagi server */ 00236 if (!ast_strlen_zero(script)) 00237 fdprintf(s, "agi_network_script: %s\n", script); 00238 00239 if (option_debug > 3) 00240 ast_log(LOG_DEBUG, "Wow, connected!\n"); 00241 fds[0] = s; 00242 fds[1] = s; 00243 *opid = -1; 00244 return AGI_RESULT_SUCCESS_FAST; 00245 }
static enum agi_result launch_script | ( | char * | script, | |
char * | argv[], | |||
int * | fds, | |||
int * | efd, | |||
int * | efd2, | |||
int * | opid | |||
) | [static] |
Definition at line 247 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, setenv(), and VERBOSE_PREFIX_3.
Referenced by agi_exec_full().
00248 { 00249 char tmp[256]; 00250 int pid; 00251 int toast[2]; 00252 int fromast[2]; 00253 int audio[2]; 00254 int audio2[2]; 00255 int x; 00256 int res; 00257 sigset_t signal_set, old_set; 00258 00259 if (!strncasecmp(script, "agi://", 6)) 00260 return launch_netscript(script, argv, fds, efd, opid); 00261 00262 if (script[0] != '/') { 00263 snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script); 00264 script = tmp; 00265 } 00266 if (pipe(toast)) { 00267 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno)); 00268 return AGI_RESULT_FAILURE; 00269 } 00270 if (pipe(fromast)) { 00271 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno)); 00272 close(toast[0]); 00273 close(toast[1]); 00274 return AGI_RESULT_FAILURE; 00275 } 00276 if (efd) { 00277 if (pipe(audio)) { 00278 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00279 close(fromast[0]); 00280 close(fromast[1]); 00281 close(toast[0]); 00282 close(toast[1]); 00283 return AGI_RESULT_FAILURE; 00284 } 00285 res = fcntl(audio[1], F_GETFL); 00286 if (res > -1) 00287 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK); 00288 if (res < 0) { 00289 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00290 close(fromast[0]); 00291 close(fromast[1]); 00292 close(toast[0]); 00293 close(toast[1]); 00294 close(audio[0]); 00295 close(audio[1]); 00296 return AGI_RESULT_FAILURE; 00297 } 00298 } 00299 if (efd2) { 00300 if (pipe(audio2)) { 00301 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00302 close(fromast[0]); 00303 close(fromast[1]); 00304 close(toast[0]); 00305 close(toast[1]); 00306 close(audio[0]); 00307 close(audio[1]); 00308 return AGI_RESULT_FAILURE; 00309 } 00310 res = fcntl(audio2[0], F_GETFL); 00311 if (res > -1) 00312 res = fcntl(audio2[0], F_SETFL, res | O_NONBLOCK); 00313 if (res < 0) { 00314 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00315 close(fromast[0]); 00316 close(fromast[1]); 00317 close(toast[0]); 00318 close(toast[1]); 00319 close(audio[0]); 00320 close(audio[1]); 00321 close(audio2[0]); 00322 close(audio2[1]); 00323 return AGI_RESULT_FAILURE; 00324 } 00325 } 00326 00327 /* Block SIGHUP during the fork - prevents a race */ 00328 sigfillset(&signal_set); 00329 pthread_sigmask(SIG_BLOCK, &signal_set, &old_set); 00330 pid = fork(); 00331 if (pid < 0) { 00332 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); 00333 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00334 return AGI_RESULT_FAILURE; 00335 } 00336 if (!pid) { 00337 /* Pass paths to AGI via environmental variables */ 00338 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1); 00339 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1); 00340 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1); 00341 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1); 00342 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1); 00343 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1); 00344 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1); 00345 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1); 00346 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1); 00347 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1); 00348 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1); 00349 00350 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ 00351 ast_set_priority(0); 00352 00353 /* Redirect stdin and out, provide enhanced audio channel if desired */ 00354 dup2(fromast[0], STDIN_FILENO); 00355 dup2(toast[1], STDOUT_FILENO); 00356 if (efd) { 00357 dup2(audio[0], STDERR_FILENO + 1); 00358 } else { 00359 close(STDERR_FILENO + 1); 00360 } 00361 if (efd2) { 00362 dup2(audio2[1], STDERR_FILENO + 2); 00363 } else { 00364 close(STDERR_FILENO + 2); 00365 } 00366 00367 /* Before we unblock our signals, return our trapped signals back to the defaults */ 00368 signal(SIGHUP, SIG_DFL); 00369 signal(SIGCHLD, SIG_DFL); 00370 signal(SIGINT, SIG_DFL); 00371 signal(SIGURG, SIG_DFL); 00372 signal(SIGTERM, SIG_DFL); 00373 signal(SIGPIPE, SIG_DFL); 00374 signal(SIGXFSZ, SIG_DFL); 00375 00376 /* unblock important signal handlers */ 00377 if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { 00378 ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); 00379 _exit(1); 00380 } 00381 00382 /* Close everything but stdin/out/error */ 00383 for (x=STDERR_FILENO + 3;x<1024;x++) 00384 close(x); 00385 00386 /* Execute script */ 00387 execv(script, argv); 00388 /* Can't use ast_log since FD's are closed */ 00389 fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno)); 00390 /* Special case to set status of AGI to failure */ 00391 fprintf(stdout, "failure\n"); 00392 fflush(stdout); 00393 _exit(1); 00394 } 00395 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00396 if (option_verbose > 2) 00397 ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); 00398 fds[0] = toast[0]; 00399 fds[1] = fromast[1]; 00400 if (efd) { 00401 *efd = audio[1]; 00402 } 00403 if (efd2) { 00404 *efd2 = audio2[0]; 00405 } 00406 /* close what we're not using in the parent */ 00407 close(toast[1]); 00408 close(fromast[0]); 00409 00410 if (efd) { 00411 close(audio[0]); 00412 } 00413 if (efd2) { 00414 close(audio2[1]); 00415 } 00416 00417 *opid = pid; 00418 return AGI_RESULT_SUCCESS; 00419 }
static int load_module | ( | void | ) | [static] |
Definition at line 2296 of file res_agi.c.
References agi_exec(), ast_cli_register_multiple(), ast_register_application(), deadagi_exec(), eagi_exec(), and xagi_exec().
02297 { 02298 ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02299 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02300 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02301 ast_register_application(xapp, xagi_exec, xsynopsis, descrip); 02302 return ast_register_application(app, agi_exec, synopsis, descrip); 02303 }
static int parse_args | ( | char * | s, | |
int * | max, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1782 of file res_agi.c.
References ast_log(), LOG_WARNING, and MAX_ARGS.
01783 { 01784 int x=0; 01785 int quoted=0; 01786 int escaped=0; 01787 int whitespace=1; 01788 char *cur; 01789 01790 cur = s; 01791 while(*s) { 01792 switch(*s) { 01793 case '"': 01794 /* If it's escaped, put a literal quote */ 01795 if (escaped) 01796 goto normal; 01797 else 01798 quoted = !quoted; 01799 if (quoted && whitespace) { 01800 /* If we're starting a quote, coming off white space start a new word, too */ 01801 argv[x++] = cur; 01802 whitespace=0; 01803 } 01804 escaped = 0; 01805 break; 01806 case ' ': 01807 case '\t': 01808 if (!quoted && !escaped) { 01809 /* If we're not quoted, mark this as whitespace, and 01810 end the previous argument */ 01811 whitespace = 1; 01812 *(cur++) = '\0'; 01813 } else 01814 /* Otherwise, just treat it as anything else */ 01815 goto normal; 01816 break; 01817 case '\\': 01818 /* If we're escaped, print a literal, otherwise enable escaping */ 01819 if (escaped) { 01820 goto normal; 01821 } else { 01822 escaped=1; 01823 } 01824 break; 01825 default: 01826 normal: 01827 if (whitespace) { 01828 if (x >= MAX_ARGS -1) { 01829 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01830 break; 01831 } 01832 /* Coming off of whitespace, start the next argument */ 01833 argv[x++] = cur; 01834 whitespace=0; 01835 } 01836 *(cur++) = *s; 01837 escaped=0; 01838 } 01839 s++; 01840 } 01841 /* Null terminate */ 01842 *(cur++) = '\0'; 01843 argv[x] = NULL; 01844 *max = x; 01845 return 0; 01846 }
static enum agi_result run_agi | ( | struct ast_channel * | chan, | |
char * | request, | |||
AGI * | agi, | |||
int | pid, | |||
int * | status, | |||
int | dead | |||
) | [static] |
Definition at line 1879 of file res_agi.c.
References AGI_BUF_LEN, agi_handle_command(), AGI_NANDFS_RETRY, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, ast_false(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_strlen_zero(), ast_verbose(), ast_waitfor_nandfds(), ast_write(), agi_state::audio, agi_state::audio_in, agi_state::ctrl, ast_frame::data, ast_frame::datalen, errno, f, agi_state::fast, agi_state::fd, ast_frame::frametype, len, LOG_DEBUG, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), setup_env(), ast_frame::subclass, and VERBOSE_PREFIX_3.
Referenced by agi_exec_full().
01880 { 01881 struct ast_channel *c; 01882 int outfd; 01883 int ms; 01884 enum agi_result returnstatus = AGI_RESULT_SUCCESS; 01885 struct ast_frame *f; 01886 struct ast_frame fr; 01887 char buf[AGI_BUF_LEN]; 01888 char audiobuf[AGI_BUF_LEN]; 01889 char *res = NULL; 01890 int audiobytes; 01891 int fds[2]; 01892 int enhanced = 0; 01893 FILE *readf; 01894 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01895 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01896 int retry = AGI_NANDFS_RETRY; 01897 01898 if (!(readf = fdopen(agi->ctrl, "r"))) { 01899 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01900 if (pid > -1) 01901 kill(pid, SIGHUP); 01902 close(agi->ctrl); 01903 return AGI_RESULT_FAILURE; 01904 } 01905 setlinebuf(readf); 01906 if (agi->audio > -1) { 01907 enhanced = 1; 01908 } 01909 if (agi->audio_in > -1) { 01910 enhanced++; 01911 } 01912 setup_env(chan, request, agi->fd, enhanced); 01913 fds[0] = agi->ctrl; 01914 fds[1] = agi->audio_in; 01915 for (;;) { 01916 ms = -1; 01917 if (agi->audio_in > -1) { 01918 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, fds, 2, NULL, &outfd, &ms); 01919 } else { 01920 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01921 } 01922 if (c) { 01923 retry = AGI_NANDFS_RETRY; 01924 /* Idle the channel until we get a command */ 01925 f = ast_read(c); 01926 if (!f) { 01927 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01928 returnstatus = AGI_RESULT_HANGUP; 01929 break; 01930 } else { 01931 /* If it's voice, write it to the audio pipe */ 01932 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01933 /* Write, ignoring errors */ 01934 write(agi->audio, f->data, f->datalen); 01935 } 01936 ast_frfree(f); 01937 } 01938 } else if (outfd > -1) { 01939 if ((agi->audio_in > -1) && (outfd == agi->audio_in)) { 01940 audiobytes = read(agi->audio_in, audiobuf, sizeof(audiobuf)); 01941 if (audiobytes > 0) { 01942 fr.frametype = AST_FRAME_VOICE; 01943 fr.subclass = AST_FORMAT_SLINEAR; 01944 fr.datalen = audiobytes; 01945 fr.data = audiobuf; 01946 ast_write(chan, &fr); 01947 } 01948 } else { 01949 size_t len = sizeof(buf); 01950 size_t buflen = 0; 01951 01952 retry = AGI_NANDFS_RETRY; 01953 buf[0] = '\0'; 01954 01955 while (buflen < (len - 1)) { 01956 res = fgets(buf + buflen, len, readf); 01957 if (feof(readf)) 01958 break; 01959 if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN))) 01960 break; 01961 if (res != NULL && !agi->fast) 01962 break; 01963 buflen = strlen(buf); 01964 if (buflen && buf[buflen - 1] == '\n') 01965 break; 01966 len -= buflen; 01967 if (agidebug) 01968 ast_verbose( "AGI Rx << temp buffer %s - errno %s\n", buf, strerror(errno)); 01969 } 01970 01971 if (!buf[0]) { 01972 /* Program terminated */ 01973 if (returnstatus) 01974 returnstatus = -1; 01975 if (option_verbose > 2) 01976 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01977 if (pid > 0) 01978 waitpid(pid, status, 0); 01979 /* No need to kill the pid anymore, since they closed us */ 01980 pid = -1; 01981 break; 01982 } 01983 01984 /* Special case for inability to execute child process */ 01985 if (*buf && strncasecmp(buf, "failure", 7) == 0) { 01986 returnstatus = AGI_RESULT_FAILURE; 01987 break; 01988 } 01989 01990 /* get rid of trailing newline, if any */ 01991 if (*buf && buf[strlen(buf) - 1] == '\n') 01992 buf[strlen(buf) - 1] = 0; 01993 if (agidebug) 01994 ast_verbose("AGI Rx << %s\n", buf); 01995 returnstatus |= agi_handle_command(chan, agi, buf); 01996 /* If the handle_command returns -1, we need to stop */ 01997 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01998 break; 01999 } 02000 } 02001 } else { 02002 if (--retry <= 0) { 02003 ast_log(LOG_WARNING, "No channel, no fd?\n"); 02004 returnstatus = AGI_RESULT_FAILURE; 02005 break; 02006 } 02007 } 02008 } 02009 /* Notify process */ 02010 if (pid > -1) { 02011 const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP"); 02012 if (ast_strlen_zero(sighup) || !ast_false(sighup)) { 02013 if (kill(pid, SIGHUP)) { 02014 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 02015 } else { /* Give the process a chance to die */ 02016 usleep(1); 02017 } 02018 } 02019 waitpid(pid, status, WNOHANG); 02020 } 02021 fclose(readf); 02022 return returnstatus; 02023 }
static void setup_env | ( | struct ast_channel * | chan, | |
char * | request, | |||
int | fd, | |||
int | enhanced | |||
) | [static] |
Definition at line 421 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().
00422 { 00423 /* Print initial environment, with agi_request always being the first 00424 thing */ 00425 fdprintf(fd, "agi_request: %s\n", request); 00426 fdprintf(fd, "agi_channel: %s\n", chan->name); 00427 fdprintf(fd, "agi_language: %s\n", chan->language); 00428 fdprintf(fd, "agi_type: %s\n", chan->tech->type); 00429 fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid); 00430 00431 /* ANI/DNIS */ 00432 fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown")); 00433 fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown")); 00434 fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres); 00435 fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2); 00436 fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton); 00437 fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns); 00438 fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown")); 00439 fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown")); 00440 00441 /* Context information */ 00442 fdprintf(fd, "agi_context: %s\n", chan->context); 00443 fdprintf(fd, "agi_extension: %s\n", chan->exten); 00444 fdprintf(fd, "agi_priority: %d\n", chan->priority); 00445 fdprintf(fd, "agi_enhanced: %d%s\n", enhanced, ".0"); 00446 00447 /* User information */ 00448 fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); 00449 00450 /* End with empty return */ 00451 fdprintf(fd, "\n"); 00452 }
static int unload_module | ( | void | ) | [static] |
Definition at line 2286 of file res_agi.c.
References ast_cli_unregister_multiple(), ast_module_user_hangup_all, and ast_unregister_application().
02287 { 02288 ast_module_user_hangup_all(); 02289 ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02290 ast_unregister_application(xapp); 02291 ast_unregister_application(eapp); 02292 ast_unregister_application(deadapp); 02293 return ast_unregister_application(app); 02294 }
static int xagi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2206 of file res_agi.c.
References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), ast_set_write_format(), LOG_WARNING, ast_channel::readformat, and ast_channel::writeformat.
Referenced by load_module().
02207 { 02208 int readformat, writeformat; 02209 int res; 02210 02211 if (chan->_softhangup) 02212 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02213 readformat = chan->readformat; 02214 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02215 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02216 return -1; 02217 } 02218 writeformat = chan->writeformat; 02219 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 02220 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02221 return -1; 02222 } 02223 res = agi_exec_full(chan, data, 2, 0); 02224 if (!res) { 02225 if (ast_set_read_format(chan, readformat)) { 02226 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02227 } 02228 if (ast_set_write_format(chan, writeformat)) { 02229 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(writeformat)); 02230 } 02231 } 02232 return res; 02233 }
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 1656 of file res_agi.c.
Referenced by aji_dinfo_handler(), and dundi_showframe().
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] |
char* xsynopsis = "Executes an XAGI compliant application" [static] |