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