#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 "asterisk.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/manager.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/strings.h"
#include "asterisk/agi.h"
Go to the source code of this file.
Defines | |
#define | AGI_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 |
Functions | |
void | agi_debug_cli (int fd, char *fmt,...) |
int | agi_do_debug (int fd, int argc, char *argv[]) |
int | agi_exec (struct ast_channel *chan, void *data) |
int | agi_exec_full (struct ast_channel *chan, void *data, int enhanced, int dead) |
int | agi_handle_command (struct ast_channel *chan, AGI *agi, char *buf) |
int | agi_no_debug (int fd, int argc, char *argv[]) |
int | agi_register (agi_command *agi) |
void | agi_unregister (agi_command *agi) |
int | deadagi_exec (struct ast_channel *chan, void *data) |
char * | description (void) |
Provides a description of the module. | |
int | eagi_exec (struct ast_channel *chan, void *data) |
agi_command * | find_command (char *cmds[], int exact) |
int | handle_answer (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_autohangup (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_channelstatus (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_controlstreamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_dbdel (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_dbdeltree (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_dbget (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_dbput (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_dumpagihtml (int fd, int argc, char *argv[]) |
int | handle_exec (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_getdata (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_getoption (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_getvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_getvariablefull (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_hangup (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_noop (struct ast_channel *chan, AGI *agi, int arg, char *argv[]) |
int | handle_recordfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_recvchar (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_recvtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_sayalpha (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_saydate (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_saydatetime (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_saydigits (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_saynumber (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_sayphonetic (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_saytime (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_sendimage (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_sendtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_setcallerid (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_setcontext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_setextension (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_setmusic (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_setpriority (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_setvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_showagi (int fd, int argc, char *argv[]) |
int | handle_streamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_tddmode (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | handle_verbose (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
int | handle_waitfordigit (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
int | help_workhorse (int fd, char *match[]) |
void | join (char *s, size_t len, char *w[]) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | launch_netscript (char *agiurl, char *argv[], int *fds, int *efd, int *opid) |
int | launch_script (char *script, char *argv[], int *fds, int *efd, int *opid) |
int | load_module (void) |
Initialize the module. | |
int | parse_args (char *s, int *max, char *argv[]) |
int | run_agi (struct ast_channel *chan, char *request, AGI *agi, int pid, int dead) |
void | setup_env (struct ast_channel *chan, char *request, int fd, int enhanced) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
int | agidebug = 0 |
char * | app = "AGI" |
ast_cli_entry | cli_debug |
ast_cli_entry | cli_no_debug |
agi_command | commands [MAX_COMMANDS] |
char * | deadapp = "DeadAGI" |
char * | deadsynopsis = "Executes AGI on a hungup channel" |
char | debug_usage [] |
char * | descrip |
ast_cli_entry | dumpagihtml |
char | dumpagihtml_help [] |
char * | eapp = "EAGI" |
char * | esynopsis = "Executes an EAGI compliant application" |
LOCAL_USER_DECL | |
char | no_debug_usage [] |
ast_cli_entry | showagi |
char | showagi_help [] |
STANDARD_LOCAL_USER | |
char * | synopsis = "Executes an AGI compliant application" |
char * | tdesc = "Asterisk Gateway Interface (AGI)" |
char | usage_answer [] |
char | usage_autohangup [] |
char | usage_channelstatus [] |
char | usage_controlstreamfile [] |
char | usage_dbdel [] |
char | usage_dbdeltree [] |
char | usage_dbget [] |
char | usage_dbput [] |
char | usage_exec [] |
char | usage_getdata [] |
char | usage_getoption [] |
char | usage_getvariable [] |
char | usage_getvariablefull [] |
char | usage_hangup [] |
char | usage_noop [] |
char | usage_recordfile [] |
char | usage_recvchar [] |
char | usage_recvtext [] |
char | usage_sayalpha [] |
char | usage_saydate [] |
char | usage_saydatetime [] |
char | usage_saydigits [] |
char | usage_saynumber [] |
char | usage_sayphonetic [] |
char | usage_saytime [] |
char | usage_sendimage [] |
char | usage_sendtext [] |
char | usage_setcallerid [] |
char | usage_setcontext [] |
char | usage_setextension [] |
char | usage_setmusic [] |
char | usage_setpriority [] |
char | usage_setvariable [] |
char | usage_streamfile [] |
char | usage_tddmode [] |
char | usage_verbose [] |
char | usage_waitfordigit [] |
Definition in file res_agi.c.
|
|
|
|
Definition at line 107 of file res_agi.c. Referenced by launch_netscript(). |
|
|
|
Definition at line 68 of file res_agi.c. Referenced by agi_register(), and agi_unregister(). |
|
|
|
|
|
Definition at line 111 of file res_agi.c. References ast_carefulwrite(), ast_log(), ast_verbose(), fmt, free, LOG_ERROR, and vasprintf. 00112 { 00113 char *stuff; 00114 int res = 0; 00115 00116 va_list ap; 00117 va_start(ap, fmt); 00118 res = vasprintf(&stuff, fmt, ap); 00119 va_end(ap); 00120 if (res == -1) { 00121 ast_log(LOG_ERROR, "Out of memory\n"); 00122 } else { 00123 if (agidebug) 00124 ast_verbose("AGI Tx >> %s", stuff); 00125 ast_carefulwrite(fd, stuff, strlen(stuff), 100); 00126 free(stuff); 00127 } 00128 }
|
|
Definition at line 1312 of file res_agi.c. References agidebug, and ast_cli(). 01313 { 01314 if (argc != 2) 01315 return RESULT_SHOWUSAGE; 01316 agidebug = 1; 01317 ast_cli(fd, "AGI Debugging Enabled\n"); 01318 return RESULT_SUCCESS; 01319 }
|
|
Definition at line 2061 of file res_agi.c. References ast_channel::_softhangup, agi_exec_full(), ast_log(), and LOG_WARNING. Referenced by load_module(). 02062 { 02063 if (chan->_softhangup) 02064 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02065 return agi_exec_full(chan, data, 0, 0); 02066 }
|
|
Definition at line 2012 of file res_agi.c. References ast_channel::_state, AGI, ast_answer(), ast_log(), ast_strlen_zero(), launch_script(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, MAX_ARGS, run_agi(), and strsep(). Referenced by agi_exec(), deadagi_exec(), and eagi_exec(). 02013 { 02014 int res=0; 02015 struct localuser *u; 02016 char *argv[MAX_ARGS]; 02017 char buf[2048]=""; 02018 char *tmp = (char *)buf; 02019 int argc = 0; 02020 int fds[2]; 02021 int efd = -1; 02022 int pid; 02023 char *stringp; 02024 AGI agi; 02025 02026 if (ast_strlen_zero(data)) { 02027 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02028 return -1; 02029 } 02030 ast_copy_string(buf, data, sizeof(buf)); 02031 02032 memset(&agi, 0, sizeof(agi)); 02033 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS - 1) 02034 argv[argc++] = stringp; 02035 argv[argc] = NULL; 02036 02037 LOCAL_USER_ADD(u); 02038 #if 0 02039 /* Answer if need be */ 02040 if (chan->_state != AST_STATE_UP) { 02041 if (ast_answer(chan)) { 02042 LOCAL_USER_REMOVE(u); 02043 return -1; 02044 } 02045 } 02046 #endif 02047 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); 02048 if (!res) { 02049 agi.fd = fds[1]; 02050 agi.ctrl = fds[0]; 02051 agi.audio = efd; 02052 res = run_agi(chan, argv[0], &agi, pid, dead); 02053 close(fds[1]); 02054 if (efd > -1) 02055 close(efd); 02056 } 02057 LOCAL_USER_REMOVE(u); 02058 return res; 02059 }
|
|
Definition at line 1815 of file res_agi.c. References AGI, AST_PBX_KEEPALIVE, agi_state::fd, fdprintf, find_command(), agi_command::handler, parse_args(), RESULT_FAILURE, RESULT_SHOWUSAGE, and agi_command::usage. Referenced by run_agi(). 01816 { 01817 char *argv[MAX_ARGS]; 01818 int argc = 0; 01819 int res; 01820 agi_command *c; 01821 argc = MAX_ARGS; 01822 01823 parse_args(buf, &argc, argv); 01824 #if 0 01825 { int x; 01826 for (x=0; x<argc; x++) 01827 fprintf(stderr, "Got Arg%d: %s\n", x, argv[x]); } 01828 #endif 01829 c = find_command(argv, 0); 01830 if (c) { 01831 res = c->handler(chan, agi, argc, argv); 01832 switch(res) { 01833 case RESULT_SHOWUSAGE: 01834 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01835 fdprintf(agi->fd, c->usage); 01836 fdprintf(agi->fd, "520 End of proper usage.\n"); 01837 break; 01838 case AST_PBX_KEEPALIVE: 01839 /* We've been asked to keep alive, so do so */ 01840 return AST_PBX_KEEPALIVE; 01841 break; 01842 case RESULT_FAILURE: 01843 /* They've already given the failure. We've been hung up on so handle this 01844 appropriately */ 01845 return -1; 01846 } 01847 } else { 01848 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01849 } 01850 return 0; 01851 }
|
|
Definition at line 1321 of file res_agi.c. References agidebug, and ast_cli(). 01322 { 01323 if (argc != 3) 01324 return RESULT_SHOWUSAGE; 01325 agidebug = 0; 01326 ast_cli(fd, "AGI Debugging Disabled\n"); 01327 return RESULT_SUCCESS; 01328 }
|
|
Definition at line 1686 of file res_agi.c. References ast_log(), agi_command::cmda, commands, LOG_WARNING, and MAX_COMMANDS. 01687 { 01688 int x; 01689 for (x=0; x<MAX_COMMANDS - 1; x++) { 01690 if (commands[x].cmda[0] == agi->cmda[0]) { 01691 ast_log(LOG_WARNING, "Command already registered!\n"); 01692 return -1; 01693 } 01694 } 01695 for (x=0; x<MAX_COMMANDS - 1; x++) { 01696 if (!commands[x].cmda[0]) { 01697 commands[x] = *agi; 01698 return 0; 01699 } 01700 } 01701 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01702 return -1; 01703 }
|
|
Definition at line 1705 of file res_agi.c. References agi_command::cmda, commands, and MAX_COMMANDS. 01706 { 01707 int x; 01708 for (x=0; x<MAX_COMMANDS - 1; x++) { 01709 if (commands[x].cmda[0] == agi->cmda[0]) { 01710 memset(&commands[x], 0, sizeof(agi_command)); 01711 } 01712 } 01713 }
|
|
Definition at line 2089 of file res_agi.c. References agi_exec_full(). Referenced by load_module(). 02090 { 02091 return agi_exec_full(chan, data, 0, 1); 02092 }
|
|
Provides a description of the module.
Definition at line 2134 of file res_agi.c. 02135 {
02136 return tdesc;
02137 }
|
|
Definition at line 2068 of file res_agi.c. References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), LOG_WARNING, ast_channel::name, and ast_channel::readformat. Referenced by load_module(). 02069 { 02070 int readformat; 02071 int res; 02072 02073 if (chan->_softhangup) 02074 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02075 readformat = chan->readformat; 02076 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02077 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02078 return -1; 02079 } 02080 res = agi_exec_full(chan, data, 1, 0); 02081 if (!res) { 02082 if (ast_set_read_format(chan, readformat)) { 02083 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02084 } 02085 } 02086 return res; 02087 }
|
|
Definition at line 1715 of file res_agi.c. References agi_command::cmda, and commands. Referenced by agi_handle_command(), handle_response(), and handle_showagi(). 01716 { 01717 int x; 01718 int y; 01719 int match; 01720 01721 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01722 if (!commands[x].cmda[0]) 01723 break; 01724 /* start optimistic */ 01725 match = 1; 01726 for (y=0; match && cmds[y]; y++) { 01727 /* If there are no more words in the command (and we're looking for 01728 an exact match) or there is a difference between the two words, 01729 then this is not a match */ 01730 if (!commands[x].cmda[y] && !exact) 01731 break; 01732 /* don't segfault if the next part of a command doesn't exist */ 01733 if (!commands[x].cmda[y]) 01734 return NULL; 01735 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01736 match = 0; 01737 } 01738 /* If more words are needed to complete the command then this is not 01739 a candidate (unless we're looking for a really inexact answer */ 01740 if ((exact > -1) && commands[x].cmda[y]) 01741 match = 0; 01742 if (match) 01743 return &commands[x]; 01744 } 01745 return NULL; 01746 }
|
|
Definition at line 362 of file res_agi.c. References ast_channel::_state, AGI, ast_answer(), agi_state::fd, and fdprintf. 00363 { 00364 int res; 00365 res = 0; 00366 if (chan->_state != AST_STATE_UP) { 00367 /* Answer the chan */ 00368 res = ast_answer(chan); 00369 } 00370 fdprintf(agi->fd, "200 result=%d\n", res); 00371 if (res >= 0) 00372 return RESULT_SUCCESS; 00373 else 00374 return RESULT_FAILURE; 00375 }
|
|
Definition at line 1039 of file res_agi.c. References AGI, agi_state::fd, fdprintf, and ast_channel::whentohangup. 01040 { 01041 int timeout; 01042 01043 if (argc != 3) 01044 return RESULT_SHOWUSAGE; 01045 if (sscanf(argv[2], "%d", &timeout) != 1) 01046 return RESULT_SHOWUSAGE; 01047 if (timeout < 0) 01048 timeout = 0; 01049 if (timeout) 01050 chan->whentohangup = time(NULL) + timeout; 01051 else 01052 chan->whentohangup = 0; 01053 fdprintf(agi->fd, "200 result=0\n"); 01054 return RESULT_SUCCESS; 01055 }
|
|
Definition at line 1128 of file res_agi.c. References ast_channel::_state, AGI, ast_get_channel_by_name_locked(), ast_mutex_unlock(), agi_state::fd, fdprintf, and ast_channel::lock. 01129 { 01130 struct ast_channel *c; 01131 if (argc == 2) { 01132 /* no argument: supply info on the current channel */ 01133 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01134 return RESULT_SUCCESS; 01135 } else if (argc == 3) { 01136 /* one argument: look for info on the specified channel */ 01137 c = ast_get_channel_by_name_locked(argv[2]); 01138 if (c) { 01139 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01140 ast_mutex_unlock(&c->lock); 01141 return RESULT_SUCCESS; 01142 } 01143 /* if we get this far no channel name matched the argument given */ 01144 fdprintf(agi->fd, "200 result=-1\n"); 01145 return RESULT_SUCCESS; 01146 } else { 01147 return RESULT_SHOWUSAGE; 01148 } 01149 }
|
|
Definition at line 485 of file res_agi.c. References AGI, ast_control_streamfile(), ast_strlen_zero(), agi_state::fd, and fdprintf. 00486 { 00487 int res = 0; 00488 int skipms = 3000; 00489 char *fwd = NULL; 00490 char *rev = NULL; 00491 char *pause = NULL; 00492 char *stop = NULL; 00493 00494 if (argc < 5 || argc > 9) 00495 return RESULT_SHOWUSAGE; 00496 00497 if (!ast_strlen_zero(argv[4])) 00498 stop = argv[4]; 00499 else 00500 stop = NULL; 00501 00502 if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) 00503 return RESULT_SHOWUSAGE; 00504 00505 if (argc > 6 && !ast_strlen_zero(argv[8])) 00506 fwd = argv[6]; 00507 else 00508 fwd = "#"; 00509 00510 if (argc > 7 && !ast_strlen_zero(argv[8])) 00511 rev = argv[7]; 00512 else 00513 rev = "*"; 00514 00515 if (argc > 8 && !ast_strlen_zero(argv[8])) 00516 pause = argv[8]; 00517 else 00518 pause = NULL; 00519 00520 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); 00521 00522 fdprintf(agi->fd, "200 result=%d\n", res); 00523 00524 if (res >= 0) 00525 return RESULT_SUCCESS; 00526 else 00527 return RESULT_FAILURE; 00528 }
|
|
Definition at line 1272 of file res_agi.c. References AGI, ast_db_del(), agi_state::fd, and fdprintf. 01273 { 01274 int res; 01275 01276 if (argc != 4) 01277 return RESULT_SHOWUSAGE; 01278 res = ast_db_del(argv[2], argv[3]); 01279 if (res) 01280 fdprintf(agi->fd, "200 result=0\n"); 01281 else 01282 fdprintf(agi->fd, "200 result=1\n"); 01283 01284 return RESULT_SUCCESS; 01285 }
|
|
Definition at line 1287 of file res_agi.c. References AGI, ast_db_deltree(), agi_state::fd, and fdprintf. 01288 { 01289 int res; 01290 if ((argc < 3) || (argc > 4)) 01291 return RESULT_SHOWUSAGE; 01292 if (argc == 4) 01293 res = ast_db_deltree(argv[2], argv[3]); 01294 else 01295 res = ast_db_deltree(argv[2], NULL); 01296 01297 if (res) 01298 fdprintf(agi->fd, "200 result=0\n"); 01299 else 01300 fdprintf(agi->fd, "200 result=1\n"); 01301 return RESULT_SUCCESS; 01302 }
|
|
Definition at line 1241 of file res_agi.c. References AGI, ast_db_get(), agi_state::fd, and fdprintf. 01242 { 01243 int res; 01244 char tmp[256]; 01245 01246 if (argc != 4) 01247 return RESULT_SHOWUSAGE; 01248 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01249 if (res) 01250 fdprintf(agi->fd, "200 result=0\n"); 01251 else 01252 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01253 01254 return RESULT_SUCCESS; 01255 }
|
|
Definition at line 1257 of file res_agi.c. References AGI, ast_db_put(), agi_state::fd, and fdprintf. 01258 { 01259 int res; 01260 01261 if (argc != 5) 01262 return RESULT_SHOWUSAGE; 01263 res = ast_db_put(argv[2], argv[3], argv[4]); 01264 if (res) 01265 fdprintf(agi->fd, "200 result=0\n"); 01266 else 01267 fdprintf(agi->fd, "200 result=1\n"); 01268 01269 return RESULT_SUCCESS; 01270 }
|
|
Definition at line 1956 of file res_agi.c. References ast_cli(), agi_command::cmda, commands, join(), strsep(), agi_command::summary, and agi_command::usage. 01956 { 01957 struct agi_command *e; 01958 char fullcmd[80]; 01959 char *tempstr; 01960 int x; 01961 FILE *htmlfile; 01962 01963 if ((argc < 3)) 01964 return RESULT_SHOWUSAGE; 01965 01966 if (!(htmlfile = fopen(argv[2], "wt"))) { 01967 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 01968 return RESULT_SHOWUSAGE; 01969 } 01970 01971 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 01972 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 01973 01974 01975 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 01976 01977 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01978 char *stringp=NULL; 01979 if (!commands[x].cmda[0]) break; 01980 e = &commands[x]; 01981 if (e) 01982 join(fullcmd, sizeof(fullcmd), e->cmda); 01983 /* Hide commands that start with '_' */ 01984 if (fullcmd[0] == '_') 01985 continue; 01986 01987 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 01988 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TD></TR>\n", fullcmd,e->summary); 01989 01990 01991 stringp=e->usage; 01992 tempstr = strsep(&stringp, "\n"); 01993 01994 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 01995 01996 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 01997 while ((tempstr = strsep(&stringp, "\n")) != NULL) { 01998 fprintf(htmlfile, "%s<BR>\n",tempstr); 01999 02000 } 02001 fprintf(htmlfile, "</TD></TR>\n"); 02002 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 02003 02004 } 02005 02006 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 02007 fclose(htmlfile); 02008 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 02009 return RESULT_SUCCESS; 02010 }
|
|
Definition at line 1083 of file res_agi.c. References AGI, app, ast_log(), ast_verbose(), agi_state::fd, fdprintf, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3. 01084 { 01085 int res; 01086 struct ast_app *app; 01087 01088 if (argc < 2) 01089 return RESULT_SHOWUSAGE; 01090 01091 if (option_verbose > 2) 01092 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01093 01094 app = pbx_findapp(argv[1]); 01095 01096 if (app) { 01097 res = pbx_exec(chan, app, argv[2], 1); 01098 } else { 01099 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01100 res = -2; 01101 } 01102 fdprintf(agi->fd, "200 result=%d\n", res); 01103 01104 return res; 01105 }
|
|
Definition at line 805 of file res_agi.c. References AGI, ast_app_getdata_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, and fdprintf. 00806 { 00807 int res; 00808 char data[1024]; 00809 int max; 00810 int timeout; 00811 00812 if (argc < 3) 00813 return RESULT_SHOWUSAGE; 00814 if (argc >= 4) 00815 timeout = atoi(argv[3]); 00816 else 00817 timeout = 0; 00818 if (argc >= 5) 00819 max = atoi(argv[4]); 00820 else 00821 max = 1024; 00822 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00823 if (res == 2) /* New command */ 00824 return RESULT_SUCCESS; 00825 else if (res == 1) 00826 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00827 else if (res < 0 ) 00828 fdprintf(agi->fd, "200 result=-1\n"); 00829 else 00830 fdprintf(agi->fd, "200 result=%s\n", data); 00831 return RESULT_SUCCESS; 00832 }
|
|
Definition at line 586 of file res_agi.c. References AGI, ast_applystream(), ast_log(), ast_openstream(), 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_WARNING, option_verbose, ast_channel::pbx, ast_channel::stream, and VERBOSE_PREFIX_3. 00587 { 00588 int res; 00589 struct ast_filestream *fs; 00590 long sample_offset = 0; 00591 long max_length; 00592 int timeout = 0; 00593 char *edigits = NULL; 00594 00595 if ( argc < 4 || argc > 5 ) 00596 return RESULT_SHOWUSAGE; 00597 00598 if ( argv[3] ) 00599 edigits = argv[3]; 00600 00601 if ( argc == 5 ) 00602 timeout = atoi(argv[4]); 00603 else if (chan->pbx->dtimeout) { 00604 /* by default dtimeout is set to 5sec */ 00605 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00606 } 00607 00608 fs = ast_openstream(chan, argv[2], chan->language); 00609 if (!fs){ 00610 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00611 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00612 return RESULT_SUCCESS; 00613 } 00614 if (option_verbose > 2) 00615 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00616 00617 ast_seekstream(fs, 0, SEEK_END); 00618 max_length = ast_tellstream(fs); 00619 ast_seekstream(fs, sample_offset, SEEK_SET); 00620 res = ast_applystream(chan, fs); 00621 res = ast_playstream(fs); 00622 if (res) { 00623 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00624 if (res >= 0) 00625 return RESULT_SHOWUSAGE; 00626 else 00627 return RESULT_FAILURE; 00628 } 00629 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00630 /* this is to check for if ast_waitstream closed the stream, we probably are at 00631 * the end of the stream, return that amount, else check for the amount */ 00632 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00633 ast_stopstream(chan); 00634 if (res == 1) { 00635 /* Stop this command, don't print a result line, as there is a new command */ 00636 return RESULT_SUCCESS; 00637 } 00638 00639 /* If the user didnt press a key, wait for digitTimeout*/ 00640 if (res == 0 ) { 00641 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00642 /* Make sure the new result is in the escape digits of the GET OPTION */ 00643 if ( !strchr(edigits,res) ) 00644 res=0; 00645 } 00646 00647 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00648 if (res >= 0) 00649 return RESULT_SUCCESS; 00650 else 00651 return RESULT_FAILURE; 00652 }
|
|
Definition at line 1160 of file res_agi.c. References AGI, ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, and pbx_retrieve_variable(). 01161 { 01162 char *ret; 01163 char tempstr[1024]; 01164 01165 if (argc != 3) 01166 return RESULT_SHOWUSAGE; 01167 01168 /* check if we want to execute an ast_custom_function */ 01169 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01170 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)); 01171 } else { 01172 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01173 } 01174 01175 if (ret) 01176 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01177 else 01178 fdprintf(agi->fd, "200 result=0\n"); 01179 01180 return RESULT_SUCCESS; 01181 }
|
|
Definition at line 1183 of file res_agi.c. References AGI, ast_get_channel_by_name_locked(), ast_mutex_unlock(), agi_state::fd, fdprintf, ast_channel::lock, and pbx_substitute_variables_helper(). 01184 { 01185 char tmp[4096] = ""; 01186 struct ast_channel *chan2=NULL; 01187 01188 if ((argc != 4) && (argc != 5)) 01189 return RESULT_SHOWUSAGE; 01190 if (argc == 5) { 01191 chan2 = ast_get_channel_by_name_locked(argv[4]); 01192 } else { 01193 chan2 = chan; 01194 } 01195 if (chan) { /* XXX isn't this chan2 ? */ 01196 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01197 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01198 } else { 01199 fdprintf(agi->fd, "200 result=0\n"); 01200 } 01201 if (chan2 && (chan2 != chan)) 01202 ast_mutex_unlock(&chan2->lock); 01203 return RESULT_SUCCESS; 01204 }
|
|
Definition at line 1057 of file res_agi.c. References AGI, ast_get_channel_by_name_locked(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, agi_state::fd, fdprintf, and ast_channel::lock. 01058 { 01059 struct ast_channel *c; 01060 if (argc == 1) { 01061 /* no argument: hangup the current channel */ 01062 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01063 fdprintf(agi->fd, "200 result=1\n"); 01064 return RESULT_SUCCESS; 01065 } else if (argc == 2) { 01066 /* one argument: look for info on the specified channel */ 01067 c = ast_get_channel_by_name_locked(argv[1]); 01068 if (c) { 01069 /* we have a matching channel */ 01070 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01071 fdprintf(agi->fd, "200 result=1\n"); 01072 ast_mutex_unlock(&c->lock); 01073 return RESULT_SUCCESS; 01074 } 01075 /* if we get this far no channel name matched the argument given */ 01076 fdprintf(agi->fd, "200 result=-1\n"); 01077 return RESULT_SUCCESS; 01078 } else { 01079 return RESULT_SHOWUSAGE; 01080 } 01081 }
|
|
Definition at line 1336 of file res_agi.c. References AGI, agi_state::fd, and fdprintf.
|
|
Definition at line 869 of file res_agi.c. References AGI, ast_applystream(), ast_closestream(), ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), 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(), agi_state::fd, fdprintf, ast_frame::frametype, ast_channel::language, LOG_WARNING, ast_channel::name, ast_channel::readformat, ast_channel::stream, and ast_frame::subclass. 00870 { 00871 struct ast_filestream *fs; 00872 struct ast_frame *f; 00873 struct timeval start; 00874 long sample_offset = 0; 00875 int res = 0; 00876 int ms; 00877 00878 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00879 int totalsilence = 0; 00880 int dspsilence = 0; 00881 int silence = 0; /* amount of silence to allow */ 00882 int gotsilence = 0; /* did we timeout for silence? */ 00883 char *silencestr=NULL; 00884 int rfmt=0; 00885 00886 00887 /* XXX EAGI FIXME XXX */ 00888 00889 if (argc < 6) 00890 return RESULT_SHOWUSAGE; 00891 if (sscanf(argv[5], "%d", &ms) != 1) 00892 return RESULT_SHOWUSAGE; 00893 00894 if (argc > 6) 00895 silencestr = strchr(argv[6],'s'); 00896 if ((argc > 7) && (!silencestr)) 00897 silencestr = strchr(argv[7],'s'); 00898 if ((argc > 8) && (!silencestr)) 00899 silencestr = strchr(argv[8],'s'); 00900 00901 if (silencestr) { 00902 if (strlen(silencestr) > 2) { 00903 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00904 silencestr++; 00905 silencestr++; 00906 if (silencestr) 00907 silence = atoi(silencestr); 00908 if (silence > 0) 00909 silence *= 1000; 00910 } 00911 } 00912 } 00913 00914 if (silence > 0) { 00915 rfmt = chan->readformat; 00916 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00917 if (res < 0) { 00918 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00919 return -1; 00920 } 00921 sildet = ast_dsp_new(); 00922 if (!sildet) { 00923 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00924 return -1; 00925 } 00926 ast_dsp_set_threshold(sildet, 256); 00927 } 00928 00929 /* backward compatibility, if no offset given, arg[6] would have been 00930 * caught below and taken to be a beep, else if it is a digit then it is a 00931 * offset */ 00932 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00933 res = ast_streamfile(chan, "beep", chan->language); 00934 00935 if ((argc > 7) && (!strchr(argv[7], '='))) 00936 res = ast_streamfile(chan, "beep", chan->language); 00937 00938 if (!res) 00939 res = ast_waitstream(chan, argv[4]); 00940 if (res) { 00941 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00942 } else { 00943 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644); 00944 if (!fs) { 00945 res = -1; 00946 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 00947 if (sildet) 00948 ast_dsp_free(sildet); 00949 return RESULT_FAILURE; 00950 } 00951 00952 chan->stream = fs; 00953 ast_applystream(chan,fs); 00954 /* really should have checks */ 00955 ast_seekstream(fs, sample_offset, SEEK_SET); 00956 ast_truncstream(fs); 00957 00958 start = ast_tvnow(); 00959 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 00960 res = ast_waitfor(chan, -1); 00961 if (res < 0) { 00962 ast_closestream(fs); 00963 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 00964 if (sildet) 00965 ast_dsp_free(sildet); 00966 return RESULT_FAILURE; 00967 } 00968 f = ast_read(chan); 00969 if (!f) { 00970 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset); 00971 ast_closestream(fs); 00972 if (sildet) 00973 ast_dsp_free(sildet); 00974 return RESULT_FAILURE; 00975 } 00976 switch(f->frametype) { 00977 case AST_FRAME_DTMF: 00978 if (strchr(argv[4], f->subclass)) { 00979 /* This is an interrupting chracter, so rewind to chop off any small 00980 amount of DTMF that may have been recorded 00981 */ 00982 ast_stream_rewind(fs, 200); 00983 ast_truncstream(fs); 00984 sample_offset = ast_tellstream(fs); 00985 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 00986 ast_closestream(fs); 00987 ast_frfree(f); 00988 if (sildet) 00989 ast_dsp_free(sildet); 00990 return RESULT_SUCCESS; 00991 } 00992 break; 00993 case AST_FRAME_VOICE: 00994 ast_writestream(fs, f); 00995 /* this is a safe place to check progress since we know that fs 00996 * is valid after a write, and it will then have our current 00997 * location */ 00998 sample_offset = ast_tellstream(fs); 00999 if (silence > 0) { 01000 dspsilence = 0; 01001 ast_dsp_silence(sildet, f, &dspsilence); 01002 if (dspsilence) { 01003 totalsilence = dspsilence; 01004 } else { 01005 totalsilence = 0; 01006 } 01007 if (totalsilence > silence) { 01008 /* Ended happily with silence */ 01009 ast_frfree(f); 01010 gotsilence = 1; 01011 break; 01012 } 01013 } 01014 break; 01015 } 01016 ast_frfree(f); 01017 if (gotsilence) 01018 break; 01019 } 01020 01021 if (gotsilence) { 01022 ast_stream_rewind(fs, silence-1000); 01023 ast_truncstream(fs); 01024 sample_offset = ast_tellstream(fs); 01025 } 01026 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01027 ast_closestream(fs); 01028 } 01029 01030 if (silence > 0) { 01031 res = ast_set_read_format(chan, rfmt); 01032 if (res) 01033 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01034 ast_dsp_free(sildet); 01035 } 01036 return RESULT_SUCCESS; 01037 }
|
|
Definition at line 413 of file res_agi.c. References AGI, ast_recvchar(), agi_state::fd, and fdprintf. 00414 { 00415 int res; 00416 if (argc != 3) 00417 return RESULT_SHOWUSAGE; 00418 res = ast_recvchar(chan,atoi(argv[2])); 00419 if (res == 0) { 00420 fdprintf(agi->fd, "200 result=%d (timeout)\n", res); 00421 return RESULT_SUCCESS; 00422 } 00423 if (res > 0) { 00424 fdprintf(agi->fd, "200 result=%d\n", res); 00425 return RESULT_SUCCESS; 00426 } 00427 else { 00428 fdprintf(agi->fd, "200 result=%d (hangup)\n", res); 00429 return RESULT_FAILURE; 00430 } 00431 }
|
|
Definition at line 433 of file res_agi.c. References AGI, ast_recvtext(), agi_state::fd, fdprintf, and free. 00434 { 00435 char *buf; 00436 00437 if (argc != 3) 00438 return RESULT_SHOWUSAGE; 00439 buf = ast_recvtext(chan,atoi(argv[2])); 00440 if (buf) { 00441 fdprintf(agi->fd, "200 result=1 (%s)\n", buf); 00442 free(buf); 00443 } else { 00444 fdprintf(agi->fd, "200 result=-1\n"); 00445 } 00446 return RESULT_SUCCESS; 00447 }
|
|
Definition at line 698 of file res_agi.c. References AGI, ast_say_character_str_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, and ast_channel::language. 00699 { 00700 int res; 00701 00702 if (argc != 4) 00703 return RESULT_SHOWUSAGE; 00704 00705 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00706 if (res == 1) /* New command */ 00707 return RESULT_SUCCESS; 00708 fdprintf(agi->fd, "200 result=%d\n", res); 00709 if (res >= 0) 00710 return RESULT_SUCCESS; 00711 else 00712 return RESULT_FAILURE; 00713 }
|
|
Definition at line 715 of file res_agi.c. References AGI, ast_say_date(), agi_state::fd, fdprintf, and ast_channel::language. 00716 { 00717 int res; 00718 int num; 00719 if (argc != 4) 00720 return RESULT_SHOWUSAGE; 00721 if (sscanf(argv[2], "%d", &num) != 1) 00722 return RESULT_SHOWUSAGE; 00723 res = ast_say_date(chan, num, argv[3], chan->language); 00724 if (res == 1) 00725 return RESULT_SUCCESS; 00726 fdprintf(agi->fd, "200 result=%d\n", res); 00727 if (res >= 0) 00728 return RESULT_SUCCESS; 00729 else 00730 return RESULT_FAILURE; 00731 }
|
|
Definition at line 751 of file res_agi.c. References AGI, ast_say_date_with_format(), ast_strlen_zero(), agi_state::fd, fdprintf, and ast_channel::language. 00752 { 00753 int res=0; 00754 long unixtime; 00755 char *format, *zone=NULL; 00756 00757 if (argc < 4) 00758 return RESULT_SHOWUSAGE; 00759 00760 if (argc > 4) { 00761 format = argv[4]; 00762 } else { 00763 if (!strcasecmp(chan->language, "de")) { 00764 format = "A dBY HMS"; 00765 } else { 00766 format = "ABdY 'digits/at' IMp"; 00767 } 00768 } 00769 00770 if (argc > 5 && !ast_strlen_zero(argv[5])) 00771 zone = argv[5]; 00772 00773 if (sscanf(argv[2], "%ld", &unixtime) != 1) 00774 return RESULT_SHOWUSAGE; 00775 00776 res = ast_say_date_with_format(chan, (time_t) unixtime, argv[3], chan->language, format, zone); 00777 if (res == 1) 00778 return RESULT_SUCCESS; 00779 00780 fdprintf(agi->fd, "200 result=%d\n", res); 00781 00782 if (res >= 0) 00783 return RESULT_SUCCESS; 00784 else 00785 return RESULT_FAILURE; 00786 }
|
|
Definition at line 678 of file res_agi.c. References AGI, ast_say_digit_str_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, and ast_channel::language. 00679 { 00680 int res; 00681 int num; 00682 00683 if (argc != 4) 00684 return RESULT_SHOWUSAGE; 00685 if (sscanf(argv[2], "%d", &num) != 1) 00686 return RESULT_SHOWUSAGE; 00687 00688 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00689 if (res == 1) /* New command */ 00690 return RESULT_SUCCESS; 00691 fdprintf(agi->fd, "200 result=%d\n", res); 00692 if (res >= 0) 00693 return RESULT_SUCCESS; 00694 else 00695 return RESULT_FAILURE; 00696 }
|
|
Definition at line 660 of file res_agi.c. References AGI, ast_say_number_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, and ast_channel::language. 00661 { 00662 int res; 00663 int num; 00664 if (argc != 4) 00665 return RESULT_SHOWUSAGE; 00666 if (sscanf(argv[2], "%d", &num) != 1) 00667 return RESULT_SHOWUSAGE; 00668 res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl); 00669 if (res == 1) 00670 return RESULT_SUCCESS; 00671 fdprintf(agi->fd, "200 result=%d\n", res); 00672 if (res >= 0) 00673 return RESULT_SUCCESS; 00674 else 00675 return RESULT_FAILURE; 00676 }
|
|
Definition at line 788 of file res_agi.c. References AGI, ast_say_phonetic_str_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, and ast_channel::language. 00789 { 00790 int res; 00791 00792 if (argc != 4) 00793 return RESULT_SHOWUSAGE; 00794 00795 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00796 if (res == 1) /* New command */ 00797 return RESULT_SUCCESS; 00798 fdprintf(agi->fd, "200 result=%d\n", res); 00799 if (res >= 0) 00800 return RESULT_SUCCESS; 00801 else 00802 return RESULT_FAILURE; 00803 }
|
|
Definition at line 733 of file res_agi.c. References AGI, ast_say_time(), agi_state::fd, fdprintf, and ast_channel::language. 00734 { 00735 int res; 00736 int num; 00737 if (argc != 4) 00738 return RESULT_SHOWUSAGE; 00739 if (sscanf(argv[2], "%d", &num) != 1) 00740 return RESULT_SHOWUSAGE; 00741 res = ast_say_time(chan, num, argv[3], chan->language); 00742 if (res == 1) 00743 return RESULT_SUCCESS; 00744 fdprintf(agi->fd, "200 result=%d\n", res); 00745 if (res >= 0) 00746 return RESULT_SUCCESS; 00747 else 00748 return RESULT_FAILURE; 00749 }
|
|
Definition at line 470 of file res_agi.c. References AGI, ast_check_hangup(), ast_send_image(), agi_state::fd, and fdprintf. 00471 { 00472 int res; 00473 if (argc != 3) 00474 return RESULT_SHOWUSAGE; 00475 res = ast_send_image(chan, argv[2]); 00476 if (!ast_check_hangup(chan)) 00477 res = 0; 00478 fdprintf(agi->fd, "200 result=%d\n", res); 00479 if (res >= 0) 00480 return RESULT_SUCCESS; 00481 else 00482 return RESULT_FAILURE; 00483 }
|
|
Definition at line 393 of file res_agi.c. References AGI, ast_sendtext(), agi_state::fd, and fdprintf. 00394 { 00395 int res; 00396 if (argc != 3) 00397 return RESULT_SHOWUSAGE; 00398 /* At the moment, the parser (perhaps broken) returns with 00399 the last argument PLUS the newline at the end of the input 00400 buffer. This probably needs to be fixed, but I wont do that 00401 because other stuff may break as a result. The right way 00402 would probably be to strip off the trailing newline before 00403 parsing, then here, add a newline at the end of the string 00404 before sending it to ast_sendtext --DUDE */ 00405 res = ast_sendtext(chan, argv[2]); 00406 fdprintf(agi->fd, "200 result=%d\n", res); 00407 if (res >= 0) 00408 return RESULT_SUCCESS; 00409 else 00410 return RESULT_FAILURE; 00411 }
|
|
Definition at line 1107 of file res_agi.c. References AGI, ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, and fdprintf. 01108 { 01109 char tmp[256]=""; 01110 char *l = NULL, *n = NULL; 01111 01112 if (argv[2]) { 01113 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01114 ast_callerid_parse(tmp, &n, &l); 01115 if (l) 01116 ast_shrink_phone_number(l); 01117 else 01118 l = ""; 01119 if (!n) 01120 n = ""; 01121 ast_set_callerid(chan, l, n, NULL); 01122 } 01123 01124 fdprintf(agi->fd, "200 result=1\n"); 01125 return RESULT_SUCCESS; 01126 }
|
|
Definition at line 834 of file res_agi.c. References AGI, ast_channel::context, agi_state::fd, and fdprintf. 00835 { 00836 00837 if (argc != 3) 00838 return RESULT_SHOWUSAGE; 00839 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00840 fdprintf(agi->fd, "200 result=0\n"); 00841 return RESULT_SUCCESS; 00842 }
|
|
Definition at line 844 of file res_agi.c. References AGI, ast_channel::exten, agi_state::fd, and fdprintf. 00845 { 00846 if (argc != 3) 00847 return RESULT_SHOWUSAGE; 00848 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00849 fdprintf(agi->fd, "200 result=0\n"); 00850 return RESULT_SUCCESS; 00851 }
|
|
Definition at line 1342 of file res_agi.c. References AGI, ast_moh_start(), ast_moh_stop(), agi_state::fd, and fdprintf. 01343 { 01344 if (!strncasecmp(argv[2],"on",2)) { 01345 if (argc > 3) 01346 ast_moh_start(chan, argv[3]); 01347 else 01348 ast_moh_start(chan, NULL); 01349 } 01350 if (!strncasecmp(argv[2],"off",3)) { 01351 ast_moh_stop(chan); 01352 } 01353 fdprintf(agi->fd, "200 result=0\n"); 01354 return RESULT_SUCCESS; 01355 }
|
|
Definition at line 853 of file res_agi.c. References AGI, ast_explicit_goto(), ast_findlabel_extension(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, agi_state::fd, and fdprintf. 00854 { 00855 int pri; 00856 if (argc != 3) 00857 return RESULT_SHOWUSAGE; 00858 00859 if (sscanf(argv[2], "%d", &pri) != 1) { 00860 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00861 return RESULT_SHOWUSAGE; 00862 } 00863 00864 ast_explicit_goto(chan, NULL, NULL, pri); 00865 fdprintf(agi->fd, "200 result=0\n"); 00866 return RESULT_SUCCESS; 00867 }
|
|
Definition at line 1151 of file res_agi.c. References AGI, agi_state::fd, fdprintf, and pbx_builtin_setvar_helper(). 01152 { 01153 if (argv[3]) 01154 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01155 01156 fdprintf(agi->fd, "200 result=1\n"); 01157 return RESULT_SUCCESS; 01158 }
|
|
Definition at line 1933 of file res_agi.c. References ast_cli(), find_command(), help_workhorse(), join(), and agi_command::usage. 01933 { 01934 struct agi_command *e; 01935 char fullcmd[80]; 01936 if ((argc < 2)) 01937 return RESULT_SHOWUSAGE; 01938 if (argc > 2) { 01939 e = find_command(argv + 2, 1); 01940 if (e) 01941 ast_cli(fd, e->usage); 01942 else { 01943 if (find_command(argv + 2, -1)) { 01944 return help_workhorse(fd, argv + 1); 01945 } else { 01946 join(fullcmd, sizeof(fullcmd), argv+1); 01947 ast_cli(fd, "No such command '%s'.\n", fullcmd); 01948 } 01949 } 01950 } else { 01951 return help_workhorse(fd, NULL); 01952 } 01953 return RESULT_SUCCESS; 01954 }
|
|
Definition at line 530 of file res_agi.c. References AGI, ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, LOG_DEBUG, and ast_channel::stream. 00531 { 00532 int res; 00533 int vres; 00534 struct ast_filestream *fs; 00535 struct ast_filestream *vfs; 00536 long sample_offset = 0; 00537 long max_length; 00538 00539 if (argc < 4) 00540 return RESULT_SHOWUSAGE; 00541 if (argc > 5) 00542 return RESULT_SHOWUSAGE; 00543 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00544 return RESULT_SHOWUSAGE; 00545 00546 fs = ast_openstream(chan, argv[2], chan->language); 00547 if (!fs){ 00548 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00549 return RESULT_SUCCESS; 00550 } 00551 vfs = ast_openvstream(chan, argv[2], chan->language); 00552 if (vfs) 00553 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00554 00555 ast_seekstream(fs, 0, SEEK_END); 00556 max_length = ast_tellstream(fs); 00557 ast_seekstream(fs, sample_offset, SEEK_SET); 00558 res = ast_applystream(chan, fs); 00559 if (vfs) vres = ast_applystream(chan, vfs); 00560 res = ast_playstream(fs); 00561 if (vfs) vres = ast_playstream(vfs); 00562 if (res) { 00563 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00564 if (res >= 0) 00565 return RESULT_SHOWUSAGE; 00566 else 00567 return RESULT_FAILURE; 00568 } 00569 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00570 /* this is to check for if ast_waitstream closed the stream, we probably are at 00571 * the end of the stream, return that amount, else check for the amount */ 00572 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00573 ast_stopstream(chan); 00574 if (res == 1) { 00575 /* Stop this command, don't print a result line, as there is a new command */ 00576 return RESULT_SUCCESS; 00577 } 00578 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00579 if (res >= 0) 00580 return RESULT_SUCCESS; 00581 else 00582 return RESULT_FAILURE; 00583 }
|
|
Definition at line 449 of file res_agi.c. References AGI, ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, and fdprintf. 00450 { 00451 int res,x; 00452 if (argc != 3) 00453 return RESULT_SHOWUSAGE; 00454 if (!strncasecmp(argv[2],"on",2)) 00455 x = 1; 00456 else 00457 x = 0; 00458 if (!strncasecmp(argv[2],"mate",4)) 00459 x = 2; 00460 if (!strncasecmp(argv[2],"tdd",3)) 00461 x = 1; 00462 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0); 00463 if (res != RESULT_SUCCESS) 00464 fdprintf(agi->fd, "200 result=0\n"); 00465 else 00466 fdprintf(agi->fd, "200 result=1\n"); 00467 return RESULT_SUCCESS; 00468 }
|
|
Definition at line 1206 of file res_agi.c. References AGI, ast_verbose(), ast_channel::data, agi_state::fd, and fdprintf. 01207 { 01208 int level = 0; 01209 char *prefix; 01210 01211 if (argc < 2) 01212 return RESULT_SHOWUSAGE; 01213 01214 if (argv[2]) 01215 sscanf(argv[2], "%d", &level); 01216 01217 switch (level) { 01218 case 4: 01219 prefix = VERBOSE_PREFIX_4; 01220 break; 01221 case 3: 01222 prefix = VERBOSE_PREFIX_3; 01223 break; 01224 case 2: 01225 prefix = VERBOSE_PREFIX_2; 01226 break; 01227 case 1: 01228 default: 01229 prefix = VERBOSE_PREFIX_1; 01230 break; 01231 } 01232 01233 if (level <= option_verbose) 01234 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01235 01236 fdprintf(agi->fd, "200 result=1\n"); 01237 01238 return RESULT_SUCCESS; 01239 }
|
|
Definition at line 377 of file res_agi.c. References AGI, ast_waitfordigit_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, and fdprintf. 00378 { 00379 int res; 00380 int to; 00381 if (argc != 4) 00382 return RESULT_SHOWUSAGE; 00383 if (sscanf(argv[3], "%d", &to) != 1) 00384 return RESULT_SHOWUSAGE; 00385 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); 00386 fdprintf(agi->fd, "200 result=%d\n", res); 00387 if (res >= 0) 00388 return RESULT_SUCCESS; 00389 else 00390 return RESULT_FAILURE; 00391 }
|
|
Definition at line 1660 of file res_agi.c. References ast_cli(), agi_command::cmda, commands, join(), and agi_command::summary. Referenced by handle_help(), and handle_showagi(). 01661 { 01662 char fullcmd[80]; 01663 char matchstr[80]; 01664 int x; 01665 struct agi_command *e; 01666 if (match) 01667 join(matchstr, sizeof(matchstr), match); 01668 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01669 if (!commands[x].cmda[0]) break; 01670 e = &commands[x]; 01671 if (e) 01672 join(fullcmd, sizeof(fullcmd), e->cmda); 01673 /* Hide commands that start with '_' */ 01674 if (fullcmd[0] == '_') 01675 continue; 01676 if (match) { 01677 if (strncasecmp(matchstr, fullcmd, strlen(matchstr))) { 01678 continue; 01679 } 01680 } 01681 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01682 } 01683 return 0; 01684 }
|
|
Definition at line 1644 of file res_agi.c. References s. Referenced by __ast_cli_generator(), find_best(), handle_dumpagihtml(), handle_help(), handle_showagi(), and help_workhorse(). 01645 { 01646 int x; 01647 01648 /* Join words into a string */ 01649 if (!s) { 01650 return; 01651 } 01652 s[0] = '\0'; 01653 for (x=0; w[x]; x++) { 01654 if (x) 01655 strncat(s, " ", len - strlen(s) - 1); 01656 strncat(s, w[x], len - strlen(s) - 1); 01657 } 01658 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 2146 of file res_agi.c. 02147 {
02148 return ASTERISK_GPL_KEY;
02149 }
|
|
Definition at line 132 of file res_agi.c. References 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(), and s. Referenced by launch_script(). 00133 { 00134 int s; 00135 int flags; 00136 struct pollfd pfds[1]; 00137 char *host; 00138 char *c; int port = AGI_PORT; 00139 char *script=""; 00140 struct sockaddr_in sin; 00141 struct hostent *hp; 00142 struct ast_hostent ahp; 00143 00144 host = ast_strdupa(agiurl + 6); /* Remove agi:// */ 00145 if (!host) 00146 return -1; 00147 /* Strip off any script name */ 00148 if ((c = strchr(host, '/'))) { 00149 *c = '\0'; 00150 c++; 00151 script = c; 00152 } 00153 if ((c = strchr(host, ':'))) { 00154 *c = '\0'; 00155 c++; 00156 port = atoi(c); 00157 } 00158 if (efd) { 00159 ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n"); 00160 return -1; 00161 } 00162 hp = ast_gethostbyname(host, &ahp); 00163 if (!hp) { 00164 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host); 00165 return -1; 00166 } 00167 s = socket(AF_INET, SOCK_STREAM, 0); 00168 if (s < 0) { 00169 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 00170 return -1; 00171 } 00172 flags = fcntl(s, F_GETFL); 00173 if (flags < 0) { 00174 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno)); 00175 close(s); 00176 return -1; 00177 } 00178 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { 00179 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno)); 00180 close(s); 00181 return -1; 00182 } 00183 memset(&sin, 0, sizeof(sin)); 00184 sin.sin_family = AF_INET; 00185 sin.sin_port = htons(port); 00186 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00187 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) { 00188 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno)); 00189 close(s); 00190 return -1; 00191 } 00192 00193 pfds[0].fd = s; 00194 pfds[0].events = POLLOUT; 00195 while (poll(pfds, 1, MAX_AGI_CONNECT) != 1) { 00196 if (errno != EINTR) { 00197 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00198 close(s); 00199 return -1; 00200 } 00201 } 00202 00203 while (write(s, "agi_network: yes\n", strlen("agi_network: yes\n")) < 0) { 00204 if (errno != EINTR) { 00205 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00206 close(s); 00207 return -1; 00208 } 00209 } 00210 00211 /* If we have a script parameter, relay it to the fastagi server */ 00212 if (!ast_strlen_zero(script)) 00213 fdprintf(s, "agi_network_script: %s\n", script); 00214 00215 if (option_debug > 3) 00216 ast_log(LOG_DEBUG, "Wow, connected!\n"); 00217 fds[0] = s; 00218 fds[1] = s; 00219 *opid = -1; 00220 return 0; 00221 }
|
|
Definition at line 223 of file res_agi.c. References ast_config_AST_AGI_DIR, ast_log(), ast_set_priority(), ast_verbose(), launch_netscript(), LOG_WARNING, option_verbose, and VERBOSE_PREFIX_3. Referenced by agi_exec_full(). 00224 { 00225 char tmp[256]; 00226 int pid; 00227 int toast[2]; 00228 int fromast[2]; 00229 int audio[2]; 00230 int x; 00231 int res; 00232 sigset_t signal_set; 00233 00234 if (!strncasecmp(script, "agi://", 6)) 00235 return launch_netscript(script, argv, fds, efd, opid); 00236 00237 if (script[0] != '/') { 00238 snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script); 00239 script = tmp; 00240 } 00241 if (pipe(toast)) { 00242 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno)); 00243 return -1; 00244 } 00245 if (pipe(fromast)) { 00246 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno)); 00247 close(toast[0]); 00248 close(toast[1]); 00249 return -1; 00250 } 00251 if (efd) { 00252 if (pipe(audio)) { 00253 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00254 close(fromast[0]); 00255 close(fromast[1]); 00256 close(toast[0]); 00257 close(toast[1]); 00258 return -1; 00259 } 00260 res = fcntl(audio[1], F_GETFL); 00261 if (res > -1) 00262 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK); 00263 if (res < 0) { 00264 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00265 close(fromast[0]); 00266 close(fromast[1]); 00267 close(toast[0]); 00268 close(toast[1]); 00269 close(audio[0]); 00270 close(audio[1]); 00271 return -1; 00272 } 00273 } 00274 pid = fork(); 00275 if (pid < 0) { 00276 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); 00277 return -1; 00278 } 00279 if (!pid) { 00280 /* Redirect stdin and out, provide enhanced audio channel if desired */ 00281 dup2(fromast[0], STDIN_FILENO); 00282 dup2(toast[1], STDOUT_FILENO); 00283 if (efd) { 00284 dup2(audio[0], STDERR_FILENO + 1); 00285 } else { 00286 close(STDERR_FILENO + 1); 00287 } 00288 00289 /* unblock important signal handlers */ 00290 if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { 00291 ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); 00292 exit(1); 00293 } 00294 00295 /* Close everything but stdin/out/error */ 00296 for (x=STDERR_FILENO + 2;x<1024;x++) 00297 close(x); 00298 00299 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ 00300 ast_set_priority(0); 00301 00302 /* Execute script */ 00303 execv(script, argv); 00304 /* Can't use ast_log since FD's are closed */ 00305 fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno)); 00306 exit(1); 00307 } 00308 if (option_verbose > 2) 00309 ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); 00310 fds[0] = toast[0]; 00311 fds[1] = fromast[1]; 00312 if (efd) { 00313 *efd = audio[1]; 00314 } 00315 /* close what we're not using in the parent */ 00316 close(toast[1]); 00317 close(fromast[0]); 00318 00319 if (efd) { 00320 /* [PHM 12/18/03] */ 00321 close(audio[0]); 00322 } 00323 00324 *opid = pid; 00325 return 0; 00326 00327 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 2123 of file res_agi.c. References agi_exec(), app, ast_cli_register(), ast_register_application(), cli_debug, cli_no_debug, deadagi_exec(), deadapp, deadsynopsis, descrip, dumpagihtml, eagi_exec(), eapp, esynopsis, showagi, and synopsis. 02124 { 02125 ast_cli_register(&showagi); 02126 ast_cli_register(&dumpagihtml); 02127 ast_cli_register(&cli_debug); 02128 ast_cli_register(&cli_no_debug); 02129 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02130 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02131 return ast_register_application(app, agi_exec, synopsis, descrip); 02132 }
|
|
Definition at line 1749 of file res_agi.c. References ast_log(), LOG_WARNING, MAX_ARGS, and s. Referenced by __ast_cli_generator(), agi_handle_command(), and ast_cli_command(). 01750 { 01751 int x=0; 01752 int quoted=0; 01753 int escaped=0; 01754 int whitespace=1; 01755 char *cur; 01756 01757 cur = s; 01758 while(*s) { 01759 switch(*s) { 01760 case '"': 01761 /* If it's escaped, put a literal quote */ 01762 if (escaped) 01763 goto normal; 01764 else 01765 quoted = !quoted; 01766 if (quoted && whitespace) { 01767 /* If we're starting a quote, coming off white space start a new word, too */ 01768 argv[x++] = cur; 01769 whitespace=0; 01770 } 01771 escaped = 0; 01772 break; 01773 case ' ': 01774 case '\t': 01775 if (!quoted && !escaped) { 01776 /* If we're not quoted, mark this as whitespace, and 01777 end the previous argument */ 01778 whitespace = 1; 01779 *(cur++) = '\0'; 01780 } else 01781 /* Otherwise, just treat it as anything else */ 01782 goto normal; 01783 break; 01784 case '\\': 01785 /* If we're escaped, print a literal, otherwise enable escaping */ 01786 if (escaped) { 01787 goto normal; 01788 } else { 01789 escaped=1; 01790 } 01791 break; 01792 default: 01793 normal: 01794 if (whitespace) { 01795 if (x >= MAX_ARGS -1) { 01796 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01797 break; 01798 } 01799 /* Coming off of whitespace, start the next argument */ 01800 argv[x++] = cur; 01801 whitespace=0; 01802 } 01803 *(cur++) = *s; 01804 escaped=0; 01805 } 01806 s++; 01807 } 01808 /* Null terminate */ 01809 *(cur++) = '\0'; 01810 argv[x] = NULL; 01811 *max = x; 01812 return 0; 01813 }
|
|
Definition at line 1853 of file res_agi.c. References AGI, agi_handle_command(), ast_frfree(), ast_log(), 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, ast_channel::name, option_verbose, setup_env(), and VERBOSE_PREFIX_3. Referenced by agi_exec_full(). 01854 { 01855 struct ast_channel *c; 01856 int outfd; 01857 int ms; 01858 int returnstatus = 0; 01859 struct ast_frame *f; 01860 char buf[2048]; 01861 FILE *readf; 01862 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01863 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01864 int retry = RETRY; 01865 01866 if (!(readf = fdopen(agi->ctrl, "r"))) { 01867 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01868 if (pid > -1) 01869 kill(pid, SIGHUP); 01870 close(agi->ctrl); 01871 return -1; 01872 } 01873 setlinebuf(readf); 01874 setup_env(chan, request, agi->fd, (agi->audio > -1)); 01875 for (;;) { 01876 ms = -1; 01877 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01878 if (c) { 01879 retry = RETRY; 01880 /* Idle the channel until we get a command */ 01881 f = ast_read(c); 01882 if (!f) { 01883 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01884 returnstatus = -1; 01885 break; 01886 } else { 01887 /* If it's voice, write it to the audio pipe */ 01888 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01889 /* Write, ignoring errors */ 01890 write(agi->audio, f->data, f->datalen); 01891 } 01892 ast_frfree(f); 01893 } 01894 } else if (outfd > -1) { 01895 retry = RETRY; 01896 if (!fgets(buf, sizeof(buf), readf)) { 01897 /* Program terminated */ 01898 if (returnstatus) 01899 returnstatus = -1; 01900 if (option_verbose > 2) 01901 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01902 /* No need to kill the pid anymore, since they closed us */ 01903 pid = -1; 01904 break; 01905 } 01906 /* get rid of trailing newline, if any */ 01907 if (*buf && buf[strlen(buf) - 1] == '\n') 01908 buf[strlen(buf) - 1] = 0; 01909 if (agidebug) 01910 ast_verbose("AGI Rx << %s\n", buf); 01911 returnstatus |= agi_handle_command(chan, agi, buf); 01912 /* If the handle_command returns -1, we need to stop */ 01913 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01914 break; 01915 } 01916 } else { 01917 if (--retry <= 0) { 01918 ast_log(LOG_WARNING, "No channel, no fd?\n"); 01919 returnstatus = -1; 01920 break; 01921 } 01922 } 01923 } 01924 /* Notify process */ 01925 if (pid > -1) { 01926 if (kill(pid, SIGHUP)) 01927 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 01928 } 01929 fclose(readf); 01930 return returnstatus; 01931 }
|
|
Definition at line 329 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, ast_channel::type, and ast_channel::uniqueid. Referenced by run_agi(). 00330 { 00331 /* Print initial environment, with agi_request always being the first 00332 thing */ 00333 fdprintf(fd, "agi_request: %s\n", request); 00334 fdprintf(fd, "agi_channel: %s\n", chan->name); 00335 fdprintf(fd, "agi_language: %s\n", chan->language); 00336 fdprintf(fd, "agi_type: %s\n", chan->type); 00337 fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid); 00338 00339 /* ANI/DNIS */ 00340 fdprintf(fd, "agi_callerid: %s\n", chan->cid.cid_num ? chan->cid.cid_num : "unknown"); 00341 fdprintf(fd, "agi_calleridname: %s\n", chan->cid.cid_name ? chan->cid.cid_name : "unknown"); 00342 fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres); 00343 fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2); 00344 fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton); 00345 fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns); 00346 fdprintf(fd, "agi_dnid: %s\n", chan->cid.cid_dnid ? chan->cid.cid_dnid : "unknown"); 00347 fdprintf(fd, "agi_rdnis: %s\n", chan->cid.cid_rdnis ? chan->cid.cid_rdnis : "unknown"); 00348 00349 /* Context information */ 00350 fdprintf(fd, "agi_context: %s\n", chan->context); 00351 fdprintf(fd, "agi_extension: %s\n", chan->exten); 00352 fdprintf(fd, "agi_priority: %d\n", chan->priority); 00353 fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0"); 00354 00355 /* User information */ 00356 fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); 00357 00358 /* End with empty return */ 00359 fdprintf(fd, "\n"); 00360 }
|
|
Cleanup all module structures, sockets, etc. Standard module functions ... Definition at line 2111 of file res_agi.c. References app, ast_cli_unregister(), ast_unregister_application(), cli_debug, cli_no_debug, deadapp, dumpagihtml, eapp, and showagi. 02112 { 02113 STANDARD_HANGUP_LOCALUSERS; 02114 ast_cli_unregister(&showagi); 02115 ast_cli_unregister(&dumpagihtml); 02116 ast_cli_unregister(&cli_debug); 02117 ast_cli_unregister(&cli_no_debug); 02118 ast_unregister_application(eapp); 02119 ast_unregister_application(deadapp); 02120 return ast_unregister_application(app); 02121 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 2139 of file res_agi.c. References STANDARD_USECOUNT. 02140 { 02141 int res; 02142 STANDARD_USECOUNT(res); 02143 return res; 02144 }
|
|
Definition at line 97 of file res_agi.c. Referenced by agi_do_debug(), and agi_no_debug(). |
|
Definition at line 75 of file res_agi.c. Referenced by handle_exec(), load_module(), and unload_module(). |
|
Initial value: { { "agi", "debug", NULL }, agi_do_debug, "Enable AGI debugging", debug_usage } Definition at line 1330 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "agi", "no", "debug", NULL }, agi_no_debug, "Disable AGI debugging", no_debug_usage } Definition at line 1333 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 1604 of file res_agi.c. Referenced by agi_register(), agi_unregister(), find_command(), handle_dumpagihtml(), and help_workhorse(). |
|
Definition at line 79 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 83 of file res_agi.c. Referenced by load_module(). |
|
Initial value: "Usage: agi debug\n" " Enables dumping of AGI transactions for debugging purposes\n" |
|
Definition at line 85 of file res_agi.c. Referenced by load_module(). |
|
Initial value: { { "dump", "agihtml", NULL }, handle_dumpagihtml, "Dumps a list of agi command in html format", dumpagihtml_help } Definition at line 2108 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: dump agihtml <filename>\n" " Dumps the agi command list in html format to given filename\n" |
|
Definition at line 77 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 no debug\n" " Disables dumping of AGI transactions for debugging purposes\n" |
|
Initial value: { { "show", "agi", NULL }, handle_showagi, "Show AGI commands or specific help", showagi_help } Definition at line 2105 of file res_agi.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: show agi [topic]\n" " When called with a topic as an argument, displays usage\n" " information on the given command. If called without a\n" " topic, it provides a list of AGI commands.\n" |
|
|
|
Definition at line 81 of file res_agi.c. Referenced by load_module(). |
|
|
|
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" |
|
|