#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 | |
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 1857 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 1322 of file res_agi.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01323 { 01324 if (argc != 2) 01325 return RESULT_SHOWUSAGE; 01326 agidebug = 1; 01327 ast_cli(fd, "AGI Debugging Enabled\n"); 01328 return RESULT_SUCCESS; 01329 }
|
|
Definition at line 2067 of file res_agi.c. References ast_channel::_softhangup, agi_exec_full(), ast_log(), localuser::chan, and LOG_WARNING. Referenced by load_module(). 02068 { 02069 if (chan->_softhangup) 02070 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02071 return agi_exec_full(chan, data, 0, 0); 02072 }
|
|
Definition at line 2017 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(). 02018 { 02019 int res=0; 02020 struct localuser *u; 02021 char *argv[MAX_ARGS]; 02022 char buf[2048]=""; 02023 char *tmp = (char *)buf; 02024 int argc = 0; 02025 int fds[2]; 02026 int efd = -1; 02027 int pid; 02028 char *stringp; 02029 AGI agi; 02030 02031 if (ast_strlen_zero(data)) { 02032 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02033 return -1; 02034 } 02035 ast_copy_string(buf, data, sizeof(buf)); 02036 02037 memset(&agi, 0, sizeof(agi)); 02038 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS - 1) 02039 argv[argc++] = stringp; 02040 argv[argc] = NULL; 02041 02042 LOCAL_USER_ADD(u); 02043 #if 0 02044 /* Answer if need be */ 02045 if (chan->_state != AST_STATE_UP) { 02046 if (ast_answer(chan)) { 02047 LOCAL_USER_REMOVE(u); 02048 return -1; 02049 } 02050 } 02051 #endif 02052 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); 02053 if (!res) { 02054 agi.fd = fds[1]; 02055 agi.ctrl = fds[0]; 02056 agi.audio = efd; 02057 res = run_agi(chan, argv[0], &agi, pid, dead); 02058 if (fds[1] != fds[0]) 02059 close(fds[1]); 02060 if (efd > -1) 02061 close(efd); 02062 } 02063 LOCAL_USER_REMOVE(u); 02064 return res; 02065 }
|
|
Definition at line 1825 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(). 01826 { 01827 char *argv[MAX_ARGS]; 01828 int argc = 0; 01829 int res; 01830 agi_command *c; 01831 argc = MAX_ARGS; 01832 01833 parse_args(buf, &argc, argv); 01834 c = find_command(argv, 0); 01835 if (c) { 01836 res = c->handler(chan, agi, argc, argv); 01837 switch(res) { 01838 case RESULT_SHOWUSAGE: 01839 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01840 fdprintf(agi->fd, c->usage); 01841 fdprintf(agi->fd, "520 End of proper usage.\n"); 01842 break; 01843 case AST_PBX_KEEPALIVE: 01844 /* We've been asked to keep alive, so do so */ 01845 return AST_PBX_KEEPALIVE; 01846 break; 01847 case RESULT_FAILURE: 01848 /* They've already given the failure. We've been hung up on so handle this 01849 appropriately */ 01850 return -1; 01851 } 01852 } else { 01853 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01854 } 01855 return 0; 01856 }
|
|
Definition at line 1331 of file res_agi.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01332 { 01333 if (argc != 3) 01334 return RESULT_SHOWUSAGE; 01335 agidebug = 0; 01336 ast_cli(fd, "AGI Debugging Disabled\n"); 01337 return RESULT_SUCCESS; 01338 }
|
|
Definition at line 1696 of file res_agi.c. References ast_log(), agi_command::cmda, commands, LOG_WARNING, and MAX_COMMANDS. 01697 { 01698 int x; 01699 for (x=0; x<MAX_COMMANDS - 1; x++) { 01700 if (commands[x].cmda[0] == agi->cmda[0]) { 01701 ast_log(LOG_WARNING, "Command already registered!\n"); 01702 return -1; 01703 } 01704 } 01705 for (x=0; x<MAX_COMMANDS - 1; x++) { 01706 if (!commands[x].cmda[0]) { 01707 commands[x] = *agi; 01708 return 0; 01709 } 01710 } 01711 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01712 return -1; 01713 }
|
|
Definition at line 1715 of file res_agi.c. References agi_command::cmda, commands, and MAX_COMMANDS. 01716 { 01717 int x; 01718 for (x=0; x<MAX_COMMANDS - 1; x++) { 01719 if (commands[x].cmda[0] == agi->cmda[0]) { 01720 memset(&commands[x], 0, sizeof(agi_command)); 01721 } 01722 } 01723 }
|
|
Definition at line 2095 of file res_agi.c. References agi_exec_full(), and localuser::chan. Referenced by load_module(). 02096 { 02097 return agi_exec_full(chan, data, 0, 1); 02098 }
|
|
Provides a description of the module.
Definition at line 2140 of file res_agi.c. References tdesc. 02141 { 02142 return tdesc; 02143 }
|
|
Definition at line 2074 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(). 02075 { 02076 int readformat; 02077 int res; 02078 02079 if (chan->_softhangup) 02080 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02081 readformat = chan->readformat; 02082 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02083 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02084 return -1; 02085 } 02086 res = agi_exec_full(chan, data, 1, 0); 02087 if (!res) { 02088 if (ast_set_read_format(chan, readformat)) { 02089 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02090 } 02091 } 02092 return res; 02093 }
|
|
Definition at line 1725 of file res_agi.c. References agi_command::cmda, commands, and match(). 01726 { 01727 int x; 01728 int y; 01729 int match; 01730 01731 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01732 if (!commands[x].cmda[0]) 01733 break; 01734 /* start optimistic */ 01735 match = 1; 01736 for (y=0; match && cmds[y]; y++) { 01737 /* If there are no more words in the command (and we're looking for 01738 an exact match) or there is a difference between the two words, 01739 then this is not a match */ 01740 if (!commands[x].cmda[y] && !exact) 01741 break; 01742 /* don't segfault if the next part of a command doesn't exist */ 01743 if (!commands[x].cmda[y]) 01744 return NULL; 01745 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01746 match = 0; 01747 } 01748 /* If more words are needed to complete the command then this is not 01749 a candidate (unless we're looking for a really inexact answer */ 01750 if ((exact > -1) && commands[x].cmda[y]) 01751 match = 0; 01752 if (match) 01753 return &commands[x]; 01754 } 01755 return NULL; 01756 }
|
|
Definition at line 367 of file res_agi.c. References ast_channel::_state, ast_answer(), AST_STATE_UP, agi_state::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS. 00368 { 00369 int res; 00370 res = 0; 00371 if (chan->_state != AST_STATE_UP) { 00372 /* Answer the chan */ 00373 res = ast_answer(chan); 00374 } 00375 fdprintf(agi->fd, "200 result=%d\n", res); 00376 if (res >= 0) 00377 return RESULT_SUCCESS; 00378 else 00379 return RESULT_FAILURE; 00380 }
|
|
Definition at line 1049 of file res_agi.c. References agi_state::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::whentohangup. 01050 { 01051 int timeout; 01052 01053 if (argc != 3) 01054 return RESULT_SHOWUSAGE; 01055 if (sscanf(argv[2], "%d", &timeout) != 1) 01056 return RESULT_SHOWUSAGE; 01057 if (timeout < 0) 01058 timeout = 0; 01059 if (timeout) 01060 chan->whentohangup = time(NULL) + timeout; 01061 else 01062 chan->whentohangup = 0; 01063 fdprintf(agi->fd, "200 result=0\n"); 01064 return RESULT_SUCCESS; 01065 }
|
|
Definition at line 1138 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. 01139 { 01140 struct ast_channel *c; 01141 if (argc == 2) { 01142 /* no argument: supply info on the current channel */ 01143 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01144 return RESULT_SUCCESS; 01145 } else if (argc == 3) { 01146 /* one argument: look for info on the specified channel */ 01147 c = ast_get_channel_by_name_locked(argv[2]); 01148 if (c) { 01149 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01150 ast_mutex_unlock(&c->lock); 01151 return RESULT_SUCCESS; 01152 } 01153 /* if we get this far no channel name matched the argument given */ 01154 fdprintf(agi->fd, "200 result=-1\n"); 01155 return RESULT_SUCCESS; 01156 } else { 01157 return RESULT_SHOWUSAGE; 01158 } 01159 }
|
|
Definition at line 490 of file res_agi.c. References ast_control_streamfile(), ast_strlen_zero(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and skipms. 00491 { 00492 int res = 0; 00493 int skipms = 3000; 00494 char *fwd = NULL; 00495 char *rev = NULL; 00496 char *pause = NULL; 00497 char *stop = NULL; 00498 00499 if (argc < 5 || argc > 9) 00500 return RESULT_SHOWUSAGE; 00501 00502 if (!ast_strlen_zero(argv[4])) 00503 stop = argv[4]; 00504 else 00505 stop = NULL; 00506 00507 if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) 00508 return RESULT_SHOWUSAGE; 00509 00510 if (argc > 6 && !ast_strlen_zero(argv[8])) 00511 fwd = argv[6]; 00512 else 00513 fwd = "#"; 00514 00515 if (argc > 7 && !ast_strlen_zero(argv[8])) 00516 rev = argv[7]; 00517 else 00518 rev = "*"; 00519 00520 if (argc > 8 && !ast_strlen_zero(argv[8])) 00521 pause = argv[8]; 00522 else 00523 pause = NULL; 00524 00525 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); 00526 00527 fdprintf(agi->fd, "200 result=%d\n", res); 00528 00529 if (res >= 0) 00530 return RESULT_SUCCESS; 00531 else 00532 return RESULT_FAILURE; 00533 }
|
|
Definition at line 1282 of file res_agi.c. References ast_db_del(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01283 { 01284 int res; 01285 01286 if (argc != 4) 01287 return RESULT_SHOWUSAGE; 01288 res = ast_db_del(argv[2], argv[3]); 01289 if (res) 01290 fdprintf(agi->fd, "200 result=0\n"); 01291 else 01292 fdprintf(agi->fd, "200 result=1\n"); 01293 01294 return RESULT_SUCCESS; 01295 }
|
|
Definition at line 1297 of file res_agi.c. References ast_db_deltree(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01298 { 01299 int res; 01300 if ((argc < 3) || (argc > 4)) 01301 return RESULT_SHOWUSAGE; 01302 if (argc == 4) 01303 res = ast_db_deltree(argv[2], argv[3]); 01304 else 01305 res = ast_db_deltree(argv[2], NULL); 01306 01307 if (res) 01308 fdprintf(agi->fd, "200 result=0\n"); 01309 else 01310 fdprintf(agi->fd, "200 result=1\n"); 01311 return RESULT_SUCCESS; 01312 }
|
|
Definition at line 1251 of file res_agi.c. References ast_db_get(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01252 { 01253 int res; 01254 char tmp[256]; 01255 01256 if (argc != 4) 01257 return RESULT_SHOWUSAGE; 01258 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01259 if (res) 01260 fdprintf(agi->fd, "200 result=0\n"); 01261 else 01262 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01263 01264 return RESULT_SUCCESS; 01265 }
|
|
Definition at line 1267 of file res_agi.c. References ast_db_put(), agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01268 { 01269 int res; 01270 01271 if (argc != 5) 01272 return RESULT_SHOWUSAGE; 01273 res = ast_db_put(argv[2], argv[3], argv[4]); 01274 if (res) 01275 fdprintf(agi->fd, "200 result=0\n"); 01276 else 01277 fdprintf(agi->fd, "200 result=1\n"); 01278 01279 return RESULT_SUCCESS; 01280 }
|
|
Definition at line 1961 of file res_agi.c. References ast_cli(), agi_command::cmda, commands, join(), RESULT_SHOWUSAGE, strsep(), agi_command::summary, and agi_command::usage. 01961 { 01962 struct agi_command *e; 01963 char fullcmd[80]; 01964 char *tempstr; 01965 int x; 01966 FILE *htmlfile; 01967 01968 if ((argc < 3)) 01969 return RESULT_SHOWUSAGE; 01970 01971 if (!(htmlfile = fopen(argv[2], "wt"))) { 01972 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 01973 return RESULT_SHOWUSAGE; 01974 } 01975 01976 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 01977 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 01978 01979 01980 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 01981 01982 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01983 char *stringp=NULL; 01984 if (!commands[x].cmda[0]) break; 01985 e = &commands[x]; 01986 if (e) 01987 join(fullcmd, sizeof(fullcmd), e->cmda); 01988 /* Hide commands that start with '_' */ 01989 if (fullcmd[0] == '_') 01990 continue; 01991 01992 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 01993 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TD></TR>\n", fullcmd,e->summary); 01994 01995 01996 stringp=e->usage; 01997 tempstr = strsep(&stringp, "\n"); 01998 01999 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 02000 02001 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 02002 while ((tempstr = strsep(&stringp, "\n")) != NULL) { 02003 fprintf(htmlfile, "%s<BR>\n",tempstr); 02004 02005 } 02006 fprintf(htmlfile, "</TD></TR>\n"); 02007 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 02008 02009 } 02010 02011 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 02012 fclose(htmlfile); 02013 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 02014 return RESULT_SUCCESS; 02015 }
|
|
Definition at line 1093 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. 01094 { 01095 int res; 01096 struct ast_app *app; 01097 01098 if (argc < 2) 01099 return RESULT_SHOWUSAGE; 01100 01101 if (option_verbose > 2) 01102 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01103 01104 app = pbx_findapp(argv[1]); 01105 01106 if (app) { 01107 res = pbx_exec(chan, app, argv[2], 1); 01108 } else { 01109 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01110 res = -2; 01111 } 01112 fdprintf(agi->fd, "200 result=%d\n", res); 01113 01114 return res; 01115 }
|
|
Definition at line 810 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. 00811 { 00812 int res; 00813 char data[1024]; 00814 int max; 00815 int timeout; 00816 00817 if (argc < 3) 00818 return RESULT_SHOWUSAGE; 00819 if (argc >= 4) 00820 timeout = atoi(argv[3]); 00821 else 00822 timeout = 0; 00823 if (argc >= 5) 00824 max = atoi(argv[4]); 00825 else 00826 max = 1024; 00827 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00828 if (res == 2) /* New command */ 00829 return RESULT_SUCCESS; 00830 else if (res == 1) 00831 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00832 else if (res < 0 ) 00833 fdprintf(agi->fd, "200 result=-1\n"); 00834 else 00835 fdprintf(agi->fd, "200 result=%s\n", data); 00836 return RESULT_SUCCESS; 00837 }
|
|
Definition at line 591 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. 00592 { 00593 int res; 00594 struct ast_filestream *fs; 00595 long sample_offset = 0; 00596 long max_length; 00597 int timeout = 0; 00598 char *edigits = NULL; 00599 00600 if ( argc < 4 || argc > 5 ) 00601 return RESULT_SHOWUSAGE; 00602 00603 if ( argv[3] ) 00604 edigits = argv[3]; 00605 00606 if ( argc == 5 ) 00607 timeout = atoi(argv[4]); 00608 else if (chan->pbx->dtimeout) { 00609 /* by default dtimeout is set to 5sec */ 00610 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00611 } 00612 00613 fs = ast_openstream(chan, argv[2], chan->language); 00614 if (!fs){ 00615 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00616 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00617 return RESULT_SUCCESS; 00618 } 00619 if (option_verbose > 2) 00620 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00621 00622 ast_seekstream(fs, 0, SEEK_END); 00623 max_length = ast_tellstream(fs); 00624 ast_seekstream(fs, sample_offset, SEEK_SET); 00625 res = ast_applystream(chan, fs); 00626 res = ast_playstream(fs); 00627 if (res) { 00628 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00629 if (res >= 0) 00630 return RESULT_SHOWUSAGE; 00631 else 00632 return RESULT_FAILURE; 00633 } 00634 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00635 /* this is to check for if ast_waitstream closed the stream, we probably are at 00636 * the end of the stream, return that amount, else check for the amount */ 00637 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00638 ast_stopstream(chan); 00639 if (res == 1) { 00640 /* Stop this command, don't print a result line, as there is a new command */ 00641 return RESULT_SUCCESS; 00642 } 00643 00644 /* If the user didnt press a key, wait for digitTimeout*/ 00645 if (res == 0 ) { 00646 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00647 /* Make sure the new result is in the escape digits of the GET OPTION */ 00648 if ( !strchr(edigits,res) ) 00649 res=0; 00650 } 00651 00652 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00653 if (res >= 0) 00654 return RESULT_SUCCESS; 00655 else 00656 return RESULT_FAILURE; 00657 }
|
|
Definition at line 1170 of file res_agi.c. References ast_func_read(), ast_strlen_zero(), agi_state::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01171 { 01172 char *ret; 01173 char tempstr[1024]; 01174 01175 if (argc != 3) 01176 return RESULT_SHOWUSAGE; 01177 01178 /* check if we want to execute an ast_custom_function */ 01179 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01180 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)); 01181 } else { 01182 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01183 } 01184 01185 if (ret) 01186 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01187 else 01188 fdprintf(agi->fd, "200 result=0\n"); 01189 01190 return RESULT_SUCCESS; 01191 }
|
|
Definition at line 1193 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. 01194 { 01195 char tmp[4096] = ""; 01196 struct ast_channel *chan2=NULL; 01197 01198 if ((argc != 4) && (argc != 5)) 01199 return RESULT_SHOWUSAGE; 01200 if (argc == 5) { 01201 chan2 = ast_get_channel_by_name_locked(argv[4]); 01202 } else { 01203 chan2 = chan; 01204 } 01205 if (chan) { /* XXX isn't this chan2 ? */ 01206 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01207 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01208 } else { 01209 fdprintf(agi->fd, "200 result=0\n"); 01210 } 01211 if (chan2 && (chan2 != chan)) 01212 ast_mutex_unlock(&chan2->lock); 01213 return RESULT_SUCCESS; 01214 }
|
|
Definition at line 1067 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. 01068 { 01069 struct ast_channel *c; 01070 if (argc == 1) { 01071 /* no argument: hangup the current channel */ 01072 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01073 fdprintf(agi->fd, "200 result=1\n"); 01074 return RESULT_SUCCESS; 01075 } else if (argc == 2) { 01076 /* one argument: look for info on the specified channel */ 01077 c = ast_get_channel_by_name_locked(argv[1]); 01078 if (c) { 01079 /* we have a matching channel */ 01080 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01081 fdprintf(agi->fd, "200 result=1\n"); 01082 ast_mutex_unlock(&c->lock); 01083 return RESULT_SUCCESS; 01084 } 01085 /* if we get this far no channel name matched the argument given */ 01086 fdprintf(agi->fd, "200 result=-1\n"); 01087 return RESULT_SUCCESS; 01088 } else { 01089 return RESULT_SHOWUSAGE; 01090 } 01091 }
|
|
Definition at line 1346 of file res_agi.c. References agi_state::fd, fdprintf, and RESULT_SUCCESS. 01347 { 01348 fdprintf(agi->fd, "200 result=0\n"); 01349 return RESULT_SUCCESS; 01350 }
|
|
Definition at line 874 of file res_agi.c. References ast_applystream(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), ast_seekstream(), ast_set_read_format(), ast_stream_rewind(), ast_streamfile(), ast_tellstream(), ast_truncstream(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), 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. 00875 { 00876 struct ast_filestream *fs; 00877 struct ast_frame *f; 00878 struct timeval start; 00879 long sample_offset = 0; 00880 int res = 0; 00881 int ms; 00882 00883 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00884 int totalsilence = 0; 00885 int dspsilence = 0; 00886 int silence = 0; /* amount of silence to allow */ 00887 int gotsilence = 0; /* did we timeout for silence? */ 00888 char *silencestr=NULL; 00889 int rfmt=0; 00890 00891 00892 /* XXX EAGI FIXME XXX */ 00893 00894 if (argc < 6) 00895 return RESULT_SHOWUSAGE; 00896 if (sscanf(argv[5], "%d", &ms) != 1) 00897 return RESULT_SHOWUSAGE; 00898 00899 if (argc > 6) 00900 silencestr = strchr(argv[6],'s'); 00901 if ((argc > 7) && (!silencestr)) 00902 silencestr = strchr(argv[7],'s'); 00903 if ((argc > 8) && (!silencestr)) 00904 silencestr = strchr(argv[8],'s'); 00905 00906 if (silencestr) { 00907 if (strlen(silencestr) > 2) { 00908 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00909 silencestr++; 00910 silencestr++; 00911 if (silencestr) 00912 silence = atoi(silencestr); 00913 if (silence > 0) 00914 silence *= 1000; 00915 } 00916 } 00917 } 00918 00919 if (silence > 0) { 00920 rfmt = chan->readformat; 00921 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00922 if (res < 0) { 00923 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00924 return -1; 00925 } 00926 sildet = ast_dsp_new(); 00927 if (!sildet) { 00928 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00929 return -1; 00930 } 00931 ast_dsp_set_threshold(sildet, 256); 00932 } 00933 00934 /* backward compatibility, if no offset given, arg[6] would have been 00935 * caught below and taken to be a beep, else if it is a digit then it is a 00936 * offset */ 00937 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00938 res = ast_streamfile(chan, "beep", chan->language); 00939 00940 if ((argc > 7) && (!strchr(argv[7], '='))) 00941 res = ast_streamfile(chan, "beep", chan->language); 00942 00943 if (!res) 00944 res = ast_waitstream(chan, argv[4]); 00945 if (res) { 00946 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00947 } else { 00948 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644); 00949 if (!fs) { 00950 res = -1; 00951 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 00952 if (sildet) 00953 ast_dsp_free(sildet); 00954 return RESULT_FAILURE; 00955 } 00956 00957 /* Request a video update */ 00958 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00959 00960 chan->stream = fs; 00961 ast_applystream(chan,fs); 00962 /* really should have checks */ 00963 ast_seekstream(fs, sample_offset, SEEK_SET); 00964 ast_truncstream(fs); 00965 00966 start = ast_tvnow(); 00967 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 00968 res = ast_waitfor(chan, -1); 00969 if (res < 0) { 00970 ast_closestream(fs); 00971 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 00972 if (sildet) 00973 ast_dsp_free(sildet); 00974 return RESULT_FAILURE; 00975 } 00976 f = ast_read(chan); 00977 if (!f) { 00978 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset); 00979 ast_closestream(fs); 00980 if (sildet) 00981 ast_dsp_free(sildet); 00982 return RESULT_FAILURE; 00983 } 00984 switch(f->frametype) { 00985 case AST_FRAME_DTMF: 00986 if (strchr(argv[4], f->subclass)) { 00987 /* This is an interrupting chracter, so rewind to chop off any small 00988 amount of DTMF that may have been recorded 00989 */ 00990 ast_stream_rewind(fs, 200); 00991 ast_truncstream(fs); 00992 sample_offset = ast_tellstream(fs); 00993 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 00994 ast_closestream(fs); 00995 ast_frfree(f); 00996 if (sildet) 00997 ast_dsp_free(sildet); 00998 return RESULT_SUCCESS; 00999 } 01000 break; 01001 case AST_FRAME_VOICE: 01002 ast_writestream(fs, f); 01003 /* this is a safe place to check progress since we know that fs 01004 * is valid after a write, and it will then have our current 01005 * location */ 01006 sample_offset = ast_tellstream(fs); 01007 if (silence > 0) { 01008 dspsilence = 0; 01009 ast_dsp_silence(sildet, f, &dspsilence); 01010 if (dspsilence) { 01011 totalsilence = dspsilence; 01012 } else { 01013 totalsilence = 0; 01014 } 01015 if (totalsilence > silence) { 01016 /* Ended happily with silence */ 01017 gotsilence = 1; 01018 break; 01019 } 01020 } 01021 break; 01022 case AST_FRAME_VIDEO: 01023 ast_writestream(fs, f); 01024 break; 01025 } 01026 ast_frfree(f); 01027 if (gotsilence) 01028 break; 01029 } 01030 01031 if (gotsilence) { 01032 ast_stream_rewind(fs, silence-1000); 01033 ast_truncstream(fs); 01034 sample_offset = ast_tellstream(fs); 01035 } 01036 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01037 ast_closestream(fs); 01038 } 01039 01040 if (silence > 0) { 01041 res = ast_set_read_format(chan, rfmt); 01042 if (res) 01043 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01044 ast_dsp_free(sildet); 01045 } 01046 return RESULT_SUCCESS; 01047 }
|
|
Definition at line 418 of file res_agi.c. References ast_recvchar(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00419 { 00420 int res; 00421 if (argc != 3) 00422 return RESULT_SHOWUSAGE; 00423 res = ast_recvchar(chan,atoi(argv[2])); 00424 if (res == 0) { 00425 fdprintf(agi->fd, "200 result=%d (timeout)\n", res); 00426 return RESULT_SUCCESS; 00427 } 00428 if (res > 0) { 00429 fdprintf(agi->fd, "200 result=%d\n", res); 00430 return RESULT_SUCCESS; 00431 } 00432 else { 00433 fdprintf(agi->fd, "200 result=%d (hangup)\n", res); 00434 return RESULT_FAILURE; 00435 } 00436 }
|
|
Definition at line 438 of file res_agi.c. References ast_recvtext(), ast_hostent::buf, agi_state::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00439 { 00440 char *buf; 00441 00442 if (argc != 3) 00443 return RESULT_SHOWUSAGE; 00444 buf = ast_recvtext(chan,atoi(argv[2])); 00445 if (buf) { 00446 fdprintf(agi->fd, "200 result=1 (%s)\n", buf); 00447 free(buf); 00448 } else { 00449 fdprintf(agi->fd, "200 result=-1\n"); 00450 } 00451 return RESULT_SUCCESS; 00452 }
|
|
Definition at line 703 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. 00704 { 00705 int res; 00706 00707 if (argc != 4) 00708 return RESULT_SHOWUSAGE; 00709 00710 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00711 if (res == 1) /* New command */ 00712 return RESULT_SUCCESS; 00713 fdprintf(agi->fd, "200 result=%d\n", res); 00714 if (res >= 0) 00715 return RESULT_SUCCESS; 00716 else 00717 return RESULT_FAILURE; 00718 }
|
|
Definition at line 720 of file res_agi.c. References ast_say_date(), agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00721 { 00722 int res; 00723 int num; 00724 if (argc != 4) 00725 return RESULT_SHOWUSAGE; 00726 if (sscanf(argv[2], "%d", &num) != 1) 00727 return RESULT_SHOWUSAGE; 00728 res = ast_say_date(chan, num, argv[3], chan->language); 00729 if (res == 1) 00730 return RESULT_SUCCESS; 00731 fdprintf(agi->fd, "200 result=%d\n", res); 00732 if (res >= 0) 00733 return RESULT_SUCCESS; 00734 else 00735 return RESULT_FAILURE; 00736 }
|
|
Definition at line 756 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. 00757 { 00758 int res=0; 00759 long unixtime; 00760 char *format, *zone=NULL; 00761 00762 if (argc < 4) 00763 return RESULT_SHOWUSAGE; 00764 00765 if (argc > 4) { 00766 format = argv[4]; 00767 } else { 00768 if (!strcasecmp(chan->language, "de")) { 00769 format = "A dBY HMS"; 00770 } else { 00771 format = "ABdY 'digits/at' IMp"; 00772 } 00773 } 00774 00775 if (argc > 5 && !ast_strlen_zero(argv[5])) 00776 zone = argv[5]; 00777 00778 if (sscanf(argv[2], "%ld", &unixtime) != 1) 00779 return RESULT_SHOWUSAGE; 00780 00781 res = ast_say_date_with_format(chan, (time_t) unixtime, argv[3], chan->language, format, zone); 00782 if (res == 1) 00783 return RESULT_SUCCESS; 00784 00785 fdprintf(agi->fd, "200 result=%d\n", res); 00786 00787 if (res >= 0) 00788 return RESULT_SUCCESS; 00789 else 00790 return RESULT_FAILURE; 00791 }
|
|
Definition at line 683 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. 00684 { 00685 int res; 00686 int num; 00687 00688 if (argc != 4) 00689 return RESULT_SHOWUSAGE; 00690 if (sscanf(argv[2], "%d", &num) != 1) 00691 return RESULT_SHOWUSAGE; 00692 00693 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00694 if (res == 1) /* New command */ 00695 return RESULT_SUCCESS; 00696 fdprintf(agi->fd, "200 result=%d\n", res); 00697 if (res >= 0) 00698 return RESULT_SUCCESS; 00699 else 00700 return RESULT_FAILURE; 00701 }
|
|
Definition at line 665 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. 00666 { 00667 int res; 00668 int num; 00669 if (argc != 4) 00670 return RESULT_SHOWUSAGE; 00671 if (sscanf(argv[2], "%d", &num) != 1) 00672 return RESULT_SHOWUSAGE; 00673 res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl); 00674 if (res == 1) 00675 return RESULT_SUCCESS; 00676 fdprintf(agi->fd, "200 result=%d\n", res); 00677 if (res >= 0) 00678 return RESULT_SUCCESS; 00679 else 00680 return RESULT_FAILURE; 00681 }
|
|
Definition at line 793 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. 00794 { 00795 int res; 00796 00797 if (argc != 4) 00798 return RESULT_SHOWUSAGE; 00799 00800 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00801 if (res == 1) /* New command */ 00802 return RESULT_SUCCESS; 00803 fdprintf(agi->fd, "200 result=%d\n", res); 00804 if (res >= 0) 00805 return RESULT_SUCCESS; 00806 else 00807 return RESULT_FAILURE; 00808 }
|
|
Definition at line 738 of file res_agi.c. References ast_say_time(), agi_state::fd, fdprintf, ast_channel::language, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00739 { 00740 int res; 00741 int num; 00742 if (argc != 4) 00743 return RESULT_SHOWUSAGE; 00744 if (sscanf(argv[2], "%d", &num) != 1) 00745 return RESULT_SHOWUSAGE; 00746 res = ast_say_time(chan, num, argv[3], chan->language); 00747 if (res == 1) 00748 return RESULT_SUCCESS; 00749 fdprintf(agi->fd, "200 result=%d\n", res); 00750 if (res >= 0) 00751 return RESULT_SUCCESS; 00752 else 00753 return RESULT_FAILURE; 00754 }
|
|
Definition at line 475 of file res_agi.c. References ast_check_hangup(), ast_send_image(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00476 { 00477 int res; 00478 if (argc != 3) 00479 return RESULT_SHOWUSAGE; 00480 res = ast_send_image(chan, argv[2]); 00481 if (!ast_check_hangup(chan)) 00482 res = 0; 00483 fdprintf(agi->fd, "200 result=%d\n", res); 00484 if (res >= 0) 00485 return RESULT_SUCCESS; 00486 else 00487 return RESULT_FAILURE; 00488 }
|
|
Definition at line 398 of file res_agi.c. References ast_sendtext(), agi_state::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00399 { 00400 int res; 00401 if (argc != 3) 00402 return RESULT_SHOWUSAGE; 00403 /* At the moment, the parser (perhaps broken) returns with 00404 the last argument PLUS the newline at the end of the input 00405 buffer. This probably needs to be fixed, but I wont do that 00406 because other stuff may break as a result. The right way 00407 would probably be to strip off the trailing newline before 00408 parsing, then here, add a newline at the end of the string 00409 before sending it to ast_sendtext --DUDE */ 00410 res = ast_sendtext(chan, argv[2]); 00411 fdprintf(agi->fd, "200 result=%d\n", res); 00412 if (res >= 0) 00413 return RESULT_SUCCESS; 00414 else 00415 return RESULT_FAILURE; 00416 }
|
|
Definition at line 1117 of file res_agi.c. References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), agi_state::fd, fdprintf, n, and RESULT_SUCCESS. 01118 { 01119 char tmp[256]=""; 01120 char *l = NULL, *n = NULL; 01121 01122 if (argv[2]) { 01123 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01124 ast_callerid_parse(tmp, &n, &l); 01125 if (l) 01126 ast_shrink_phone_number(l); 01127 else 01128 l = ""; 01129 if (!n) 01130 n = ""; 01131 ast_set_callerid(chan, l, n, NULL); 01132 } 01133 01134 fdprintf(agi->fd, "200 result=1\n"); 01135 return RESULT_SUCCESS; 01136 }
|
|
Definition at line 839 of file res_agi.c. References ast_channel::context, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00840 { 00841 00842 if (argc != 3) 00843 return RESULT_SHOWUSAGE; 00844 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00845 fdprintf(agi->fd, "200 result=0\n"); 00846 return RESULT_SUCCESS; 00847 }
|
|
Definition at line 849 of file res_agi.c. References ast_channel::exten, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00850 { 00851 if (argc != 3) 00852 return RESULT_SHOWUSAGE; 00853 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00854 fdprintf(agi->fd, "200 result=0\n"); 00855 return RESULT_SUCCESS; 00856 }
|
|
Definition at line 1352 of file res_agi.c. References ast_moh_start(), ast_moh_stop(), agi_state::fd, fdprintf, and RESULT_SUCCESS. 01353 { 01354 if (!strncasecmp(argv[2],"on",2)) { 01355 if (argc > 3) 01356 ast_moh_start(chan, argv[3]); 01357 else 01358 ast_moh_start(chan, NULL); 01359 } 01360 if (!strncasecmp(argv[2],"off",3)) { 01361 ast_moh_stop(chan); 01362 } 01363 fdprintf(agi->fd, "200 result=0\n"); 01364 return RESULT_SUCCESS; 01365 }
|
|
Definition at line 858 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. 00859 { 00860 int pri; 00861 if (argc != 3) 00862 return RESULT_SHOWUSAGE; 00863 00864 if (sscanf(argv[2], "%d", &pri) != 1) { 00865 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00866 return RESULT_SHOWUSAGE; 00867 } 00868 00869 ast_explicit_goto(chan, NULL, NULL, pri); 00870 fdprintf(agi->fd, "200 result=0\n"); 00871 return RESULT_SUCCESS; 00872 }
|
|
Definition at line 1161 of file res_agi.c. References agi_state::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS. 01162 { 01163 if (argv[3]) 01164 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01165 01166 fdprintf(agi->fd, "200 result=1\n"); 01167 return RESULT_SUCCESS; 01168 }
|
|
Definition at line 1938 of file res_agi.c. References ast_cli(), find_command(), help_workhorse(), join(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage. 01938 { 01939 struct agi_command *e; 01940 char fullcmd[80]; 01941 if ((argc < 2)) 01942 return RESULT_SHOWUSAGE; 01943 if (argc > 2) { 01944 e = find_command(argv + 2, 1); 01945 if (e) 01946 ast_cli(fd, e->usage); 01947 else { 01948 if (find_command(argv + 2, -1)) { 01949 return help_workhorse(fd, argv + 1); 01950 } else { 01951 join(fullcmd, sizeof(fullcmd), argv+1); 01952 ast_cli(fd, "No such command '%s'.\n", fullcmd); 01953 } 01954 } 01955 } else { 01956 return help_workhorse(fd, NULL); 01957 } 01958 return RESULT_SUCCESS; 01959 }
|
|
Definition at line 535 of file res_agi.c. References 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, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, and ast_filestream::vfs. 00536 { 00537 int res; 00538 int vres; 00539 struct ast_filestream *fs; 00540 struct ast_filestream *vfs; 00541 long sample_offset = 0; 00542 long max_length; 00543 00544 if (argc < 4) 00545 return RESULT_SHOWUSAGE; 00546 if (argc > 5) 00547 return RESULT_SHOWUSAGE; 00548 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00549 return RESULT_SHOWUSAGE; 00550 00551 fs = ast_openstream(chan, argv[2], chan->language); 00552 if (!fs){ 00553 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00554 return RESULT_SUCCESS; 00555 } 00556 vfs = ast_openvstream(chan, argv[2], chan->language); 00557 if (vfs) 00558 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00559 00560 ast_seekstream(fs, 0, SEEK_END); 00561 max_length = ast_tellstream(fs); 00562 ast_seekstream(fs, sample_offset, SEEK_SET); 00563 res = ast_applystream(chan, fs); 00564 if (vfs) vres = ast_applystream(chan, vfs); 00565 res = ast_playstream(fs); 00566 if (vfs) vres = ast_playstream(vfs); 00567 if (res) { 00568 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00569 if (res >= 0) 00570 return RESULT_SHOWUSAGE; 00571 else 00572 return RESULT_FAILURE; 00573 } 00574 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00575 /* this is to check for if ast_waitstream closed the stream, we probably are at 00576 * the end of the stream, return that amount, else check for the amount */ 00577 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00578 ast_stopstream(chan); 00579 if (res == 1) { 00580 /* Stop this command, don't print a result line, as there is a new command */ 00581 return RESULT_SUCCESS; 00582 } 00583 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00584 if (res >= 0) 00585 return RESULT_SUCCESS; 00586 else 00587 return RESULT_FAILURE; 00588 }
|
|
Definition at line 454 of file res_agi.c. References ast_channel_setoption(), AST_OPTION_TDD, agi_state::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00455 { 00456 int res,x; 00457 if (argc != 3) 00458 return RESULT_SHOWUSAGE; 00459 if (!strncasecmp(argv[2],"on",2)) 00460 x = 1; 00461 else 00462 x = 0; 00463 if (!strncasecmp(argv[2],"mate",4)) 00464 x = 2; 00465 if (!strncasecmp(argv[2],"tdd",3)) 00466 x = 1; 00467 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0); 00468 if (res != RESULT_SUCCESS) 00469 fdprintf(agi->fd, "200 result=0\n"); 00470 else 00471 fdprintf(agi->fd, "200 result=1\n"); 00472 return RESULT_SUCCESS; 00473 }
|
|
Definition at line 1216 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. 01217 { 01218 int level = 0; 01219 char *prefix; 01220 01221 if (argc < 2) 01222 return RESULT_SHOWUSAGE; 01223 01224 if (argv[2]) 01225 sscanf(argv[2], "%d", &level); 01226 01227 switch (level) { 01228 case 4: 01229 prefix = VERBOSE_PREFIX_4; 01230 break; 01231 case 3: 01232 prefix = VERBOSE_PREFIX_3; 01233 break; 01234 case 2: 01235 prefix = VERBOSE_PREFIX_2; 01236 break; 01237 case 1: 01238 default: 01239 prefix = VERBOSE_PREFIX_1; 01240 break; 01241 } 01242 01243 if (level <= option_verbose) 01244 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01245 01246 fdprintf(agi->fd, "200 result=1\n"); 01247 01248 return RESULT_SUCCESS; 01249 }
|
|
Definition at line 382 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. 00383 { 00384 int res; 00385 int to; 00386 if (argc != 4) 00387 return RESULT_SHOWUSAGE; 00388 if (sscanf(argv[3], "%d", &to) != 1) 00389 return RESULT_SHOWUSAGE; 00390 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); 00391 fdprintf(agi->fd, "200 result=%d\n", res); 00392 if (res >= 0) 00393 return RESULT_SUCCESS; 00394 else 00395 return RESULT_FAILURE; 00396 }
|
|
Definition at line 1670 of file res_agi.c. References agi_command::cmda, commands, and join(). 01671 { 01672 char fullcmd[80]; 01673 char matchstr[80]; 01674 int x; 01675 struct agi_command *e; 01676 if (match) 01677 join(matchstr, sizeof(matchstr), match); 01678 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01679 if (!commands[x].cmda[0]) break; 01680 e = &commands[x]; 01681 if (e) 01682 join(fullcmd, sizeof(fullcmd), e->cmda); 01683 /* Hide commands that start with '_' */ 01684 if (fullcmd[0] == '_') 01685 continue; 01686 if (match) { 01687 if (strncasecmp(matchstr, fullcmd, strlen(matchstr))) { 01688 continue; 01689 } 01690 } 01691 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01692 } 01693 return 0; 01694 }
|
|
Definition at line 1654 of file res_agi.c. 01655 { 01656 int x; 01657 01658 /* Join words into a string */ 01659 if (!s) { 01660 return; 01661 } 01662 s[0] = '\0'; 01663 for (x=0; w[x]; x++) { 01664 if (x) 01665 strncat(s, " ", len - strlen(s) - 1); 01666 strncat(s, w[x], len - strlen(s) - 1); 01667 } 01668 }
|
|
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 2152 of file res_agi.c. References ASTERISK_GPL_KEY. 02153 { 02154 return ASTERISK_GPL_KEY; 02155 }
|
|
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 int res; 00144 00145 host = ast_strdupa(agiurl + 6); /* Remove agi:// */ 00146 if (!host) 00147 return -1; 00148 /* Strip off any script name */ 00149 if ((c = strchr(host, '/'))) { 00150 *c = '\0'; 00151 c++; 00152 script = c; 00153 } 00154 if ((c = strchr(host, ':'))) { 00155 *c = '\0'; 00156 c++; 00157 port = atoi(c); 00158 } 00159 if (efd) { 00160 ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n"); 00161 return -1; 00162 } 00163 hp = ast_gethostbyname(host, &ahp); 00164 if (!hp) { 00165 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host); 00166 return -1; 00167 } 00168 s = socket(AF_INET, SOCK_STREAM, 0); 00169 if (s < 0) { 00170 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 00171 return -1; 00172 } 00173 flags = fcntl(s, F_GETFL); 00174 if (flags < 0) { 00175 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno)); 00176 close(s); 00177 return -1; 00178 } 00179 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { 00180 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno)); 00181 close(s); 00182 return -1; 00183 } 00184 memset(&sin, 0, sizeof(sin)); 00185 sin.sin_family = AF_INET; 00186 sin.sin_port = htons(port); 00187 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00188 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) { 00189 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno)); 00190 close(s); 00191 return -1; 00192 } 00193 00194 pfds[0].fd = s; 00195 pfds[0].events = POLLOUT; 00196 while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) { 00197 if (errno != EINTR) { 00198 if (!res) { 00199 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n", 00200 agiurl, MAX_AGI_CONNECT); 00201 } else 00202 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00203 close(s); 00204 return -1; 00205 } 00206 } 00207 00208 while (write(s, "agi_network: yes\n", strlen("agi_network: yes\n")) < 0) { 00209 if (errno != EINTR) { 00210 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00211 close(s); 00212 return -1; 00213 } 00214 } 00215 00216 /* If we have a script parameter, relay it to the fastagi server */ 00217 if (!ast_strlen_zero(script)) 00218 fdprintf(s, "agi_network_script: %s\n", script); 00219 00220 if (option_debug > 3) 00221 ast_log(LOG_DEBUG, "Wow, connected!\n"); 00222 fds[0] = s; 00223 fds[1] = s; 00224 *opid = -1; 00225 return 0; 00226 }
|
|
Definition at line 228 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(). 00229 { 00230 char tmp[256]; 00231 int pid; 00232 int toast[2]; 00233 int fromast[2]; 00234 int audio[2]; 00235 int x; 00236 int res; 00237 sigset_t signal_set; 00238 00239 if (!strncasecmp(script, "agi://", 6)) 00240 return launch_netscript(script, argv, fds, efd, opid); 00241 00242 if (script[0] != '/') { 00243 snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script); 00244 script = tmp; 00245 } 00246 if (pipe(toast)) { 00247 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno)); 00248 return -1; 00249 } 00250 if (pipe(fromast)) { 00251 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno)); 00252 close(toast[0]); 00253 close(toast[1]); 00254 return -1; 00255 } 00256 if (efd) { 00257 if (pipe(audio)) { 00258 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00259 close(fromast[0]); 00260 close(fromast[1]); 00261 close(toast[0]); 00262 close(toast[1]); 00263 return -1; 00264 } 00265 res = fcntl(audio[1], F_GETFL); 00266 if (res > -1) 00267 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK); 00268 if (res < 0) { 00269 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00270 close(fromast[0]); 00271 close(fromast[1]); 00272 close(toast[0]); 00273 close(toast[1]); 00274 close(audio[0]); 00275 close(audio[1]); 00276 return -1; 00277 } 00278 } 00279 pid = fork(); 00280 if (pid < 0) { 00281 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); 00282 return -1; 00283 } 00284 if (!pid) { 00285 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ 00286 ast_set_priority(0); 00287 00288 /* Redirect stdin and out, provide enhanced audio channel if desired */ 00289 dup2(fromast[0], STDIN_FILENO); 00290 dup2(toast[1], STDOUT_FILENO); 00291 if (efd) { 00292 dup2(audio[0], STDERR_FILENO + 1); 00293 } else { 00294 close(STDERR_FILENO + 1); 00295 } 00296 00297 /* unblock important signal handlers */ 00298 if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { 00299 ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); 00300 exit(1); 00301 } 00302 00303 /* Close everything but stdin/out/error */ 00304 for (x=STDERR_FILENO + 2;x<1024;x++) 00305 close(x); 00306 00307 /* Execute script */ 00308 execv(script, argv); 00309 /* Can't use ast_log since FD's are closed */ 00310 fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno)); 00311 exit(1); 00312 } 00313 if (option_verbose > 2) 00314 ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); 00315 fds[0] = toast[0]; 00316 fds[1] = fromast[1]; 00317 if (efd) { 00318 *efd = audio[1]; 00319 } 00320 /* close what we're not using in the parent */ 00321 close(toast[1]); 00322 close(fromast[0]); 00323 00324 if (efd) { 00325 /* [PHM 12/18/03] */ 00326 close(audio[0]); 00327 } 00328 00329 *opid = pid; 00330 return 0; 00331 00332 }
|
|
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 2129 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. 02130 { 02131 ast_cli_register(&showagi); 02132 ast_cli_register(&dumpagihtml); 02133 ast_cli_register(&cli_debug); 02134 ast_cli_register(&cli_no_debug); 02135 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02136 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02137 return ast_register_application(app, agi_exec, synopsis, descrip); 02138 }
|
|
Definition at line 1759 of file res_agi.c. References ast_log(), LOG_WARNING, and MAX_ARGS. 01760 { 01761 int x=0; 01762 int quoted=0; 01763 int escaped=0; 01764 int whitespace=1; 01765 char *cur; 01766 01767 cur = s; 01768 while(*s) { 01769 switch(*s) { 01770 case '"': 01771 /* If it's escaped, put a literal quote */ 01772 if (escaped) 01773 goto normal; 01774 else 01775 quoted = !quoted; 01776 if (quoted && whitespace) { 01777 /* If we're starting a quote, coming off white space start a new word, too */ 01778 argv[x++] = cur; 01779 whitespace=0; 01780 } 01781 escaped = 0; 01782 break; 01783 case ' ': 01784 case '\t': 01785 if (!quoted && !escaped) { 01786 /* If we're not quoted, mark this as whitespace, and 01787 end the previous argument */ 01788 whitespace = 1; 01789 *(cur++) = '\0'; 01790 } else 01791 /* Otherwise, just treat it as anything else */ 01792 goto normal; 01793 break; 01794 case '\\': 01795 /* If we're escaped, print a literal, otherwise enable escaping */ 01796 if (escaped) { 01797 goto normal; 01798 } else { 01799 escaped=1; 01800 } 01801 break; 01802 default: 01803 normal: 01804 if (whitespace) { 01805 if (x >= MAX_ARGS -1) { 01806 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01807 break; 01808 } 01809 /* Coming off of whitespace, start the next argument */ 01810 argv[x++] = cur; 01811 whitespace=0; 01812 } 01813 *(cur++) = *s; 01814 escaped=0; 01815 } 01816 s++; 01817 } 01818 /* Null terminate */ 01819 *(cur++) = '\0'; 01820 argv[x] = NULL; 01821 *max = x; 01822 return 0; 01823 }
|
|
Definition at line 1858 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(). 01859 { 01860 struct ast_channel *c; 01861 int outfd; 01862 int ms; 01863 int returnstatus = 0; 01864 struct ast_frame *f; 01865 char buf[2048]; 01866 FILE *readf; 01867 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01868 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01869 int retry = RETRY; 01870 01871 if (!(readf = fdopen(agi->ctrl, "r"))) { 01872 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01873 if (pid > -1) 01874 kill(pid, SIGHUP); 01875 close(agi->ctrl); 01876 return -1; 01877 } 01878 setlinebuf(readf); 01879 setup_env(chan, request, agi->fd, (agi->audio > -1)); 01880 for (;;) { 01881 ms = -1; 01882 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01883 if (c) { 01884 retry = RETRY; 01885 /* Idle the channel until we get a command */ 01886 f = ast_read(c); 01887 if (!f) { 01888 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01889 returnstatus = -1; 01890 break; 01891 } else { 01892 /* If it's voice, write it to the audio pipe */ 01893 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01894 /* Write, ignoring errors */ 01895 write(agi->audio, f->data, f->datalen); 01896 } 01897 ast_frfree(f); 01898 } 01899 } else if (outfd > -1) { 01900 retry = RETRY; 01901 if (!fgets(buf, sizeof(buf), readf)) { 01902 /* Program terminated */ 01903 if (returnstatus) 01904 returnstatus = -1; 01905 if (option_verbose > 2) 01906 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01907 /* No need to kill the pid anymore, since they closed us */ 01908 pid = -1; 01909 break; 01910 } 01911 /* get rid of trailing newline, if any */ 01912 if (*buf && buf[strlen(buf) - 1] == '\n') 01913 buf[strlen(buf) - 1] = 0; 01914 if (agidebug) 01915 ast_verbose("AGI Rx << %s\n", buf); 01916 returnstatus |= agi_handle_command(chan, agi, buf); 01917 /* If the handle_command returns -1, we need to stop */ 01918 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01919 break; 01920 } 01921 } else { 01922 if (--retry <= 0) { 01923 ast_log(LOG_WARNING, "No channel, no fd?\n"); 01924 returnstatus = -1; 01925 break; 01926 } 01927 } 01928 } 01929 /* Notify process */ 01930 if (pid > -1) { 01931 if (kill(pid, SIGHUP)) 01932 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 01933 } 01934 fclose(readf); 01935 return returnstatus; 01936 }
|
|
Definition at line 334 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(). 00335 { 00336 /* Print initial environment, with agi_request always being the first 00337 thing */ 00338 fdprintf(fd, "agi_request: %s\n", request); 00339 fdprintf(fd, "agi_channel: %s\n", chan->name); 00340 fdprintf(fd, "agi_language: %s\n", chan->language); 00341 fdprintf(fd, "agi_type: %s\n", chan->type); 00342 fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid); 00343 00344 /* ANI/DNIS */ 00345 fdprintf(fd, "agi_callerid: %s\n", chan->cid.cid_num ? chan->cid.cid_num : "unknown"); 00346 fdprintf(fd, "agi_calleridname: %s\n", chan->cid.cid_name ? chan->cid.cid_name : "unknown"); 00347 fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres); 00348 fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2); 00349 fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton); 00350 fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns); 00351 fdprintf(fd, "agi_dnid: %s\n", chan->cid.cid_dnid ? chan->cid.cid_dnid : "unknown"); 00352 fdprintf(fd, "agi_rdnis: %s\n", chan->cid.cid_rdnis ? chan->cid.cid_rdnis : "unknown"); 00353 00354 /* Context information */ 00355 fdprintf(fd, "agi_context: %s\n", chan->context); 00356 fdprintf(fd, "agi_extension: %s\n", chan->exten); 00357 fdprintf(fd, "agi_priority: %d\n", chan->priority); 00358 fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0"); 00359 00360 /* User information */ 00361 fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); 00362 00363 /* End with empty return */ 00364 fdprintf(fd, "\n"); 00365 }
|
|
Cleanup all module structures, sockets, etc. Standard module functions ... Definition at line 2117 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. 02118 { 02119 STANDARD_HANGUP_LOCALUSERS; 02120 ast_cli_unregister(&showagi); 02121 ast_cli_unregister(&dumpagihtml); 02122 ast_cli_unregister(&cli_debug); 02123 ast_cli_unregister(&cli_no_debug); 02124 ast_unregister_application(eapp); 02125 ast_unregister_application(deadapp); 02126 return ast_unregister_application(app); 02127 }
|
|
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 2145 of file res_agi.c. References STANDARD_USECOUNT. 02146 { 02147 int res; 02148 STANDARD_USECOUNT(res); 02149 return res; 02150 }
|
|
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 1614 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 2114 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 2111 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" |
|
|