#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"
Include dependency graph for res_agi.c:
Go to the source code of this file.
Defines | |
#define | AGI_PORT 4573 |
#define | fdprintf agi_debug_cli |
#define | MAX_AGI_CONNECT 2000 |
#define | MAX_ARGS 128 |
#define | MAX_COMMANDS 128 |
#define | RETRY 3 |
#define | TONE_BLOCK_SIZE 200 |
Functions | |
static void | agi_debug_cli (int fd, char *fmt,...) |
static int | agi_do_debug (int fd, int argc, char *argv[]) |
static int | agi_exec (struct ast_channel *chan, void *data) |
static int | agi_exec_full (struct ast_channel *chan, void *data, int enhanced, int dead) |
static int | agi_handle_command (struct ast_channel *chan, AGI *agi, char *buf) |
static int | agi_no_debug (int fd, int argc, char *argv[]) |
int | agi_register (agi_command *agi) |
void | agi_unregister (agi_command *agi) |
static int | deadagi_exec (struct ast_channel *chan, void *data) |
char * | description (void) |
Provides a description of the module. | |
static int | eagi_exec (struct ast_channel *chan, void *data) |
static agi_command * | find_command (char *cmds[], int exact) |
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_dumpagihtml (int fd, 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 void | join (char *s, size_t len, char *w[]) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static int | launch_netscript (char *agiurl, char *argv[], int *fds, int *efd, int *opid) |
static int | launch_script (char *script, char *argv[], int *fds, int *efd, int *opid) |
int | load_module (void) |
Initialize the module. | |
static int | parse_args (char *s, int *max, char *argv[]) |
static int | run_agi (struct ast_channel *chan, char *request, AGI *agi, int pid, int dead) |
static 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 | |
static int | agidebug = 0 |
static char * | app = "AGI" |
static struct ast_cli_entry | cli_debug |
static struct ast_cli_entry | cli_no_debug |
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 struct ast_cli_entry | dumpagihtml |
static char | dumpagihtml_help [] |
static char * | eapp = "EAGI" |
static char * | esynopsis = "Executes an EAGI compliant application" |
LOCAL_USER_DECL | |
static char | no_debug_usage [] |
static struct ast_cli_entry | showagi |
static char | showagi_help [] |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Executes an AGI compliant application" |
static char * | tdesc = "Asterisk Gateway Interface (AGI)" |
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.
|
Definition at line 109 of file res_agi.c. Referenced by launch_netscript(). |
|
|
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 1844 of file res_agi.c. Referenced by run_agi(). |
|
|
|
Definition at line 111 of file res_agi.c. References ast_carefulwrite(), ast_log(), ast_verbose(), free, LOG_ERROR, ast_variable::stuff, 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 1304 of file res_agi.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01305 { 01306 if (argc != 2) 01307 return RESULT_SHOWUSAGE; 01308 agidebug = 1; 01309 ast_cli(fd, "AGI Debugging Enabled\n"); 01310 return RESULT_SUCCESS; 01311 }
|
|
Definition at line 2053 of file res_agi.c. References ast_channel::_softhangup, agi_exec_full(), ast_log(), localuser::chan, and LOG_WARNING. Referenced by load_module(). 02054 { 02055 if (chan->_softhangup) 02056 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02057 return agi_exec_full(chan, data, 0, 0); 02058 }
|
|
Definition at line 2004 of file res_agi.c. References ast_channel::_state, ast_answer(), ast_log(), AST_STATE_UP, ast_strlen_zero(), localuser::chan, 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(). 02005 { 02006 int res=0; 02007 struct localuser *u; 02008 char *argv[MAX_ARGS]; 02009 char buf[2048]=""; 02010 char *tmp = (char *)buf; 02011 int argc = 0; 02012 int fds[2]; 02013 int efd = -1; 02014 int pid; 02015 char *stringp; 02016 AGI agi; 02017 02018 if (ast_strlen_zero(data)) { 02019 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02020 return -1; 02021 } 02022 ast_copy_string(buf, data, sizeof(buf)); 02023 02024 memset(&agi, 0, sizeof(agi)); 02025 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS - 1) 02026 argv[argc++] = stringp; 02027 argv[argc] = NULL; 02028 02029 LOCAL_USER_ADD(u); 02030 #if 0 02031 /* Answer if need be */ 02032 if (chan->_state != AST_STATE_UP) { 02033 if (ast_answer(chan)) { 02034 LOCAL_USER_REMOVE(u); 02035 return -1; 02036 } 02037 } 02038 #endif 02039 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); 02040 if (!res) { 02041 agi.fd = fds[1]; 02042 agi.ctrl = fds[0]; 02043 agi.audio = efd; 02044 res = run_agi(chan, argv[0], &agi, pid, dead); 02045 close(fds[1]); 02046 if (efd > -1) 02047 close(efd); 02048 } 02049 LOCAL_USER_REMOVE(u); 02050 return res; 02051 }
|
|
Definition at line 1807 of file res_agi.c. References AST_PBX_KEEPALIVE, agi_state::fd, fdprintf, find_command(), agi_command::handler, MAX_ARGS, parse_args(), RESULT_FAILURE, RESULT_SHOWUSAGE, and agi_command::usage. Referenced by run_agi(). 01808 { 01809 char *argv[MAX_ARGS]; 01810 int argc = 0; 01811 int res; 01812 agi_command *c; 01813 argc = MAX_ARGS; 01814 01815 parse_args(buf, &argc, argv); 01816 #if 0 01817 { int x; 01818 for (x=0; x<argc; x++) 01819 fprintf(stderr, "Got Arg%d: %s\n", x, argv[x]); } 01820 #endif 01821 c = find_command(argv, 0); 01822 if (c) { 01823 res = c->handler(chan, agi, argc, argv); 01824 switch(res) { 01825 case RESULT_SHOWUSAGE: 01826 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01827 fdprintf(agi->fd, c->usage); 01828 fdprintf(agi->fd, "520 End of proper usage.\n"); 01829 break; 01830 case AST_PBX_KEEPALIVE: 01831 /* We've been asked to keep alive, so do so */ 01832 return AST_PBX_KEEPALIVE; 01833 break; 01834 case RESULT_FAILURE: 01835 /* They've already given the failure. We've been hung up on so handle this 01836 appropriately */ 01837 return -1; 01838 } 01839 } else { 01840 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01841 } 01842 return 0; 01843 }
|
|
Definition at line 1313 of file res_agi.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01314 { 01315 if (argc != 3) 01316 return RESULT_SHOWUSAGE; 01317 agidebug = 0; 01318 ast_cli(fd, "AGI Debugging Disabled\n"); 01319 return RESULT_SUCCESS; 01320 }
|
|
Definition at line 1678 of file res_agi.c. References ast_log(), agi_command::cmda, commands, LOG_WARNING, and MAX_COMMANDS. 01679 { 01680 int x; 01681 for (x=0; x<MAX_COMMANDS - 1; x++) { 01682 if (commands[x].cmda[0] == agi->cmda[0]) { 01683 ast_log(LOG_WARNING, "Command already registered!\n"); 01684 return -1; 01685 } 01686 } 01687 for (x=0; x<MAX_COMMANDS - 1; x++) { 01688 if (!commands[x].cmda[0]) { 01689 commands[x] = *agi; 01690 return 0; 01691 } 01692 } 01693 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01694 return -1; 01695 }
|
|
Definition at line 1697 of file res_agi.c. References agi_command::cmda, commands, and MAX_COMMANDS. 01698 { 01699 int x; 01700 for (x=0; x<MAX_COMMANDS - 1; x++) { 01701 if (commands[x].cmda[0] == agi->cmda[0]) { 01702 memset(&commands[x], 0, sizeof(agi_command)); 01703 } 01704 } 01705 }
|
|
Definition at line 2081 of file res_agi.c. References agi_exec_full(), and localuser::chan. Referenced by load_module(). 02082 { 02083 return agi_exec_full(chan, data, 0, 1); 02084 }
|
|
Provides a description of the module.
Definition at line 2126 of file res_agi.c. References tdesc. 02127 { 02128 return tdesc; 02129 }
|
|
Definition at line 2060 of file res_agi.c. References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), localuser::chan, LOG_WARNING, ast_channel::name, and ast_channel::readformat. Referenced by load_module(). 02061 { 02062 int readformat; 02063 int res; 02064 02065 if (chan->_softhangup) 02066 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02067 readformat = chan->readformat; 02068 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02069 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02070 return -1; 02071 } 02072 res = agi_exec_full(chan, data, 1, 0); 02073 if (!res) { 02074 if (ast_set_read_format(chan, readformat)) { 02075 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02076 } 02077 } 02078 return res; 02079 }
|
|
Definition at line 1707 of file res_agi.c. References agi_command::cmda, commands, and match(). 01708 { 01709 int x; 01710 int y; 01711 int match; 01712 01713 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01714 if (!commands[x].cmda[0]) 01715 break; 01716 /* start optimistic */ 01717 match = 1; 01718 for (y=0; match && cmds[y]; y++) { 01719 /* If there are no more words in the command (and we're looking for 01720 an exact match) or there is a difference between the two words, 01721 then this is not a match */ 01722 if (!commands[x].cmda[y] && !exact) 01723 break; 01724 /* don't segfault if the next part of a command doesn't exist */ 01725 if (!commands[x].cmda[y]) 01726 return NULL; 01727 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01728 match = 0; 01729 } 01730 /* If more words are needed to complete the command then this is not 01731 a candidate (unless we're looking for a really inexact answer */ 01732 if ((exact > -1) && commands[x].cmda[y]) 01733 match = 0; 01734 if (match) 01735 return &commands[x]; 01736 } 01737 return NULL; 01738 }
|
|
Definition at line 362 of file res_agi.c. References ast_channel::_state, ast_answer(), AST_STATE_UP, agi_state::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS. 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 1031 of file res_agi.c. References agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::whentohangup. 01032 { 01033 int timeout; 01034 01035 if (argc != 3) 01036 return RESULT_SHOWUSAGE; 01037 if (sscanf(argv[2], "%d", &timeout) != 1) 01038 return RESULT_SHOWUSAGE; 01039 if (timeout < 0) 01040 timeout = 0; 01041 if (timeout) 01042 chan->whentohangup = time(NULL) + timeout; 01043 else 01044 chan->whentohangup = 0; 01045 fdprintf(agi->fd, "200 result=0\n"); 01046 return RESULT_SUCCESS; 01047 }
|
|
Definition at line 1120 of file res_agi.c. References ast_channel::_state, ast_get_channel_by_name_locked(), ast_mutex_unlock(), agi_state::fd, fdprintf, ast_channel::lock, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01121 { 01122 struct ast_channel *c; 01123 if (argc == 2) { 01124 /* no argument: supply info on the current channel */ 01125 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01126 return RESULT_SUCCESS; 01127 } else if (argc == 3) { 01128 /* one argument: look for info on the specified channel */ 01129 c = ast_get_channel_by_name_locked(argv[2]); 01130 if (c) { 01131 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01132 ast_mutex_unlock(&c->lock); 01133 return RESULT_SUCCESS; 01134 } 01135 /* if we get this far no channel name matched the argument given */ 01136 fdprintf(agi->fd, "200 result=-1\n"); 01137 return RESULT_SUCCESS; 01138 } else { 01139 return RESULT_SHOWUSAGE; 01140 } 01141 }
|
|
Definition at line 485 of file res_agi.c. References ast_control_streamfile(), ast_strlen_zero(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and skipms. 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 1264 of file res_agi.c. References ast_db_del(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01265 { 01266 int res; 01267 01268 if (argc != 4) 01269 return RESULT_SHOWUSAGE; 01270 res = ast_db_del(argv[2], argv[3]); 01271 if (res) 01272 fdprintf(agi->fd, "200 result=0\n"); 01273 else 01274 fdprintf(agi->fd, "200 result=1\n"); 01275 01276 return RESULT_SUCCESS; 01277 }
|
|
Definition at line 1279 of file res_agi.c. References ast_db_deltree(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01280 { 01281 int res; 01282 if ((argc < 3) || (argc > 4)) 01283 return RESULT_SHOWUSAGE; 01284 if (argc == 4) 01285 res = ast_db_deltree(argv[2], argv[3]); 01286 else 01287 res = ast_db_deltree(argv[2], NULL); 01288 01289 if (res) 01290 fdprintf(agi->fd, "200 result=0\n"); 01291 else 01292 fdprintf(agi->fd, "200 result=1\n"); 01293 return RESULT_SUCCESS; 01294 }
|
|
Definition at line 1233 of file res_agi.c. References ast_db_get(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01234 { 01235 int res; 01236 char tmp[256]; 01237 01238 if (argc != 4) 01239 return RESULT_SHOWUSAGE; 01240 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01241 if (res) 01242 fdprintf(agi->fd, "200 result=0\n"); 01243 else 01244 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01245 01246 return RESULT_SUCCESS; 01247 }
|
|
Definition at line 1249 of file res_agi.c. References ast_db_put(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01250 { 01251 int res; 01252 01253 if (argc != 5) 01254 return RESULT_SHOWUSAGE; 01255 res = ast_db_put(argv[2], argv[3], argv[4]); 01256 if (res) 01257 fdprintf(agi->fd, "200 result=0\n"); 01258 else 01259 fdprintf(agi->fd, "200 result=1\n"); 01260 01261 return RESULT_SUCCESS; 01262 }
|
|
Definition at line 1948 of file res_agi.c. References ast_cli(), agi_command::cmda, commands, join(), RESULT_SHOWUSAGE, strsep(), agi_command::summary, and agi_command::usage. 01948 { 01949 struct agi_command *e; 01950 char fullcmd[80]; 01951 char *tempstr; 01952 int x; 01953 FILE *htmlfile; 01954 01955 if ((argc < 3)) 01956 return RESULT_SHOWUSAGE; 01957 01958 if (!(htmlfile = fopen(argv[2], "wt"))) { 01959 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 01960 return RESULT_SHOWUSAGE; 01961 } 01962 01963 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 01964 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 01965 01966 01967 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 01968 01969 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01970 char *stringp=NULL; 01971 if (!commands[x].cmda[0]) break; 01972 e = &commands[x]; 01973 if (e) 01974 join(fullcmd, sizeof(fullcmd), e->cmda); 01975 /* Hide commands that start with '_' */ 01976 if (fullcmd[0] == '_') 01977 continue; 01978 01979 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 01980 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TD></TR>\n", fullcmd,e->summary); 01981 01982 01983 stringp=e->usage; 01984 tempstr = strsep(&stringp, "\n"); 01985 01986 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 01987 01988 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 01989 while ((tempstr = strsep(&stringp, "\n")) != NULL) { 01990 fprintf(htmlfile, "%s<BR>\n",tempstr); 01991 01992 } 01993 fprintf(htmlfile, "</TD></TR>\n"); 01994 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 01995 01996 } 01997 01998 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 01999 fclose(htmlfile); 02000 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 02001 return RESULT_SUCCESS; 02002 }
|
|
Definition at line 1075 of file res_agi.c. References app, ast_log(), ast_verbose(), agi_state::fd, fdprintf, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), RESULT_SHOWUSAGE, and VERBOSE_PREFIX_3. 01076 { 01077 int res; 01078 struct ast_app *app; 01079 01080 if (argc < 2) 01081 return RESULT_SHOWUSAGE; 01082 01083 if (option_verbose > 2) 01084 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01085 01086 app = pbx_findapp(argv[1]); 01087 01088 if (app) { 01089 res = pbx_exec(chan, app, argv[2], 1); 01090 } else { 01091 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01092 res = -2; 01093 } 01094 fdprintf(agi->fd, "200 result=%d\n", res); 01095 01096 return res; 01097 }
|
|
Definition at line 797 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. 00798 { 00799 int res; 00800 char data[1024]; 00801 int max; 00802 int timeout; 00803 00804 if (argc < 3) 00805 return RESULT_SHOWUSAGE; 00806 if (argc >= 4) 00807 timeout = atoi(argv[3]); 00808 else 00809 timeout = 0; 00810 if (argc >= 5) 00811 max = atoi(argv[4]); 00812 else 00813 max = 1024; 00814 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00815 if (res == 2) /* New command */ 00816 return RESULT_SUCCESS; 00817 else if (res == 1) 00818 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00819 else if (res < 0 ) 00820 fdprintf(agi->fd, "200 result=-1\n"); 00821 else 00822 fdprintf(agi->fd, "200 result=%s\n", data); 00823 return RESULT_SUCCESS; 00824 }
|
|
Definition at line 578 of file res_agi.c. References 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, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, and VERBOSE_PREFIX_3. 00579 { 00580 int res; 00581 struct ast_filestream *fs; 00582 long sample_offset = 0; 00583 long max_length; 00584 int timeout = 0; 00585 char *edigits = NULL; 00586 00587 if ( argc < 4 || argc > 5 ) 00588 return RESULT_SHOWUSAGE; 00589 00590 if ( argv[3] ) 00591 edigits = argv[3]; 00592 00593 if ( argc == 5 ) 00594 timeout = atoi(argv[4]); 00595 else if (chan->pbx->dtimeout) { 00596 /* by default dtimeout is set to 5sec */ 00597 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00598 } 00599 00600 fs = ast_openstream(chan, argv[2], chan->language); 00601 if (!fs){ 00602 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00603 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00604 return RESULT_SUCCESS; 00605 } 00606 if (option_verbose > 2) 00607 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00608 00609 ast_seekstream(fs, 0, SEEK_END); 00610 max_length = ast_tellstream(fs); 00611 ast_seekstream(fs, sample_offset, SEEK_SET); 00612 res = ast_applystream(chan, fs); 00613 res = ast_playstream(fs); 00614 if (res) { 00615 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00616 if (res >= 0) 00617 return RESULT_SHOWUSAGE; 00618 else 00619 return RESULT_FAILURE; 00620 } 00621 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00622 /* this is to check for if ast_waitstream closed the stream, we probably are at 00623 * the end of the stream, return that amount, else check for the amount */ 00624 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00625 ast_stopstream(chan); 00626 if (res == 1) { 00627 /* Stop this command, don't print a result line, as there is a new command */ 00628 return RESULT_SUCCESS; 00629 } 00630 00631 /* If the user didnt press a key, wait for digitTimeout*/ 00632 if (res == 0 ) { 00633 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00634 /* Make sure the new result is in the escape digits of the GET OPTION */ 00635 if ( !strchr(edigits,res) ) 00636 res=0; 00637 } 00638 00639 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00640 if (res >= 0) 00641 return RESULT_SUCCESS; 00642 else 00643 return RESULT_FAILURE; 00644 }
|
|
Definition at line 1152 of file res_agi.c. References ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01153 { 01154 char *ret; 01155 char tempstr[1024]; 01156 01157 if (argc != 3) 01158 return RESULT_SHOWUSAGE; 01159 01160 /* check if we want to execute an ast_custom_function */ 01161 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01162 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)); 01163 } else { 01164 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01165 } 01166 01167 if (ret) 01168 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01169 else 01170 fdprintf(agi->fd, "200 result=0\n"); 01171 01172 return RESULT_SUCCESS; 01173 }
|
|
Definition at line 1175 of file res_agi.c. References ast_get_channel_by_name_locked(), ast_mutex_unlock(), agi_state::fd, fdprintf, ast_channel::lock, pbx_substitute_variables_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01176 { 01177 char tmp[4096] = ""; 01178 struct ast_channel *chan2=NULL; 01179 01180 if ((argc != 4) && (argc != 5)) 01181 return RESULT_SHOWUSAGE; 01182 if (argc == 5) { 01183 chan2 = ast_get_channel_by_name_locked(argv[4]); 01184 } else { 01185 chan2 = chan; 01186 } 01187 if (chan) { /* XXX isn't this chan2 ? */ 01188 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01189 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01190 } else { 01191 fdprintf(agi->fd, "200 result=0\n"); 01192 } 01193 if (chan2 && (chan2 != chan)) 01194 ast_mutex_unlock(&chan2->lock); 01195 return RESULT_SUCCESS; 01196 }
|
|
Definition at line 1049 of file res_agi.c. References ast_get_channel_by_name_locked(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01050 { 01051 struct ast_channel *c; 01052 if (argc == 1) { 01053 /* no argument: hangup the current channel */ 01054 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01055 fdprintf(agi->fd, "200 result=1\n"); 01056 return RESULT_SUCCESS; 01057 } else if (argc == 2) { 01058 /* one argument: look for info on the specified channel */ 01059 c = ast_get_channel_by_name_locked(argv[1]); 01060 if (c) { 01061 /* we have a matching channel */ 01062 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01063 fdprintf(agi->fd, "200 result=1\n"); 01064 ast_mutex_unlock(&c->lock); 01065 return RESULT_SUCCESS; 01066 } 01067 /* if we get this far no channel name matched the argument given */ 01068 fdprintf(agi->fd, "200 result=-1\n"); 01069 return RESULT_SUCCESS; 01070 } else { 01071 return RESULT_SHOWUSAGE; 01072 } 01073 }
|
|
Definition at line 1328 of file res_agi.c. References agi_state::fd, fdprintf, and RESULT_SUCCESS. 01329 { 01330 fdprintf(agi->fd, "200 result=0\n"); 01331 return RESULT_SUCCESS; 01332 }
|
|
Definition at line 861 of file res_agi.c. References 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(), ast_dsp::f, agi_state::fd, fdprintf, ast_frame::frametype, ast_channel::language, LOG_WARNING, ast_channel::name, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, ast_frame::subclass, and ast_dsp::totalsilence. 00862 { 00863 struct ast_filestream *fs; 00864 struct ast_frame *f; 00865 struct timeval start; 00866 long sample_offset = 0; 00867 int res = 0; 00868 int ms; 00869 00870 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00871 int totalsilence = 0; 00872 int dspsilence = 0; 00873 int silence = 0; /* amount of silence to allow */ 00874 int gotsilence = 0; /* did we timeout for silence? */ 00875 char *silencestr=NULL; 00876 int rfmt=0; 00877 00878 00879 /* XXX EAGI FIXME XXX */ 00880 00881 if (argc < 6) 00882 return RESULT_SHOWUSAGE; 00883 if (sscanf(argv[5], "%d", &ms) != 1) 00884 return RESULT_SHOWUSAGE; 00885 00886 if (argc > 6) 00887 silencestr = strchr(argv[6],'s'); 00888 if ((argc > 7) && (!silencestr)) 00889 silencestr = strchr(argv[7],'s'); 00890 if ((argc > 8) && (!silencestr)) 00891 silencestr = strchr(argv[8],'s'); 00892 00893 if (silencestr) { 00894 if (strlen(silencestr) > 2) { 00895 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00896 silencestr++; 00897 silencestr++; 00898 if (silencestr) 00899 silence = atoi(silencestr); 00900 if (silence > 0) 00901 silence *= 1000; 00902 } 00903 } 00904 } 00905 00906 if (silence > 0) { 00907 rfmt = chan->readformat; 00908 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00909 if (res < 0) { 00910 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00911 return -1; 00912 } 00913 sildet = ast_dsp_new(); 00914 if (!sildet) { 00915 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00916 return -1; 00917 } 00918 ast_dsp_set_threshold(sildet, 256); 00919 } 00920 00921 /* backward compatibility, if no offset given, arg[6] would have been 00922 * caught below and taken to be a beep, else if it is a digit then it is a 00923 * offset */ 00924 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00925 res = ast_streamfile(chan, "beep", chan->language); 00926 00927 if ((argc > 7) && (!strchr(argv[7], '='))) 00928 res = ast_streamfile(chan, "beep", chan->language); 00929 00930 if (!res) 00931 res = ast_waitstream(chan, argv[4]); 00932 if (res) { 00933 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00934 } else { 00935 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644); 00936 if (!fs) { 00937 res = -1; 00938 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 00939 if (sildet) 00940 ast_dsp_free(sildet); 00941 return RESULT_FAILURE; 00942 } 00943 00944 chan->stream = fs; 00945 ast_applystream(chan,fs); 00946 /* really should have checks */ 00947 ast_seekstream(fs, sample_offset, SEEK_SET); 00948 ast_truncstream(fs); 00949 00950 start = ast_tvnow(); 00951 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 00952 res = ast_waitfor(chan, -1); 00953 if (res < 0) { 00954 ast_closestream(fs); 00955 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 00956 if (sildet) 00957 ast_dsp_free(sildet); 00958 return RESULT_FAILURE; 00959 } 00960 f = ast_read(chan); 00961 if (!f) { 00962 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset); 00963 ast_closestream(fs); 00964 if (sildet) 00965 ast_dsp_free(sildet); 00966 return RESULT_FAILURE; 00967 } 00968 switch(f->frametype) { 00969 case AST_FRAME_DTMF: 00970 if (strchr(argv[4], f->subclass)) { 00971 /* This is an interrupting chracter, so rewind to chop off any small 00972 amount of DTMF that may have been recorded 00973 */ 00974 ast_stream_rewind(fs, 200); 00975 ast_truncstream(fs); 00976 sample_offset = ast_tellstream(fs); 00977 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 00978 ast_closestream(fs); 00979 ast_frfree(f); 00980 if (sildet) 00981 ast_dsp_free(sildet); 00982 return RESULT_SUCCESS; 00983 } 00984 break; 00985 case AST_FRAME_VOICE: 00986 ast_writestream(fs, f); 00987 /* this is a safe place to check progress since we know that fs 00988 * is valid after a write, and it will then have our current 00989 * location */ 00990 sample_offset = ast_tellstream(fs); 00991 if (silence > 0) { 00992 dspsilence = 0; 00993 ast_dsp_silence(sildet, f, &dspsilence); 00994 if (dspsilence) { 00995 totalsilence = dspsilence; 00996 } else { 00997 totalsilence = 0; 00998 } 00999 if (totalsilence > silence) { 01000 /* Ended happily with silence */ 01001 ast_frfree(f); 01002 gotsilence = 1; 01003 break; 01004 } 01005 } 01006 break; 01007 } 01008 ast_frfree(f); 01009 if (gotsilence) 01010 break; 01011 } 01012 01013 if (gotsilence) { 01014 ast_stream_rewind(fs, silence-1000); 01015 ast_truncstream(fs); 01016 sample_offset = ast_tellstream(fs); 01017 } 01018 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01019 ast_closestream(fs); 01020 } 01021 01022 if (silence > 0) { 01023 res = ast_set_read_format(chan, rfmt); 01024 if (res) 01025 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01026 ast_dsp_free(sildet); 01027 } 01028 return RESULT_SUCCESS; 01029 }
|
|
Definition at line 413 of file res_agi.c. References ast_recvchar(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 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 ast_recvtext(), ast_hostent::buf, agi_state::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 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 690 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. 00691 { 00692 int res; 00693 00694 if (argc != 4) 00695 return RESULT_SHOWUSAGE; 00696 00697 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00698 if (res == 1) /* New command */ 00699 return RESULT_SUCCESS; 00700 fdprintf(agi->fd, "200 result=%d\n", res); 00701 if (res >= 0) 00702 return RESULT_SUCCESS; 00703 else 00704 return RESULT_FAILURE; 00705 }
|
|
Definition at line 707 of file res_agi.c. References ast_say_date(), agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00708 { 00709 int res; 00710 int num; 00711 if (argc != 4) 00712 return RESULT_SHOWUSAGE; 00713 if (sscanf(argv[2], "%d", &num) != 1) 00714 return RESULT_SHOWUSAGE; 00715 res = ast_say_date(chan, num, argv[3], chan->language); 00716 if (res == 1) 00717 return RESULT_SUCCESS; 00718 fdprintf(agi->fd, "200 result=%d\n", res); 00719 if (res >= 0) 00720 return RESULT_SUCCESS; 00721 else 00722 return RESULT_FAILURE; 00723 }
|
|
Definition at line 743 of file res_agi.c. References ast_say_date_with_format(), ast_strlen_zero(), agi_state::fd, fdprintf, format, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00744 { 00745 int res=0; 00746 long unixtime; 00747 char *format, *zone=NULL; 00748 00749 if (argc < 4) 00750 return RESULT_SHOWUSAGE; 00751 00752 if (argc > 4) { 00753 format = argv[4]; 00754 } else { 00755 if (!strcasecmp(chan->language, "de")) { 00756 format = "A dBY HMS"; 00757 } else { 00758 format = "ABdY 'digits/at' IMp"; 00759 } 00760 } 00761 00762 if (argc > 5 && !ast_strlen_zero(argv[5])) 00763 zone = argv[5]; 00764 00765 if (sscanf(argv[2], "%ld", &unixtime) != 1) 00766 return RESULT_SHOWUSAGE; 00767 00768 res = ast_say_date_with_format(chan, (time_t) unixtime, argv[3], chan->language, format, zone); 00769 if (res == 1) 00770 return RESULT_SUCCESS; 00771 00772 fdprintf(agi->fd, "200 result=%d\n", res); 00773 00774 if (res >= 0) 00775 return RESULT_SUCCESS; 00776 else 00777 return RESULT_FAILURE; 00778 }
|
|
Definition at line 670 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. 00671 { 00672 int res; 00673 int num; 00674 00675 if (argc != 4) 00676 return RESULT_SHOWUSAGE; 00677 if (sscanf(argv[2], "%d", &num) != 1) 00678 return RESULT_SHOWUSAGE; 00679 00680 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00681 if (res == 1) /* New command */ 00682 return RESULT_SUCCESS; 00683 fdprintf(agi->fd, "200 result=%d\n", res); 00684 if (res >= 0) 00685 return RESULT_SUCCESS; 00686 else 00687 return RESULT_FAILURE; 00688 }
|
|
Definition at line 652 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. 00653 { 00654 int res; 00655 int num; 00656 if (argc != 4) 00657 return RESULT_SHOWUSAGE; 00658 if (sscanf(argv[2], "%d", &num) != 1) 00659 return RESULT_SHOWUSAGE; 00660 res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl); 00661 if (res == 1) 00662 return RESULT_SUCCESS; 00663 fdprintf(agi->fd, "200 result=%d\n", res); 00664 if (res >= 0) 00665 return RESULT_SUCCESS; 00666 else 00667 return RESULT_FAILURE; 00668 }
|
|
Definition at line 780 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. 00781 { 00782 int res; 00783 00784 if (argc != 4) 00785 return RESULT_SHOWUSAGE; 00786 00787 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00788 if (res == 1) /* New command */ 00789 return RESULT_SUCCESS; 00790 fdprintf(agi->fd, "200 result=%d\n", res); 00791 if (res >= 0) 00792 return RESULT_SUCCESS; 00793 else 00794 return RESULT_FAILURE; 00795 }
|
|
Definition at line 725 of file res_agi.c. References ast_say_time(), agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00726 { 00727 int res; 00728 int num; 00729 if (argc != 4) 00730 return RESULT_SHOWUSAGE; 00731 if (sscanf(argv[2], "%d", &num) != 1) 00732 return RESULT_SHOWUSAGE; 00733 res = ast_say_time(chan, num, argv[3], chan->language); 00734 if (res == 1) 00735 return RESULT_SUCCESS; 00736 fdprintf(agi->fd, "200 result=%d\n", res); 00737 if (res >= 0) 00738 return RESULT_SUCCESS; 00739 else 00740 return RESULT_FAILURE; 00741 }
|
|
Definition at line 470 of file res_agi.c. References ast_check_hangup(), ast_send_image(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 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 ast_sendtext(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 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 1099 of file res_agi.c. References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, fdprintf, n, and RESULT_SUCCESS. 01100 { 01101 char tmp[256]=""; 01102 char *l = NULL, *n = NULL; 01103 01104 if (argv[2]) { 01105 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01106 ast_callerid_parse(tmp, &n, &l); 01107 if (l) 01108 ast_shrink_phone_number(l); 01109 else 01110 l = ""; 01111 if (!n) 01112 n = ""; 01113 ast_set_callerid(chan, l, n, NULL); 01114 } 01115 01116 fdprintf(agi->fd, "200 result=1\n"); 01117 return RESULT_SUCCESS; 01118 }
|
|
Definition at line 826 of file res_agi.c. References ast_channel::context, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00827 { 00828 00829 if (argc != 3) 00830 return RESULT_SHOWUSAGE; 00831 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00832 fdprintf(agi->fd, "200 result=0\n"); 00833 return RESULT_SUCCESS; 00834 }
|
|
Definition at line 836 of file res_agi.c. References ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00837 { 00838 if (argc != 3) 00839 return RESULT_SHOWUSAGE; 00840 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00841 fdprintf(agi->fd, "200 result=0\n"); 00842 return RESULT_SUCCESS; 00843 }
|
|
Definition at line 1334 of file res_agi.c. References ast_moh_start(), ast_moh_stop(), agi_state::fd, fdprintf, and RESULT_SUCCESS. 01335 { 01336 if (!strncasecmp(argv[2],"on",2)) { 01337 if (argc > 3) 01338 ast_moh_start(chan, argv[3]); 01339 else 01340 ast_moh_start(chan, NULL); 01341 } 01342 if (!strncasecmp(argv[2],"off",3)) { 01343 ast_moh_stop(chan); 01344 } 01345 fdprintf(agi->fd, "200 result=0\n"); 01346 return RESULT_SUCCESS; 01347 }
|
|
Definition at line 845 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. 00846 { 00847 int pri; 00848 if (argc != 3) 00849 return RESULT_SHOWUSAGE; 00850 00851 if (sscanf(argv[2], "%d", &pri) != 1) { 00852 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00853 return RESULT_SHOWUSAGE; 00854 } 00855 00856 ast_explicit_goto(chan, NULL, NULL, pri); 00857 fdprintf(agi->fd, "200 result=0\n"); 00858 return RESULT_SUCCESS; 00859 }
|
|
Definition at line 1143 of file res_agi.c. References agi_state::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS. 01144 { 01145 if (argv[3]) 01146 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01147 01148 fdprintf(agi->fd, "200 result=1\n"); 01149 return RESULT_SUCCESS; 01150 }
|
|
Definition at line 1925 of file res_agi.c. References ast_cli(), find_command(), help_workhorse(), join(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage. 01925 { 01926 struct agi_command *e; 01927 char fullcmd[80]; 01928 if ((argc < 2)) 01929 return RESULT_SHOWUSAGE; 01930 if (argc > 2) { 01931 e = find_command(argv + 2, 1); 01932 if (e) 01933 ast_cli(fd, e->usage); 01934 else { 01935 if (find_command(argv + 2, -1)) { 01936 return help_workhorse(fd, argv + 1); 01937 } else { 01938 join(fullcmd, sizeof(fullcmd), argv+1); 01939 ast_cli(fd, "No such command '%s'.\n", fullcmd); 01940 } 01941 } 01942 } else { 01943 return help_workhorse(fd, NULL); 01944 } 01945 return RESULT_SUCCESS; 01946 }
|
|
Definition at line 530 of file res_agi.c. References ast_applystream(), ast_openstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_waitstream_full(), agi_state::audio, agi_state::ctrl, agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::stream. 00531 { 00532 int res; 00533 struct ast_filestream *fs; 00534 long sample_offset = 0; 00535 long max_length; 00536 00537 if (argc < 4) 00538 return RESULT_SHOWUSAGE; 00539 if (argc > 5) 00540 return RESULT_SHOWUSAGE; 00541 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00542 return RESULT_SHOWUSAGE; 00543 00544 fs = ast_openstream(chan, argv[2], chan->language); 00545 if (!fs){ 00546 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00547 return RESULT_SUCCESS; 00548 } 00549 ast_seekstream(fs, 0, SEEK_END); 00550 max_length = ast_tellstream(fs); 00551 ast_seekstream(fs, sample_offset, SEEK_SET); 00552 res = ast_applystream(chan, fs); 00553 res = ast_playstream(fs); 00554 if (res) { 00555 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00556 if (res >= 0) 00557 return RESULT_SHOWUSAGE; 00558 else 00559 return RESULT_FAILURE; 00560 } 00561 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00562 /* this is to check for if ast_waitstream closed the stream, we probably are at 00563 * the end of the stream, return that amount, else check for the amount */ 00564 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00565 ast_stopstream(chan); 00566 if (res == 1) { 00567 /* Stop this command, don't print a result line, as there is a new command */ 00568 return RESULT_SUCCESS; 00569 } 00570 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00571 if (res >= 0) 00572 return RESULT_SUCCESS; 00573 else 00574 return RESULT_FAILURE; 00575 }
|
|
Definition at line 449 of file res_agi.c. References ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 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 1198 of file res_agi.c. References ast_verbose(), ast_channel::data, agi_state::fd, fdprintf, option_verbose, RESULT_SHOWUSAGE, RESULT_SUCCESS, VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4. 01199 { 01200 int level = 0; 01201 char *prefix; 01202 01203 if (argc < 2) 01204 return RESULT_SHOWUSAGE; 01205 01206 if (argv[2]) 01207 sscanf(argv[2], "%d", &level); 01208 01209 switch (level) { 01210 case 4: 01211 prefix = VERBOSE_PREFIX_4; 01212 break; 01213 case 3: 01214 prefix = VERBOSE_PREFIX_3; 01215 break; 01216 case 2: 01217 prefix = VERBOSE_PREFIX_2; 01218 break; 01219 case 1: 01220 default: 01221 prefix = VERBOSE_PREFIX_1; 01222 break; 01223 } 01224 01225 if (level <= option_verbose) 01226 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01227 01228 fdprintf(agi->fd, "200 result=1\n"); 01229 01230 return RESULT_SUCCESS; 01231 }
|
|
Definition at line 377 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. 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 1652 of file res_agi.c. References agi_command::cmda, commands, and join(). 01653 { 01654 char fullcmd[80]; 01655 char matchstr[80]; 01656 int x; 01657 struct agi_command *e; 01658 if (match) 01659 join(matchstr, sizeof(matchstr), match); 01660 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01661 if (!commands[x].cmda[0]) break; 01662 e = &commands[x]; 01663 if (e) 01664 join(fullcmd, sizeof(fullcmd), e->cmda); 01665 /* Hide commands that start with '_' */ 01666 if (fullcmd[0] == '_') 01667 continue; 01668 if (match) { 01669 if (strncasecmp(matchstr, fullcmd, strlen(matchstr))) { 01670 continue; 01671 } 01672 } 01673 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01674 } 01675 return 0; 01676 }
|
|
Definition at line 1636 of file res_agi.c. 01637 { 01638 int x; 01639 01640 /* Join words into a string */ 01641 if (!s) { 01642 return; 01643 } 01644 s[0] = '\0'; 01645 for (x=0; w[x]; x++) { 01646 if (x) 01647 strncat(s, " ", len - strlen(s) - 1); 01648 strncat(s, w[x], len - strlen(s) - 1); 01649 } 01650 }
|
|
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 2138 of file res_agi.c. References ASTERISK_GPL_KEY. 02139 { 02140 return ASTERISK_GPL_KEY; 02141 }
|
|
Definition at line 132 of file res_agi.c. References AGI_PORT, ahp, ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), pollfd::events, pollfd::fd, fdprintf, host, hp, LOG_DEBUG, LOG_WARNING, MAX_AGI_CONNECT, option_debug, poll(), POLLOUT, 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 2115 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. 02116 { 02117 ast_cli_register(&showagi); 02118 ast_cli_register(&dumpagihtml); 02119 ast_cli_register(&cli_debug); 02120 ast_cli_register(&cli_no_debug); 02121 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02122 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02123 return ast_register_application(app, agi_exec, synopsis, descrip); 02124 }
|
|
Definition at line 1741 of file res_agi.c. References ast_log(), LOG_WARNING, and MAX_ARGS. 01742 { 01743 int x=0; 01744 int quoted=0; 01745 int escaped=0; 01746 int whitespace=1; 01747 char *cur; 01748 01749 cur = s; 01750 while(*s) { 01751 switch(*s) { 01752 case '"': 01753 /* If it's escaped, put a literal quote */ 01754 if (escaped) 01755 goto normal; 01756 else 01757 quoted = !quoted; 01758 if (quoted && whitespace) { 01759 /* If we're starting a quote, coming off white space start a new word, too */ 01760 argv[x++] = cur; 01761 whitespace=0; 01762 } 01763 escaped = 0; 01764 break; 01765 case ' ': 01766 case '\t': 01767 if (!quoted && !escaped) { 01768 /* If we're not quoted, mark this as whitespace, and 01769 end the previous argument */ 01770 whitespace = 1; 01771 *(cur++) = '\0'; 01772 } else 01773 /* Otherwise, just treat it as anything else */ 01774 goto normal; 01775 break; 01776 case '\\': 01777 /* If we're escaped, print a literal, otherwise enable escaping */ 01778 if (escaped) { 01779 goto normal; 01780 } else { 01781 escaped=1; 01782 } 01783 break; 01784 default: 01785 normal: 01786 if (whitespace) { 01787 if (x >= MAX_ARGS -1) { 01788 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01789 break; 01790 } 01791 /* Coming off of whitespace, start the next argument */ 01792 argv[x++] = cur; 01793 whitespace=0; 01794 } 01795 *(cur++) = *s; 01796 escaped=0; 01797 } 01798 s++; 01799 } 01800 /* Null terminate */ 01801 *(cur++) = '\0'; 01802 argv[x] = NULL; 01803 *max = x; 01804 return 0; 01805 }
|
|
Definition at line 1845 of file res_agi.c. References agi_handle_command(), agidebug, AST_FRAME_VOICE, ast_frfree(), ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_verbose(), ast_waitfor_nandfds(), agi_state::audio, agi_state::ctrl, ast_frame::data, ast_frame::datalen, agi_state::fd, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_verbose, RETRY, setup_env(), and VERBOSE_PREFIX_3. Referenced by agi_exec_full(). 01846 { 01847 struct ast_channel *c; 01848 int outfd; 01849 int ms; 01850 int returnstatus = 0; 01851 struct ast_frame *f; 01852 char buf[2048]; 01853 FILE *readf; 01854 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01855 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01856 int retry = RETRY; 01857 01858 if (!(readf = fdopen(agi->ctrl, "r"))) { 01859 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01860 if (pid > -1) 01861 kill(pid, SIGHUP); 01862 close(agi->ctrl); 01863 return -1; 01864 } 01865 setlinebuf(readf); 01866 setup_env(chan, request, agi->fd, (agi->audio > -1)); 01867 for (;;) { 01868 ms = -1; 01869 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01870 if (c) { 01871 retry = RETRY; 01872 /* Idle the channel until we get a command */ 01873 f = ast_read(c); 01874 if (!f) { 01875 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01876 returnstatus = -1; 01877 break; 01878 } else { 01879 /* If it's voice, write it to the audio pipe */ 01880 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01881 /* Write, ignoring errors */ 01882 write(agi->audio, f->data, f->datalen); 01883 } 01884 ast_frfree(f); 01885 } 01886 } else if (outfd > -1) { 01887 retry = RETRY; 01888 if (!fgets(buf, sizeof(buf), readf)) { 01889 /* Program terminated */ 01890 if (returnstatus) 01891 returnstatus = -1; 01892 if (option_verbose > 2) 01893 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01894 /* No need to kill the pid anymore, since they closed us */ 01895 pid = -1; 01896 break; 01897 } 01898 /* get rid of trailing newline, if any */ 01899 if (*buf && buf[strlen(buf) - 1] == '\n') 01900 buf[strlen(buf) - 1] = 0; 01901 if (agidebug) 01902 ast_verbose("AGI Rx << %s\n", buf); 01903 returnstatus |= agi_handle_command(chan, agi, buf); 01904 /* If the handle_command returns -1, we need to stop */ 01905 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01906 break; 01907 } 01908 } else { 01909 if (--retry <= 0) { 01910 ast_log(LOG_WARNING, "No channel, no fd?\n"); 01911 returnstatus = -1; 01912 break; 01913 } 01914 } 01915 } 01916 /* Notify process */ 01917 if (pid > -1) { 01918 if (kill(pid, SIGHUP)) 01919 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 01920 } 01921 fclose(readf); 01922 return returnstatus; 01923 }
|
|
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 2103 of file res_agi.c. References app, ast_cli_unregister(), ast_unregister_application(), cli_debug, cli_no_debug, deadapp, dumpagihtml, eapp, showagi, and STANDARD_HANGUP_LOCALUSERS. 02104 { 02105 STANDARD_HANGUP_LOCALUSERS; 02106 ast_cli_unregister(&showagi); 02107 ast_cli_unregister(&dumpagihtml); 02108 ast_cli_unregister(&cli_debug); 02109 ast_cli_unregister(&cli_no_debug); 02110 ast_unregister_application(eapp); 02111 ast_unregister_application(deadapp); 02112 return ast_unregister_application(app); 02113 }
|
|
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 2131 of file res_agi.c. References STANDARD_USECOUNT. 02132 { 02133 int res; 02134 STANDARD_USECOUNT(res); 02135 return res; 02136 }
|
|
Definition at line 97 of file res_agi.c. Referenced by run_agi(). |
|
|
|
Initial value: { { "agi", "debug", NULL }, agi_do_debug, "Enable AGI debugging", debug_usage } |
|
Initial value: { { "agi", "no", "debug", NULL }, agi_no_debug, "Disable AGI debugging", no_debug_usage } |
|
Definition at line 1596 of file res_agi.c. Referenced by agi_register(), agi_unregister(), dundi_showframe(), 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" |
|
|
|
Initial value: { { "dump", "agihtml", NULL }, handle_dumpagihtml, "Dumps a list of agi command in html format", dumpagihtml_help } Definition at line 2100 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 2097 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" |
|
|
|
|
|
|
|
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" |
|
|