![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
res_agi.c File Reference
Definition in file res_agi.c.
#include "asterisk.h"
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/astdb.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/options.h"
#include "asterisk/image.h"
#include "asterisk/say.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/strings.h"
#include "asterisk/agi.h"
Include 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 void | agi_debug_cli (int fd, char *fmt,...) |
| static int | agi_do_debug (int fd, int argc, char *argv[]) |
| static int | agi_exec (struct ast_channel *chan, void *data) |
| static int | agi_exec_full (struct ast_channel *chan, void *data, int enhanced, int dead) |
| static int | agi_handle_command (struct ast_channel *chan, AGI *agi, char *buf) |
| static int | agi_no_debug (int fd, int argc, char *argv[]) |
| int | ast_agi_register (agi_command *agi) |
| void | ast_agi_unregister (agi_command *agi) |
| AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Asterisk Gateway Interface (AGI)") | |
| 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 agi_command | commands [MAX_COMMANDS] |
| static char * | deadapp = "DeadAGI" |
| static char * | deadsynopsis = "Executes AGI on a hungup channel" |
| static const char | debug_usage [] |
| static char * | descrip |
| static char | dumpagihtml_help [] |
| static char * | eapp = "EAGI" |
| static char * | esynopsis = "Executes an EAGI compliant application" |
| static const 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 at line 110 of file res_agi.c. Referenced by launch_netscript(). |
|
|
|
Definition at line 108 of file res_agi.c. Referenced by launch_netscript(). |
|
|
Definition at line 68 of file res_agi.c. Referenced by agi_exec_full(), agi_handle_command(), and parse_args(). |
|
|
Definition at line 69 of file res_agi.c. Referenced by ast_agi_register(), and ast_agi_unregister(). |
|
|
Definition at line 1833 of file res_agi.c. Referenced by run_agi(). |
|
|
|
|
|
Definition at line 112 of file res_agi.c. 00112 { 00113 AGI_RESULT_SUCCESS, 00114 AGI_RESULT_FAILURE, 00115 AGI_RESULT_HANGUP 00116 };
|
|
||||||||||||||||
|
Definition at line 118 of file res_agi.c. References ast_carefulwrite(), ast_log(), ast_verbose(), free, LOG_ERROR, ast_variable::stuff, and vasprintf. 00119 { 00120 char *stuff; 00121 int res = 0; 00122 00123 va_list ap; 00124 va_start(ap, fmt); 00125 res = vasprintf(&stuff, fmt, ap); 00126 va_end(ap); 00127 if (res == -1) { 00128 ast_log(LOG_ERROR, "Out of memory\n"); 00129 } else { 00130 if (agidebug) 00131 ast_verbose("AGI Tx >> %s\n", stuff); 00132 ast_carefulwrite(fd, stuff, strlen(stuff), 100); 00133 free(stuff); 00134 } 00135 }
|
|
||||||||||||||||
|
Definition at line 1329 of file res_agi.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01330 { 01331 if (argc != 2) 01332 return RESULT_SHOWUSAGE; 01333 agidebug = 1; 01334 ast_cli(fd, "AGI Debugging Enabled\n"); 01335 return RESULT_SUCCESS; 01336 }
|
|
||||||||||||
|
Definition at line 2066 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(). 02067 { 02068 if (chan->_softhangup) 02069 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02070 return agi_exec_full(chan, data, 0, 0); 02071 }
|
|
||||||||||||||||||||
|
Definition at line 1998 of file res_agi.c. References ast_channel::_state, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, 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(). 01999 { 02000 enum agi_result res; 02001 struct ast_module_user *u; 02002 char *argv[MAX_ARGS]; 02003 char buf[2048]=""; 02004 char *tmp = buf; 02005 int argc = 0; 02006 int fds[2]; 02007 int efd = -1; 02008 int pid; 02009 char *stringp; 02010 AGI agi; 02011 02012 if (ast_strlen_zero(data)) { 02013 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02014 return -1; 02015 } 02016 ast_copy_string(buf, data, sizeof(buf)); 02017 02018 memset(&agi, 0, sizeof(agi)); 02019 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1) 02020 argv[argc++] = stringp; 02021 argv[argc] = NULL; 02022 02023 u = ast_module_user_add(chan); 02024 #if 0 02025 /* Answer if need be */ 02026 if (chan->_state != AST_STATE_UP) { 02027 if (ast_answer(chan)) { 02028 LOCAL_USER_REMOVE(u); 02029 return -1; 02030 } 02031 } 02032 #endif 02033 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); 02034 if (res == AGI_RESULT_SUCCESS) { 02035 int status = 0; 02036 agi.fd = fds[1]; 02037 agi.ctrl = fds[0]; 02038 agi.audio = efd; 02039 res = run_agi(chan, argv[0], &agi, pid, &status, dead, argc, argv); 02040 /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */ 02041 if (res == AGI_RESULT_SUCCESS && status) 02042 res = AGI_RESULT_FAILURE; 02043 if (fds[1] != fds[0]) 02044 close(fds[1]); 02045 if (efd > -1) 02046 close(efd); 02047 ast_unreplace_sigchld(); 02048 } 02049 ast_module_user_remove(u); 02050 02051 switch (res) { 02052 case AGI_RESULT_SUCCESS: 02053 pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS"); 02054 break; 02055 case AGI_RESULT_FAILURE: 02056 pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE"); 02057 break; 02058 case AGI_RESULT_HANGUP: 02059 pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP"); 02060 return -1; 02061 } 02062 02063 return 0; 02064 }
|
|
||||||||||||||||
|
Definition at line 1802 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(). 01803 { 01804 char *argv[MAX_ARGS]; 01805 int argc = MAX_ARGS; 01806 int res; 01807 agi_command *c; 01808 01809 parse_args(buf, &argc, argv); 01810 c = find_command(argv, 0); 01811 if (c) { 01812 res = c->handler(chan, agi, argc, argv); 01813 switch(res) { 01814 case RESULT_SHOWUSAGE: 01815 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01816 fdprintf(agi->fd, c->usage); 01817 fdprintf(agi->fd, "520 End of proper usage.\n"); 01818 break; 01819 case AST_PBX_KEEPALIVE: 01820 /* We've been asked to keep alive, so do so */ 01821 return AST_PBX_KEEPALIVE; 01822 break; 01823 case RESULT_FAILURE: 01824 /* They've already given the failure. We've been hung up on so handle this 01825 appropriately */ 01826 return -1; 01827 } 01828 } else { 01829 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01830 } 01831 return 0; 01832 }
|
|
||||||||||||||||
|
Definition at line 1338 of file res_agi.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01339 { 01340 if (argc != 2) 01341 return RESULT_SHOWUSAGE; 01342 agidebug = 0; 01343 ast_cli(fd, "AGI Debugging Disabled\n"); 01344 return RESULT_SUCCESS; 01345 }
|
|
|
Definition at line 1673 of file res_agi.c. References ast_log(), agi_command::cmda, commands, LOG_WARNING, and MAX_COMMANDS. 01674 { 01675 int x; 01676 for (x=0; x<MAX_COMMANDS - 1; x++) { 01677 if (commands[x].cmda[0] == agi->cmda[0]) { 01678 ast_log(LOG_WARNING, "Command already registered!\n"); 01679 return -1; 01680 } 01681 } 01682 for (x=0; x<MAX_COMMANDS - 1; x++) { 01683 if (!commands[x].cmda[0]) { 01684 commands[x] = *agi; 01685 return 0; 01686 } 01687 } 01688 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01689 return -1; 01690 }
|
|
|
Definition at line 1692 of file res_agi.c. References agi_command::cmda, commands, and MAX_COMMANDS. 01693 { 01694 int x; 01695 for (x=0; x<MAX_COMMANDS - 1; x++) { 01696 if (commands[x].cmda[0] == agi->cmda[0]) { 01697 memset(&commands[x], 0, sizeof(agi_command)); 01698 } 01699 } 01700 }
|
|
||||||||||||
|
|
|
||||||||||||
|
Definition at line 2094 of file res_agi.c. References agi_exec_full(), and ast_module_user::chan. Referenced by load_module(). 02095 { 02096 return agi_exec_full(chan, data, 0, 1); 02097 }
|
|
||||||||||||
|
Definition at line 2073 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(). 02074 { 02075 int readformat; 02076 int res; 02077 02078 if (chan->_softhangup) 02079 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02080 readformat = chan->readformat; 02081 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02082 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02083 return -1; 02084 } 02085 res = agi_exec_full(chan, data, 1, 0); 02086 if (!res) { 02087 if (ast_set_read_format(chan, readformat)) { 02088 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02089 } 02090 } 02091 return res; 02092 }
|
|
||||||||||||
|
Definition at line 1702 of file res_agi.c. References agi_command::cmda, commands, and match(). 01703 { 01704 int x; 01705 int y; 01706 int match; 01707 01708 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01709 if (!commands[x].cmda[0]) 01710 break; 01711 /* start optimistic */ 01712 match = 1; 01713 for (y=0; match && cmds[y]; y++) { 01714 /* If there are no more words in the command (and we're looking for 01715 an exact match) or there is a difference between the two words, 01716 then this is not a match */ 01717 if (!commands[x].cmda[y] && !exact) 01718 break; 01719 /* don't segfault if the next part of a command doesn't exist */ 01720 if (!commands[x].cmda[y]) 01721 return NULL; 01722 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01723 match = 0; 01724 } 01725 /* If more words are needed to complete the command then this is not 01726 a candidate (unless we're looking for a really inexact answer */ 01727 if ((exact > -1) && commands[x].cmda[y]) 01728 match = 0; 01729 if (match) 01730 return &commands[x]; 01731 } 01732 return NULL; 01733 }
|
|
||||||||||||||||
|
Definition at line 1944 of file res_agi.c. References ast_cli(), ast_join(), agi_command::cmda, commands, RESULT_SHOWUSAGE, strsep(), agi_command::summary, and agi_command::usage. 01945 { 01946 struct agi_command *e; 01947 char fullcmd[80]; 01948 int x; 01949 FILE *htmlfile; 01950 01951 if ((argc < 3)) 01952 return RESULT_SHOWUSAGE; 01953 01954 if (!(htmlfile = fopen(argv[2], "wt"))) { 01955 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 01956 return RESULT_SHOWUSAGE; 01957 } 01958 01959 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 01960 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 01961 01962 01963 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 01964 01965 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01966 char *stringp, *tempstr; 01967 01968 e = &commands[x]; 01969 if (!e->cmda[0]) /* end ? */ 01970 break; 01971 /* Hide commands that start with '_' */ 01972 if ((e->cmda[0])[0] == '_') 01973 continue; 01974 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01975 01976 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 01977 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TD></TR>\n", fullcmd,e->summary); 01978 01979 stringp=e->usage; 01980 tempstr = strsep(&stringp, "\n"); 01981 01982 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 01983 01984 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 01985 while ((tempstr = strsep(&stringp, "\n")) != NULL) 01986 fprintf(htmlfile, "%s<BR>\n",tempstr); 01987 fprintf(htmlfile, "</TD></TR>\n"); 01988 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 01989 01990 } 01991 01992 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 01993 fclose(htmlfile); 01994 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 01995 return RESULT_SUCCESS; 01996 }
|
|
||||||||||||||||||||
|
Definition at line 408 of file res_agi.c. References ast_channel::_state, ast_answer(), AST_STATE_UP, agi_state::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS. 00409 { 00410 int res; 00411 res = 0; 00412 if (chan->_state != AST_STATE_UP) { 00413 /* Answer the chan */ 00414 res = ast_answer(chan); 00415 } 00416 fdprintf(agi->fd, "200 result=%d\n", res); 00417 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00418 }
|
|
||||||||||||||||||||
|
Definition at line 1067 of file res_agi.c. References agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::whentohangup. 01068 { 01069 int timeout; 01070 01071 if (argc != 3) 01072 return RESULT_SHOWUSAGE; 01073 if (sscanf(argv[2], "%d", &timeout) != 1) 01074 return RESULT_SHOWUSAGE; 01075 if (timeout < 0) 01076 timeout = 0; 01077 if (timeout) 01078 chan->whentohangup = time(NULL) + timeout; 01079 else 01080 chan->whentohangup = 0; 01081 fdprintf(agi->fd, "200 result=0\n"); 01082 return RESULT_SUCCESS; 01083 }
|
|
||||||||||||||||||||
|
Definition at line 1156 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. 01157 { 01158 struct ast_channel *c; 01159 if (argc == 2) { 01160 /* no argument: supply info on the current channel */ 01161 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01162 return RESULT_SUCCESS; 01163 } else if (argc == 3) { 01164 /* one argument: look for info on the specified channel */ 01165 c = ast_get_channel_by_name_locked(argv[2]); 01166 if (c) { 01167 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01168 ast_channel_unlock(c); 01169 return RESULT_SUCCESS; 01170 } 01171 /* if we get this far no channel name matched the argument given */ 01172 fdprintf(agi->fd, "200 result=-1\n"); 01173 return RESULT_SUCCESS; 01174 } else { 01175 return RESULT_SHOWUSAGE; 01176 } 01177 }
|
|
||||||||||||||||||||
|
Definition at line 519 of file res_agi.c. References ast_control_streamfile(), ast_strlen_zero(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00520 { 00521 int res = 0; 00522 int skipms = 3000; 00523 char *fwd = NULL; 00524 char *rev = NULL; 00525 char *pause = NULL; 00526 char *stop = NULL; 00527 00528 if (argc < 5 || argc > 9) 00529 return RESULT_SHOWUSAGE; 00530 00531 if (!ast_strlen_zero(argv[4])) 00532 stop = argv[4]; 00533 else 00534 stop = NULL; 00535 00536 if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) 00537 return RESULT_SHOWUSAGE; 00538 00539 if (argc > 6 && !ast_strlen_zero(argv[6])) 00540 fwd = argv[6]; 00541 else 00542 fwd = "#"; 00543 00544 if (argc > 7 && !ast_strlen_zero(argv[7])) 00545 rev = argv[7]; 00546 else 00547 rev = "*"; 00548 00549 if (argc > 8 && !ast_strlen_zero(argv[8])) 00550 pause = argv[8]; 00551 else 00552 pause = NULL; 00553 00554 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); 00555 00556 fdprintf(agi->fd, "200 result=%d\n", res); 00557 00558 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00559 }
|
|
||||||||||||||||||||
|
Definition at line 1296 of file res_agi.c. References ast_db_del(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01297 { 01298 int res; 01299 01300 if (argc != 4) 01301 return RESULT_SHOWUSAGE; 01302 res = ast_db_del(argv[2], argv[3]); 01303 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01304 return RESULT_SUCCESS; 01305 }
|
|
||||||||||||||||||||
|
Definition at line 1307 of file res_agi.c. References ast_db_deltree(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01308 { 01309 int res; 01310 if ((argc < 3) || (argc > 4)) 01311 return RESULT_SHOWUSAGE; 01312 if (argc == 4) 01313 res = ast_db_deltree(argv[2], argv[3]); 01314 else 01315 res = ast_db_deltree(argv[2], NULL); 01316 01317 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01318 return RESULT_SUCCESS; 01319 }
|
|
||||||||||||||||||||
|
Definition at line 1269 of file res_agi.c. References ast_db_get(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01270 { 01271 int res; 01272 char tmp[256]; 01273 01274 if (argc != 4) 01275 return RESULT_SHOWUSAGE; 01276 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01277 if (res) 01278 fdprintf(agi->fd, "200 result=0\n"); 01279 else 01280 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01281 01282 return RESULT_SUCCESS; 01283 }
|
|
||||||||||||||||||||
|
Definition at line 1285 of file res_agi.c. References ast_db_put(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01286 { 01287 int res; 01288 01289 if (argc != 5) 01290 return RESULT_SHOWUSAGE; 01291 res = ast_db_put(argv[2], argv[3], argv[4]); 01292 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01293 return RESULT_SUCCESS; 01294 }
|
|
||||||||||||||||||||
|
Definition at line 1111 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. 01112 { 01113 int res; 01114 struct ast_app *app; 01115 01116 if (argc < 2) 01117 return RESULT_SHOWUSAGE; 01118 01119 if (option_verbose > 2) 01120 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01121 01122 app = pbx_findapp(argv[1]); 01123 01124 if (app) { 01125 res = pbx_exec(chan, app, argv[2]); 01126 } else { 01127 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01128 res = -2; 01129 } 01130 fdprintf(agi->fd, "200 result=%d\n", res); 01131 01132 return res; 01133 }
|
|
||||||||||||||||||||
|
Definition at line 826 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. 00827 { 00828 int res; 00829 char data[1024]; 00830 int max; 00831 int timeout; 00832 00833 if (argc < 3) 00834 return RESULT_SHOWUSAGE; 00835 if (argc >= 4) 00836 timeout = atoi(argv[3]); 00837 else 00838 timeout = 0; 00839 if (argc >= 5) 00840 max = atoi(argv[4]); 00841 else 00842 max = 1024; 00843 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00844 if (res == 2) /* New command */ 00845 return RESULT_SUCCESS; 00846 else if (res == 1) 00847 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00848 else if (res < 0 ) 00849 fdprintf(agi->fd, "200 result=-1\n"); 00850 else 00851 fdprintf(agi->fd, "200 result=%s\n", data); 00852 return RESULT_SUCCESS; 00853 }
|
|
||||||||||||||||||||
|
Definition at line 621 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_debug, option_verbose, ast_channel::pbx, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs. 00622 { 00623 int res; 00624 int vres; 00625 struct ast_filestream *fs; 00626 struct ast_filestream *vfs; 00627 long sample_offset = 0; 00628 long max_length; 00629 int timeout = 0; 00630 char *edigits = ""; 00631 00632 if ( argc < 4 || argc > 5 ) 00633 return RESULT_SHOWUSAGE; 00634 00635 if ( argv[3] ) 00636 edigits = argv[3]; 00637 00638 if ( argc == 5 ) 00639 timeout = atoi(argv[4]); 00640 else if (chan->pbx->dtimeout) { 00641 /* by default dtimeout is set to 5sec */ 00642 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00643 } 00644 00645 fs = ast_openstream(chan, argv[2], chan->language); 00646 if (!fs) { 00647 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00648 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00649 return RESULT_SUCCESS; 00650 } 00651 vfs = ast_openvstream(chan, argv[2], chan->language); 00652 if (vfs && option_debug) 00653 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00654 00655 if (option_verbose > 2) 00656 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00657 00658 ast_seekstream(fs, 0, SEEK_END); 00659 max_length = ast_tellstream(fs); 00660 ast_seekstream(fs, sample_offset, SEEK_SET); 00661 res = ast_applystream(chan, fs); 00662 if (vfs) 00663 vres = ast_applystream(chan, vfs); 00664 res = ast_playstream(fs); 00665 if (vfs) 00666 vres = ast_playstream(vfs); 00667 if (res) { 00668 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00669 if (res >= 0) 00670 return RESULT_SHOWUSAGE; 00671 else 00672 return RESULT_FAILURE; 00673 } 00674 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00675 /* this is to check for if ast_waitstream closed the stream, we probably are at 00676 * the end of the stream, return that amount, else check for the amount */ 00677 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00678 ast_stopstream(chan); 00679 if (res == 1) { 00680 /* Stop this command, don't print a result line, as there is a new command */ 00681 return RESULT_SUCCESS; 00682 } 00683 00684 /* If the user didnt press a key, wait for digitTimeout*/ 00685 if (res == 0 ) { 00686 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00687 /* Make sure the new result is in the escape digits of the GET OPTION */ 00688 if ( !strchr(edigits,res) ) 00689 res=0; 00690 } 00691 00692 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00693 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00694 }
|
|
||||||||||||||||||||
|
Definition at line 1188 of file res_agi.c. References ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01189 { 01190 char *ret; 01191 char tempstr[1024]; 01192 01193 if (argc != 3) 01194 return RESULT_SHOWUSAGE; 01195 01196 /* check if we want to execute an ast_custom_function */ 01197 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01198 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr; 01199 } else { 01200 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01201 } 01202 01203 if (ret) 01204 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01205 else 01206 fdprintf(agi->fd, "200 result=0\n"); 01207 01208 return RESULT_SUCCESS; 01209 }
|
|
||||||||||||||||||||
|
Definition at line 1211 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. 01212 { 01213 char tmp[4096] = ""; 01214 struct ast_channel *chan2=NULL; 01215 01216 if ((argc != 4) && (argc != 5)) 01217 return RESULT_SHOWUSAGE; 01218 if (argc == 5) { 01219 chan2 = ast_get_channel_by_name_locked(argv[4]); 01220 } else { 01221 chan2 = chan; 01222 } 01223 if (chan) { /* XXX isn't this chan2 ? */ 01224 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01225 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01226 } else { 01227 fdprintf(agi->fd, "200 result=0\n"); 01228 } 01229 if (chan2 && (chan2 != chan)) 01230 ast_channel_unlock(chan2); 01231 return RESULT_SUCCESS; 01232 }
|
|
||||||||||||||||||||
|
Definition at line 1085 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. 01086 { 01087 struct ast_channel *c; 01088 if (argc == 1) { 01089 /* no argument: hangup the current channel */ 01090 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01091 fdprintf(agi->fd, "200 result=1\n"); 01092 return RESULT_SUCCESS; 01093 } else if (argc == 2) { 01094 /* one argument: look for info on the specified channel */ 01095 c = ast_get_channel_by_name_locked(argv[1]); 01096 if (c) { 01097 /* we have a matching channel */ 01098 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01099 fdprintf(agi->fd, "200 result=1\n"); 01100 ast_channel_unlock(c); 01101 return RESULT_SUCCESS; 01102 } 01103 /* if we get this far no channel name matched the argument given */ 01104 fdprintf(agi->fd, "200 result=-1\n"); 01105 return RESULT_SUCCESS; 01106 } else { 01107 return RESULT_SHOWUSAGE; 01108 } 01109 }
|
|
||||||||||||||||||||
|
Definition at line 1347 of file res_agi.c. References agi_state::fd, fdprintf, and RESULT_SUCCESS. 01348 { 01349 fdprintf(agi->fd, "200 result=0\n"); 01350 return RESULT_SUCCESS; 01351 }
|
|
||||||||||||||||||||
|
Definition at line 890 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_FILE_MODE, AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), ast_seekstream(), ast_set_read_format(), ast_stream_rewind(), ast_streamfile(), ast_tellstream(), ast_truncstream(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), ast_dsp::f, agi_state::fd, fdprintf, ast_frame::frametype, LOG_WARNING, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, ast_frame::subclass, and ast_dsp::totalsilence. 00891 { 00892 struct ast_filestream *fs; 00893 struct ast_frame *f; 00894 struct timeval start; 00895 long sample_offset = 0; 00896 int res = 0; 00897 int ms; 00898 00899 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00900 int totalsilence = 0; 00901 int dspsilence = 0; 00902 int silence = 0; /* amount of silence to allow */ 00903 int gotsilence = 0; /* did we timeout for silence? */ 00904 char *silencestr=NULL; 00905 int rfmt=0; 00906 00907 00908 /* XXX EAGI FIXME XXX */ 00909 00910 if (argc < 6) 00911 return RESULT_SHOWUSAGE; 00912 if (sscanf(argv[5], "%d", &ms) != 1) 00913 return RESULT_SHOWUSAGE; 00914 00915 if (argc > 6) 00916 silencestr = strchr(argv[6],'s'); 00917 if ((argc > 7) && (!silencestr)) 00918 silencestr = strchr(argv[7],'s'); 00919 if ((argc > 8) && (!silencestr)) 00920 silencestr = strchr(argv[8],'s'); 00921 00922 if (silencestr) { 00923 if (strlen(silencestr) > 2) { 00924 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00925 silencestr++; 00926 silencestr++; 00927 if (silencestr) 00928 silence = atoi(silencestr); 00929 if (silence > 0) 00930 silence *= 1000; 00931 } 00932 } 00933 } 00934 00935 if (silence > 0) { 00936 rfmt = chan->readformat; 00937 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00938 if (res < 0) { 00939 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00940 return -1; 00941 } 00942 sildet = ast_dsp_new(); 00943 if (!sildet) { 00944 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00945 return -1; 00946 } 00947 ast_dsp_set_threshold(sildet, 256); 00948 } 00949 00950 /* backward compatibility, if no offset given, arg[6] would have been 00951 * caught below and taken to be a beep, else if it is a digit then it is a 00952 * offset */ 00953 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00954 res = ast_streamfile(chan, "beep", chan->language); 00955 00956 if ((argc > 7) && (!strchr(argv[7], '='))) 00957 res = ast_streamfile(chan, "beep", chan->language); 00958 00959 if (!res) 00960 res = ast_waitstream(chan, argv[4]); 00961 if (res) { 00962 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00963 } else { 00964 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, AST_FILE_MODE); 00965 if (!fs) { 00966 res = -1; 00967 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 00968 if (sildet) 00969 ast_dsp_free(sildet); 00970 return RESULT_FAILURE; 00971 } 00972 00973 /* Request a video update */ 00974 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00975 00976 chan->stream = fs; 00977 ast_applystream(chan,fs); 00978 /* really should have checks */ 00979 ast_seekstream(fs, sample_offset, SEEK_SET); 00980 ast_truncstream(fs); 00981 00982 start = ast_tvnow(); 00983 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 00984 res = ast_waitfor(chan, -1); 00985 if (res < 0) { 00986 ast_closestream(fs); 00987 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 00988 if (sildet) 00989 ast_dsp_free(sildet); 00990 return RESULT_FAILURE; 00991 } 00992 f = ast_read(chan); 00993 if (!f) { 00994 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset); 00995 ast_closestream(fs); 00996 if (sildet) 00997 ast_dsp_free(sildet); 00998 return RESULT_FAILURE; 00999 } 01000 switch(f->frametype) { 01001 case AST_FRAME_DTMF: 01002 if (strchr(argv[4], f->subclass)) { 01003 /* This is an interrupting chracter, so rewind to chop off any small 01004 amount of DTMF that may have been recorded 01005 */ 01006 ast_stream_rewind(fs, 200); 01007 ast_truncstream(fs); 01008 sample_offset = ast_tellstream(fs); 01009 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 01010 ast_closestream(fs); 01011 ast_frfree(f); 01012 if (sildet) 01013 ast_dsp_free(sildet); 01014 return RESULT_SUCCESS; 01015 } 01016 break; 01017 case AST_FRAME_VOICE: 01018 ast_writestream(fs, f); 01019 /* this is a safe place to check progress since we know that fs 01020 * is valid after a write, and it will then have our current 01021 * location */ 01022 sample_offset = ast_tellstream(fs); 01023 if (silence > 0) { 01024 dspsilence = 0; 01025 ast_dsp_silence(sildet, f, &dspsilence); 01026 if (dspsilence) { 01027 totalsilence = dspsilence; 01028 } else { 01029 totalsilence = 0; 01030 } 01031 if (totalsilence > silence) { 01032 /* Ended happily with silence */ 01033 gotsilence = 1; 01034 break; 01035 } 01036 } 01037 break; 01038 case AST_FRAME_VIDEO: 01039 ast_writestream(fs, f); 01040 default: 01041 /* Ignore all other frames */ 01042 break; 01043 } 01044 ast_frfree(f); 01045 if (gotsilence) 01046 break; 01047 } 01048 01049 if (gotsilence) { 01050 ast_stream_rewind(fs, silence-1000); 01051 ast_truncstream(fs); 01052 sample_offset = ast_tellstream(fs); 01053 } 01054 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01055 ast_closestream(fs); 01056 } 01057 01058 if (silence > 0) { 01059 res = ast_set_read_format(chan, rfmt); 01060 if (res) 01061 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01062 ast_dsp_free(sildet); 01063 } 01064 return RESULT_SUCCESS; 01065 }
|
|
||||||||||||||||||||
|
Definition at line 450 of file res_agi.c. References ast_recvchar(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00451 { 00452 int res; 00453 if (argc != 3) 00454 return RESULT_SHOWUSAGE; 00455 res = ast_recvchar(chan,atoi(argv[2])); 00456 if (res == 0) { 00457 fdprintf(agi->fd, "200 result=%d (timeout)\n", res); 00458 return RESULT_SUCCESS; 00459 } 00460 if (res > 0) { 00461 fdprintf(agi->fd, "200 result=%d\n", res); 00462 return RESULT_SUCCESS; 00463 } 00464 else { 00465 fdprintf(agi->fd, "200 result=%d (hangup)\n", res); 00466 return RESULT_FAILURE; 00467 } 00468 }
|
|
||||||||||||||||||||
|
Definition at line 470 of file res_agi.c. References ast_recvtext(), ast_hostent::buf, agi_state::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00471 { 00472 char *buf; 00473 00474 if (argc != 3) 00475 return RESULT_SHOWUSAGE; 00476 buf = ast_recvtext(chan,atoi(argv[2])); 00477 if (buf) { 00478 fdprintf(agi->fd, "200 result=1 (%s)\n", buf); 00479 free(buf); 00480 } else { 00481 fdprintf(agi->fd, "200 result=-1\n"); 00482 } 00483 return RESULT_SUCCESS; 00484 }
|
|
||||||||||||||||||||
|
Definition at line 734 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. 00735 { 00736 int res; 00737 00738 if (argc != 4) 00739 return RESULT_SHOWUSAGE; 00740 00741 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00742 if (res == 1) /* New command */ 00743 return RESULT_SUCCESS; 00744 fdprintf(agi->fd, "200 result=%d\n", res); 00745 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00746 }
|
|
||||||||||||||||||||
|
Definition at line 748 of file res_agi.c. References ast_say_date, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00749 { 00750 int res; 00751 int num; 00752 if (argc != 4) 00753 return RESULT_SHOWUSAGE; 00754 if (sscanf(argv[2], "%d", &num) != 1) 00755 return RESULT_SHOWUSAGE; 00756 res = ast_say_date(chan, num, argv[3], chan->language); 00757 if (res == 1) 00758 return RESULT_SUCCESS; 00759 fdprintf(agi->fd, "200 result=%d\n", res); 00760 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00761 }
|
|
||||||||||||||||||||
|
Definition at line 778 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. 00779 { 00780 int res=0; 00781 time_t unixtime; 00782 char *format, *zone=NULL; 00783 00784 if (argc < 4) 00785 return RESULT_SHOWUSAGE; 00786 00787 if (argc > 4) { 00788 format = argv[4]; 00789 } else { 00790 /* XXX this doesn't belong here, but in the 'say' module */ 00791 if (!strcasecmp(chan->language, "de")) { 00792 format = "A dBY HMS"; 00793 } else { 00794 format = "ABdY 'digits/at' IMp"; 00795 } 00796 } 00797 00798 if (argc > 5 && !ast_strlen_zero(argv[5])) 00799 zone = argv[5]; 00800 00801 if (ast_get_time_t(argv[2], &unixtime, 0, NULL)) 00802 return RESULT_SHOWUSAGE; 00803 00804 res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone); 00805 if (res == 1) 00806 return RESULT_SUCCESS; 00807 00808 fdprintf(agi->fd, "200 result=%d\n", res); 00809 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00810 }
|
|
||||||||||||||||||||
|
Definition at line 717 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. 00718 { 00719 int res; 00720 int num; 00721 00722 if (argc != 4) 00723 return RESULT_SHOWUSAGE; 00724 if (sscanf(argv[2], "%d", &num) != 1) 00725 return RESULT_SHOWUSAGE; 00726 00727 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00728 if (res == 1) /* New command */ 00729 return RESULT_SUCCESS; 00730 fdprintf(agi->fd, "200 result=%d\n", res); 00731 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00732 }
|
|
||||||||||||||||||||
|
Definition at line 702 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. 00703 { 00704 int res; 00705 int num; 00706 if (argc != 4) 00707 return RESULT_SHOWUSAGE; 00708 if (sscanf(argv[2], "%d", &num) != 1) 00709 return RESULT_SHOWUSAGE; 00710 res = ast_say_number_full(chan, num, argv[3], chan->language, NULL, agi->audio, agi->ctrl); 00711 if (res == 1) 00712 return RESULT_SUCCESS; 00713 fdprintf(agi->fd, "200 result=%d\n", res); 00714 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00715 }
|
|
||||||||||||||||||||
|
Definition at line 812 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. 00813 { 00814 int res; 00815 00816 if (argc != 4) 00817 return RESULT_SHOWUSAGE; 00818 00819 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00820 if (res == 1) /* New command */ 00821 return RESULT_SUCCESS; 00822 fdprintf(agi->fd, "200 result=%d\n", res); 00823 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00824 }
|
|
||||||||||||||||||||
|
Definition at line 763 of file res_agi.c. References ast_say_time, agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00764 { 00765 int res; 00766 int num; 00767 if (argc != 4) 00768 return RESULT_SHOWUSAGE; 00769 if (sscanf(argv[2], "%d", &num) != 1) 00770 return RESULT_SHOWUSAGE; 00771 res = ast_say_time(chan, num, argv[3], chan->language); 00772 if (res == 1) 00773 return RESULT_SUCCESS; 00774 fdprintf(agi->fd, "200 result=%d\n", res); 00775 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00776 }
|
|
||||||||||||||||||||
|
Definition at line 507 of file res_agi.c. References ast_check_hangup(), ast_send_image(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00508 { 00509 int res; 00510 if (argc != 3) 00511 return RESULT_SHOWUSAGE; 00512 res = ast_send_image(chan, argv[2]); 00513 if (!ast_check_hangup(chan)) 00514 res = 0; 00515 fdprintf(agi->fd, "200 result=%d\n", res); 00516 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00517 }
|
|
||||||||||||||||||||
|
Definition at line 433 of file res_agi.c. References ast_sendtext(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00434 { 00435 int res; 00436 if (argc != 3) 00437 return RESULT_SHOWUSAGE; 00438 /* At the moment, the parser (perhaps broken) returns with 00439 the last argument PLUS the newline at the end of the input 00440 buffer. This probably needs to be fixed, but I wont do that 00441 because other stuff may break as a result. The right way 00442 would probably be to strip off the trailing newline before 00443 parsing, then here, add a newline at the end of the string 00444 before sending it to ast_sendtext --DUDE */ 00445 res = ast_sendtext(chan, argv[2]); 00446 fdprintf(agi->fd, "200 result=%d\n", res); 00447 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00448 }
|
|
||||||||||||||||||||
|
Definition at line 1135 of file res_agi.c. References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, fdprintf, and RESULT_SUCCESS. 01136 { 01137 char tmp[256]=""; 01138 char *l = NULL, *n = NULL; 01139 01140 if (argv[2]) { 01141 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01142 ast_callerid_parse(tmp, &n, &l); 01143 if (l) 01144 ast_shrink_phone_number(l); 01145 else 01146 l = ""; 01147 if (!n) 01148 n = ""; 01149 ast_set_callerid(chan, l, n, NULL); 01150 } 01151 01152 fdprintf(agi->fd, "200 result=1\n"); 01153 return RESULT_SUCCESS; 01154 }
|
|
||||||||||||||||||||
|
Definition at line 855 of file res_agi.c. References ast_channel::context, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00856 { 00857 00858 if (argc != 3) 00859 return RESULT_SHOWUSAGE; 00860 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00861 fdprintf(agi->fd, "200 result=0\n"); 00862 return RESULT_SUCCESS; 00863 }
|
|
||||||||||||||||||||
|
Definition at line 865 of file res_agi.c. References ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00866 { 00867 if (argc != 3) 00868 return RESULT_SHOWUSAGE; 00869 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00870 fdprintf(agi->fd, "200 result=0\n"); 00871 return RESULT_SUCCESS; 00872 }
|
|
||||||||||||||||||||
|
Definition at line 1353 of file res_agi.c. References ast_moh_start(), ast_moh_stop(), agi_state::fd, fdprintf, and RESULT_SUCCESS. 01354 { 01355 if (!strncasecmp(argv[2], "on", 2)) 01356 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL); 01357 else if (!strncasecmp(argv[2], "off", 3)) 01358 ast_moh_stop(chan); 01359 fdprintf(agi->fd, "200 result=0\n"); 01360 return RESULT_SUCCESS; 01361 }
|
|
||||||||||||||||||||
|
Definition at line 874 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. 00875 { 00876 int pri; 00877 if (argc != 3) 00878 return RESULT_SHOWUSAGE; 00879 00880 if (sscanf(argv[2], "%d", &pri) != 1) { 00881 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00882 return RESULT_SHOWUSAGE; 00883 } 00884 00885 ast_explicit_goto(chan, NULL, NULL, pri); 00886 fdprintf(agi->fd, "200 result=0\n"); 00887 return RESULT_SUCCESS; 00888 }
|
|
||||||||||||||||||||
|
Definition at line 1179 of file res_agi.c. References agi_state::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS. 01180 { 01181 if (argv[3]) 01182 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01183 01184 fdprintf(agi->fd, "200 result=1\n"); 01185 return RESULT_SUCCESS; 01186 }
|
|
||||||||||||||||
|
Definition at line 1920 of file res_agi.c. References ast_cli(), ast_join(), find_command(), help_workhorse(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage. 01921 { 01922 struct agi_command *e; 01923 char fullcmd[80]; 01924 if ((argc < 2)) 01925 return RESULT_SHOWUSAGE; 01926 if (argc > 2) { 01927 e = find_command(argv + 2, 1); 01928 if (e) 01929 ast_cli(fd, e->usage); 01930 else { 01931 if (find_command(argv + 2, -1)) { 01932 return help_workhorse(fd, argv + 1); 01933 } else { 01934 ast_join(fullcmd, sizeof(fullcmd), argv+1); 01935 ast_cli(fd, "No such command '%s'.\n", fullcmd); 01936 } 01937 } 01938 } else { 01939 return help_workhorse(fd, NULL); 01940 } 01941 return RESULT_SUCCESS; 01942 }
|
|
||||||||||||||||||||
|
Definition at line 561 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_debug, option_verbose, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs. 00562 { 00563 int res; 00564 int vres; 00565 struct ast_filestream *fs; 00566 struct ast_filestream *vfs; 00567 long sample_offset = 0; 00568 long max_length; 00569 char *edigits = ""; 00570 00571 if (argc < 4 || argc > 5) 00572 return RESULT_SHOWUSAGE; 00573 00574 if (argv[3]) 00575 edigits = argv[3]; 00576 00577 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00578 return RESULT_SHOWUSAGE; 00579 00580 fs = ast_openstream(chan, argv[2], chan->language); 00581 00582 if (!fs) { 00583 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00584 return RESULT_SUCCESS; 00585 } 00586 vfs = ast_openvstream(chan, argv[2], chan->language); 00587 if (vfs && option_debug) 00588 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00589 00590 if (option_verbose > 2) 00591 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset); 00592 00593 ast_seekstream(fs, 0, SEEK_END); 00594 max_length = ast_tellstream(fs); 00595 ast_seekstream(fs, sample_offset, SEEK_SET); 00596 res = ast_applystream(chan, fs); 00597 if (vfs) 00598 vres = ast_applystream(chan, vfs); 00599 res = ast_playstream(fs); 00600 if (vfs) 00601 vres = ast_playstream(vfs); 00602 00603 if (res) { 00604 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00605 return (res >= 0) ? RESULT_SHOWUSAGE : RESULT_FAILURE; 00606 } 00607 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00608 /* this is to check for if ast_waitstream closed the stream, we probably are at 00609 * the end of the stream, return that amount, else check for the amount */ 00610 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00611 ast_stopstream(chan); 00612 if (res == 1) { 00613 /* Stop this command, don't print a result line, as there is a new command */ 00614 return RESULT_SUCCESS; 00615 } 00616 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00617 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00618 }
|
|
||||||||||||||||||||
|
Definition at line 486 of file res_agi.c. References ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00487 { 00488 int res,x; 00489 if (argc != 3) 00490 return RESULT_SHOWUSAGE; 00491 if (!strncasecmp(argv[2],"on",2)) 00492 x = 1; 00493 else 00494 x = 0; 00495 if (!strncasecmp(argv[2],"mate",4)) 00496 x = 2; 00497 if (!strncasecmp(argv[2],"tdd",3)) 00498 x = 1; 00499 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0); 00500 if (res != RESULT_SUCCESS) 00501 fdprintf(agi->fd, "200 result=0\n"); 00502 else 00503 fdprintf(agi->fd, "200 result=1\n"); 00504 return RESULT_SUCCESS; 00505 }
|
|
||||||||||||||||||||
|
Definition at line 1234 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. 01235 { 01236 int level = 0; 01237 char *prefix; 01238 01239 if (argc < 2) 01240 return RESULT_SHOWUSAGE; 01241 01242 if (argv[2]) 01243 sscanf(argv[2], "%d", &level); 01244 01245 switch (level) { 01246 case 4: 01247 prefix = VERBOSE_PREFIX_4; 01248 break; 01249 case 3: 01250 prefix = VERBOSE_PREFIX_3; 01251 break; 01252 case 2: 01253 prefix = VERBOSE_PREFIX_2; 01254 break; 01255 case 1: 01256 default: 01257 prefix = VERBOSE_PREFIX_1; 01258 break; 01259 } 01260 01261 if (level <= option_verbose) 01262 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01263 01264 fdprintf(agi->fd, "200 result=1\n"); 01265 01266 return RESULT_SUCCESS; 01267 }
|
|
||||||||||||||||||||
|
Definition at line 420 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. 00421 { 00422 int res; 00423 int to; 00424 if (argc != 4) 00425 return RESULT_SHOWUSAGE; 00426 if (sscanf(argv[3], "%d", &to) != 1) 00427 return RESULT_SHOWUSAGE; 00428 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); 00429 fdprintf(agi->fd, "200 result=%d\n", res); 00430 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00431 }
|
|
||||||||||||
|
Definition at line 1650 of file res_agi.c. References ast_cli(), ast_join(), agi_command::cmda, commands, and agi_command::summary. Referenced by handle_showagi(). 01651 { 01652 char fullcmd[80]; 01653 char matchstr[80]; 01654 int x; 01655 struct agi_command *e; 01656 if (match) 01657 ast_join(matchstr, sizeof(matchstr), match); 01658 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01659 e = &commands[x]; 01660 if (!e->cmda[0]) 01661 break; 01662 /* Hide commands that start with '_' */ 01663 if ((e->cmda[0])[0] == '_') 01664 continue; 01665 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01666 if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr))) 01667 continue; 01668 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01669 } 01670 return 0; 01671 }
|
|
||||||||||||||||||||||||
|
Definition at line 139 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(). 00140 { 00141 int s; 00142 int flags; 00143 struct pollfd pfds[1]; 00144 char *host; 00145 char *c; int port = AGI_PORT; 00146 char *script=""; 00147 struct sockaddr_in sin; 00148 struct hostent *hp; 00149 struct ast_hostent ahp; 00150 int res; 00151 00152 /* agiusl is "agi://host.domain[:port][/script/name]" */ 00153 host = ast_strdupa(agiurl + 6); /* Remove agi:// */ 00154 /* Strip off any script name */ 00155 if ((c = strchr(host, '/'))) { 00156 *c = '\0'; 00157 c++; 00158 script = c; 00159 } 00160 if ((c = strchr(host, ':'))) { 00161 *c = '\0'; 00162 c++; 00163 port = atoi(c); 00164 } 00165 if (efd) { 00166 ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n"); 00167 return -1; 00168 } 00169 hp = ast_gethostbyname(host, &ahp); 00170 if (!hp) { 00171 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host); 00172 return -1; 00173 } 00174 s = socket(AF_INET, SOCK_STREAM, 0); 00175 if (s < 0) { 00176 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 00177 return -1; 00178 } 00179 flags = fcntl(s, F_GETFL); 00180 if (flags < 0) { 00181 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno)); 00182 close(s); 00183 return -1; 00184 } 00185 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { 00186 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno)); 00187 close(s); 00188 return -1; 00189 } 00190 memset(&sin, 0, sizeof(sin)); 00191 sin.sin_family = AF_INET; 00192 sin.sin_port = htons(port); 00193 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00194 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) { 00195 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno)); 00196 close(s); 00197 return AGI_RESULT_FAILURE; 00198 } 00199 00200 pfds[0].fd = s; 00201 pfds[0].events = POLLOUT; 00202 while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) { 00203 if (errno != EINTR) { 00204 if (!res) { 00205 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n", 00206 agiurl, MAX_AGI_CONNECT); 00207 } else 00208 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00209 close(s); 00210 return AGI_RESULT_FAILURE; 00211 } 00212 } 00213 /* XXX in theory should check for partial writes... */ 00214 while (write(s, "agi_network: yes\n", strlen("agi_network: yes\n")) < 0) { 00215 if (errno != EINTR) { 00216 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00217 close(s); 00218 return AGI_RESULT_FAILURE; 00219 } 00220 } 00221 00222 /* If we have a script parameter, relay it to the fastagi server */ 00223 /* Script parameters take the form of: AGI(agi://my.example.com/?extension=${EXTEN}) */ 00224 if (!ast_strlen_zero(script)) 00225 fdprintf(s, "agi_network_script: %s\n", script); 00226 00227 if (option_debug > 3) 00228 ast_log(LOG_DEBUG, "Wow, connected!\n"); 00229 fds[0] = s; 00230 fds[1] = s; 00231 *opid = -1; 00232 return AGI_RESULT_SUCCESS; 00233 }
|
|
||||||||||||||||||||||||
|
Definition at line 235 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(). 00236 { 00237 char tmp[256]; 00238 int pid; 00239 int toast[2]; 00240 int fromast[2]; 00241 int audio[2]; 00242 int x; 00243 int res; 00244 sigset_t signal_set, old_set; 00245 00246 if (!strncasecmp(script, "agi://", 6)) 00247 return launch_netscript(script, argv, fds, efd, opid); 00248 00249 if (script[0] != '/') { 00250 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_AGI_DIR, script); 00251 script = tmp; 00252 } 00253 if (pipe(toast)) { 00254 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno)); 00255 return AGI_RESULT_FAILURE; 00256 } 00257 if (pipe(fromast)) { 00258 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno)); 00259 close(toast[0]); 00260 close(toast[1]); 00261 return AGI_RESULT_FAILURE; 00262 } 00263 if (efd) { 00264 if (pipe(audio)) { 00265 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00266 close(fromast[0]); 00267 close(fromast[1]); 00268 close(toast[0]); 00269 close(toast[1]); 00270 return AGI_RESULT_FAILURE; 00271 } 00272 res = fcntl(audio[1], F_GETFL); 00273 if (res > -1) 00274 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK); 00275 if (res < 0) { 00276 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00277 close(fromast[0]); 00278 close(fromast[1]); 00279 close(toast[0]); 00280 close(toast[1]); 00281 close(audio[0]); 00282 close(audio[1]); 00283 return AGI_RESULT_FAILURE; 00284 } 00285 } 00286 00287 /* Block SIGHUP during the fork - prevents a race */ 00288 sigfillset(&signal_set); 00289 pthread_sigmask(SIG_BLOCK, &signal_set, &old_set); 00290 pid = fork(); 00291 if (pid < 0) { 00292 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); 00293 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00294 return AGI_RESULT_FAILURE; 00295 } 00296 if (!pid) { 00297 /* Pass paths to AGI via environmental variables */ 00298 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1); 00299 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1); 00300 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1); 00301 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1); 00302 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1); 00303 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1); 00304 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1); 00305 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1); 00306 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1); 00307 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1); 00308 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1); 00309 00310 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ 00311 ast_set_priority(0); 00312 00313 /* Redirect stdin and out, provide enhanced audio channel if desired */ 00314 dup2(fromast[0], STDIN_FILENO); 00315 dup2(toast[1], STDOUT_FILENO); 00316 if (efd) { 00317 dup2(audio[0], STDERR_FILENO + 1); 00318 } else { 00319 close(STDERR_FILENO + 1); 00320 } 00321 00322 /* Before we unblock our signals, return our trapped signals back to the defaults */ 00323 signal(SIGHUP, SIG_DFL); 00324 signal(SIGCHLD, SIG_DFL); 00325 signal(SIGINT, SIG_DFL); 00326 signal(SIGURG, SIG_DFL); 00327 signal(SIGTERM, SIG_DFL); 00328 signal(SIGPIPE, SIG_DFL); 00329 signal(SIGXFSZ, SIG_DFL); 00330 00331 /* unblock important signal handlers */ 00332 if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { 00333 ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); 00334 _exit(1); 00335 } 00336 00337 /* Close everything but stdin/out/error */ 00338 for (x=STDERR_FILENO + 2;x<1024;x++) 00339 close(x); 00340 00341 /* Execute script */ 00342 /* XXX argv should be deprecated in favor of passing agi_argX paramaters */ 00343 execv(script, argv); 00344 /* Can't use ast_log since FD's are closed */ 00345 fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno)); 00346 fflush(stdout); 00347 _exit(1); 00348 } 00349 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00350 if (option_verbose > 2) 00351 ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); 00352 fds[0] = toast[0]; 00353 fds[1] = fromast[1]; 00354 if (efd) { 00355 *efd = audio[1]; 00356 } 00357 /* close what we're not using in the parent */ 00358 close(toast[1]); 00359 close(fromast[0]); 00360 00361 if (efd) 00362 close(audio[0]); 00363 00364 *opid = pid; 00365 return AGI_RESULT_SUCCESS; 00366 }
|
|
|
Definition at line 2137 of file res_agi.c. References agi_exec(), app, ast_cli_register_multiple(), ast_register_application(), cli_agi, deadagi_exec(), deadapp, deadsynopsis, descrip, eagi_exec(), eapp, esynopsis, and synopsis. 02138 { 02139 ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02140 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02141 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02142 return ast_register_application(app, agi_exec, synopsis, descrip); 02143 }
|
|
||||||||||||||||
|
Definition at line 1736 of file res_agi.c. References ast_log(), LOG_WARNING, and MAX_ARGS. 01737 { 01738 int x=0; 01739 int quoted=0; 01740 int escaped=0; 01741 int whitespace=1; 01742 char *cur; 01743 01744 cur = s; 01745 while(*s) { 01746 switch(*s) { 01747 case '"': 01748 /* If it's escaped, put a literal quote */ 01749 if (escaped) 01750 goto normal; 01751 else 01752 quoted = !quoted; 01753 if (quoted && whitespace) { 01754 /* If we're starting a quote, coming off white space start a new word, too */ 01755 argv[x++] = cur; 01756 whitespace=0; 01757 } 01758 escaped = 0; 01759 break; 01760 case ' ': 01761 case '\t': 01762 if (!quoted && !escaped) { 01763 /* If we're not quoted, mark this as whitespace, and 01764 end the previous argument */ 01765 whitespace = 1; 01766 *(cur++) = '\0'; 01767 } else 01768 /* Otherwise, just treat it as anything else */ 01769 goto normal; 01770 break; 01771 case '\\': 01772 /* If we're escaped, print a literal, otherwise enable escaping */ 01773 if (escaped) { 01774 goto normal; 01775 } else { 01776 escaped=1; 01777 } 01778 break; 01779 default: 01780 normal: 01781 if (whitespace) { 01782 if (x >= MAX_ARGS -1) { 01783 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01784 break; 01785 } 01786 /* Coming off of whitespace, start the next argument */ 01787 argv[x++] = cur; 01788 whitespace=0; 01789 } 01790 *(cur++) = *s; 01791 escaped=0; 01792 } 01793 s++; 01794 } 01795 /* Null terminate */ 01796 *(cur++) = '\0'; 01797 argv[x] = NULL; 01798 *max = x; 01799 return 0; 01800 }
|
|
||||||||||||||||||||||||||||||||||||
|
Definition at line 1834 of file res_agi.c. References agi_handle_command(), AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, agidebug, AST_FRAME_VOICE, ast_frfree(), ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_verbose(), ast_waitfor_nandfds(), agi_state::audio, agi_state::ctrl, ast_frame::data, ast_frame::datalen, agi_state::fd, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, RETRY, setup_env(), and VERBOSE_PREFIX_3. Referenced by agi_exec_full(). 01835 { 01836 struct ast_channel *c; 01837 int outfd; 01838 int ms; 01839 enum agi_result returnstatus = AGI_RESULT_SUCCESS; 01840 struct ast_frame *f; 01841 char buf[2048]; 01842 FILE *readf; 01843 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01844 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01845 int retry = RETRY; 01846 01847 if (!(readf = fdopen(agi->ctrl, "r"))) { 01848 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01849 if (pid > -1) 01850 kill(pid, SIGHUP); 01851 close(agi->ctrl); 01852 return AGI_RESULT_FAILURE; 01853 } 01854 setlinebuf(readf); 01855 setup_env(chan, request, agi->fd, (agi->audio > -1), argc, argv); 01856 for (;;) { 01857 ms = -1; 01858 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01859 if (c) { 01860 retry = RETRY; 01861 /* Idle the channel until we get a command */ 01862 f = ast_read(c); 01863 if (!f) { 01864 if (option_debug) 01865 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01866 returnstatus = AGI_RESULT_HANGUP; 01867 break; 01868 } else { 01869 /* If it's voice, write it to the audio pipe */ 01870 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01871 /* Write, ignoring errors */ 01872 write(agi->audio, f->data, f->datalen); 01873 } 01874 ast_frfree(f); 01875 } 01876 } else if (outfd > -1) { 01877 retry = RETRY; 01878 if (!fgets(buf, sizeof(buf), readf)) { 01879 /* Program terminated */ 01880 if (returnstatus) 01881 returnstatus = -1; 01882 if (option_verbose > 2) 01883 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01884 if (pid > 0) 01885 waitpid(pid, status, 0); 01886 /* No need to kill the pid anymore, since they closed us */ 01887 pid = -1; 01888 break; 01889 } 01890 /* get rid of trailing newline, if any */ 01891 if (*buf && buf[strlen(buf) - 1] == '\n') 01892 buf[strlen(buf) - 1] = 0; 01893 if (agidebug) 01894 ast_verbose("AGI Rx << %s\n", buf); 01895 returnstatus |= agi_handle_command(chan, agi, buf); 01896 /* If the handle_command returns -1, we need to stop */ 01897 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01898 break; 01899 } 01900 } else { 01901 if (--retry <= 0) { 01902 ast_log(LOG_WARNING, "No channel, no fd?\n"); 01903 returnstatus = AGI_RESULT_FAILURE; 01904 break; 01905 } 01906 } 01907 } 01908 /* Notify process */ 01909 if (pid > -1) { 01910 const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP"); 01911 if (ast_strlen_zero(sighup) || !ast_false(sighup)) { 01912 if (kill(pid, SIGHUP)) 01913 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 01914 } 01915 } 01916 fclose(readf); 01917 return returnstatus; 01918 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 368 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(). 00369 { 00370 int count; 00371 00372 /* Print initial environment, with agi_request always being the first 00373 thing */ 00374 fdprintf(fd, "agi_request: %s\n", request); 00375 fdprintf(fd, "agi_channel: %s\n", chan->name); 00376 fdprintf(fd, "agi_language: %s\n", chan->language); 00377 fdprintf(fd, "agi_type: %s\n", chan->tech->type); 00378 fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid); 00379 00380 /* ANI/DNIS */ 00381 fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown")); 00382 fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown")); 00383 fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres); 00384 fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2); 00385 fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton); 00386 fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns); 00387 fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown")); 00388 fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown")); 00389 00390 /* Context information */ 00391 fdprintf(fd, "agi_context: %s\n", chan->context); 00392 fdprintf(fd, "agi_extension: %s\n", chan->exten); 00393 fdprintf(fd, "agi_priority: %d\n", chan->priority); 00394 fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0"); 00395 00396 /* User information */ 00397 fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); 00398 00399 /* Send any parameters to the fastagi server that have been passed via the agi application */ 00400 /* Agi application paramaters take the form of: AGI(/path/to/example/script|${EXTEN}) */ 00401 for(count = 1; count < argc; count++) 00402 fdprintf(fd, "agi_arg_%d: %s\n", count, argv[count]); 00403 00404 /* End with empty return */ 00405 fdprintf(fd, "\n"); 00406 }
|
|
|
Definition at line 2128 of file res_agi.c. References app, ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_unregister_application(), cli_agi, deadapp, and eapp. 02129 { 02130 ast_module_user_hangup_all(); 02131 ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02132 ast_unregister_application(eapp); 02133 ast_unregister_application(deadapp); 02134 return ast_unregister_application(app); 02135 }
|
|
|
Definition at line 103 of file res_agi.c. Referenced by run_agi(). |
|
|
|
|
|
Definition at line 2110 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 1610 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(). |
|
|
Definition at line 78 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 82 of file res_agi.c. Referenced by load_module(). |
|
|
Initial value: "Usage: agi debug\n" " Enables dumping of AGI transactions for debugging purposes\n" |
|
|
|
|
|
Initial value: "Usage: agi dumphtml <filename>\n" " Dumps the agi command list in html format to given filename\n" |
|
|
Definition at line 76 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 81 of file res_agi.c. Referenced by load_module(). |
|
|
Initial value: "Usage: agi nodebug\n" " Disables dumping of AGI transactions for debugging purposes\n" |
|
|
Initial value: "Usage: agi show [topic]\n" " When called with a topic as an argument, displays usage\n" " information on the given command. If called without a\n" " topic, it provides a list of AGI commands.\n" |
|
|
|
|
|
Initial value: " Usage: ANSWER\n" " Answers channel if not already in answer state. Returns -1 on\n" " channel failure, or 0 if successful.\n" |
|
|
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" |
|
|
|
|
|
|
|
|
Initial value: " Usage: DATABASE DEL <family> <key>\n" " Deletes an entry in the Asterisk database for a\n" " given family and key.\n" " Returns 1 if successful, 0 otherwise.\n" |
|
|
Initial value: " Usage: DATABASE DELTREE <family> [keytree]\n" " Deletes a family or specific keytree within a family\n" " in the Asterisk database.\n" " Returns 1 if successful, 0 otherwise.\n" |
|
|
|
|
|
Initial value: " Usage: DATABASE PUT <family> <key> <value>\n" " Adds or updates an entry in the Asterisk database for a\n" " given family, key, and value.\n" " Returns 1 if successful, 0 otherwise.\n" |
|
|
Initial value: " Usage: EXEC <application> <options>\n" " Executes <application> with given <options>.\n" " Returns whatever the application returns, or -2 on failure to find application\n" |
|
|
Initial value: " Usage: GET DATA <file to be streamed> [timeout] [max digits]\n" " Stream the given file, and recieve DTMF data. Returns the digits received\n" "from the channel at the other end.\n" |
|
|
Initial value: " Usage: GET OPTION <filename> <escape_digits> [timeout]\n" " Behaves similar to STREAM FILE but used with a timeout option.\n" |
|
|
Initial value: " Usage: GET VARIABLE <variablename>\n" " Returns 0 if <variablename> is not set. Returns 1 if <variablename>\n" " is set and returns the variable in parentheses.\n" " example return code: 200 result=1 (testvariable)\n" |
|
|
|
|
|
Initial value: " Usage: HANGUP [<channelname>]\n" " Hangs up the specified channel.\n" " If no channel name is given, hangs up the current channel\n" |
|
|
Initial value: " Usage: NoOp\n" " Does nothing.\n" |
|
|
|
|
|
|
|
|
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" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Initial value: " Usage: SET CALLERID <number>\n" " Changes the callerid of the current channel.\n" |
|
|
Initial value: " Usage: SET CONTEXT <desired context>\n" " Sets the context for continuation upon exiting the application.\n" |
|
|
Initial value: " Usage: SET EXTENSION <new extension>\n" " Changes the extension for continuation upon exiting the application.\n" |
|
|
Initial value: " Usage: SET MUSIC ON <on|off> <class>\n" " Enables/Disables the music on hold generator. If <class> is\n" " not specified, then the default music on hold class will be used.\n" " Always returns 0.\n" |
|
|
Initial value: " Usage: SET PRIORITY <priority>\n" " Changes the priority for continuation upon exiting the application.\n" " The priority must be a valid priority or label.\n" |
|
|
Initial value:
" Usage: SET VARIABLE <variablename> <value>\n"
|
|
|
|
|
|
Initial value: " Usage: TDD MODE <on|off>\n" " Enable/Disable TDD transmission/reception on a channel. Returns 1 if\n" " successful, or 0 if channel is not TDD-capable.\n" |
|
|
Initial value: " Usage: VERBOSE <message> <level>\n" " Sends <message> to the console via verbose message system.\n" " <level> is the the verbose level (1-4)\n" " Always returns 1.\n" |
|
|
|