#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/indications.h"
#include "asterisk/linkedlists.h"

Go to the source code of this file.
Data Structures | |
| struct | linear_state |
Defines | |
| #define | MAX_OTHER_FORMATS 10 |
| #define | RES_EXIT (1 << 17) |
| #define | RES_REPEAT (1 << 18) |
| #define | RES_RESTART ((1 << 19) | RES_REPEAT) |
| #define | RES_UPONE (1 << 16) |
Functions | |
| int | ast_app_dtget (struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout) |
| Present a dialtone and collect a certain length extension. | |
| int | ast_app_getdata (struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout) |
| Plays a stream and gets DTMF data from a channel. | |
| int | ast_app_getdata_full (struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd) |
| Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions. | |
| int | ast_app_getvoice (struct ast_channel *c, char *dest, char *dstfmt, char *prompt, int silence, int maxsec) |
| int | ast_app_group_discard (struct ast_channel *chan) |
| int | ast_app_group_get_count (char *group, char *category) |
| struct ast_group_info * | ast_app_group_list_head (void) |
| int | ast_app_group_list_lock (void) |
| int | ast_app_group_list_unlock (void) |
| int | ast_app_group_match_get_count (char *groupmatch, char *category) |
| int | ast_app_group_set_channel (struct ast_channel *chan, char *data) |
| int | ast_app_group_split_group (char *data, char *group, int group_max, char *category, int category_max) |
| int | ast_app_group_update (struct ast_channel *old, struct ast_channel *new) |
| int | ast_app_has_voicemail (const char *mailbox, const char *folder) |
| int | ast_app_messagecount (const char *mailbox, int *newmsgs, int *oldmsgs) |
| int | ast_app_parse_options (const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr) |
| Parses a string containing application options and sets flags/arguments. | |
| unsigned int | ast_app_separate_args (char *buf, char delim, char **array, int arraylen) |
| Separate a string into arguments in an array. | |
| int | ast_control_streamfile (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms) |
| int | ast_dtmf_stream (struct ast_channel *chan, struct ast_channel *peer, char *digits, int between) |
| void | ast_install_vm_functions (int(*has_voicemail_func)(const char *mailbox, const char *folder), int(*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs)) |
| int | ast_ivr_menu_run (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata) |
| Runs an IVR menu. | |
| static int | ast_ivr_menu_run_internal (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata) |
| int | ast_linear_stream (struct ast_channel *chan, const char *filename, int fd, int allowoverride) |
| static | AST_LIST_HEAD_STATIC (groups, ast_group_info) |
| enum AST_LOCK_RESULT | ast_lock_path (const char *path) |
| Lock a filesystem path. | |
| int | ast_play_and_prepend (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence) |
| int | ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path) |
| int | ast_play_and_record_full (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf) |
| int | ast_play_and_wait (struct ast_channel *chan, const char *fn) |
| char * | ast_read_textfile (const char *filename) |
| int | ast_record_review (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) |
| void | ast_uninstall_vm_functions (void) |
| int | ast_unlock_path (const char *path) |
| static int | ivr_dispatch (struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata) |
| static void * | linear_alloc (struct ast_channel *chan, void *params) |
| static int | linear_generator (struct ast_channel *chan, void *data, int len, int samples) |
| static void | linear_release (struct ast_channel *chan, void *params) |
| static int | option_exists (struct ast_ivr_menu *menu, char *option) |
| static int | option_matchmore (struct ast_ivr_menu *menu, char *option) |
| static int | read_newoption (struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten) |
Variables | |
| static int(* | ast_has_voicemail_func )(const char *mailbox, const char *folder) = NULL |
| static int(* | ast_messagecount_func )(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL |
| static char | default_acceptdtmf [] = "#" |
| static char | default_canceldtmf [] = "0" |
| static int | global_maxsilence = 0 |
| static int | global_silence_threshold = 128 |
| static struct ast_generator | linearstream |
Definition in file app.c.
| #define MAX_OTHER_FORMATS 10 |
Definition at line 53 of file app.c.
Referenced by ast_play_and_prepend(), and ast_play_and_record_full().
| #define RES_EXIT (1 << 17) |
Definition at line 1360 of file app.c.
Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().
| #define RES_REPEAT (1 << 18) |
Definition at line 1361 of file app.c.
Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().
| #define RES_RESTART ((1 << 19) | RES_REPEAT) |
Definition at line 1362 of file app.c.
Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().
| #define RES_UPONE (1 << 16) |
Definition at line 1359 of file app.c.
Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().
| int ast_app_dtget | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| char * | collect, | |||
| size_t | size, | |||
| int | maxlen, | |||
| int | timeout | |||
| ) |
Present a dialtone and collect a certain length extension.
Definition at line 64 of file app.c.
References ast_exists_extension(), ast_get_indication_tone(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_num, tone_zone_sound::data, ast_pbx::dtimeout, LOG_NOTICE, ast_channel::pbx, and ast_channel::zone.
Referenced by builtin_atxfer(), and builtin_blindtransfer().
00065 { 00066 struct tone_zone_sound *ts; 00067 int res=0, x=0; 00068 00069 if(maxlen > size) 00070 maxlen = size; 00071 00072 if(!timeout && chan->pbx) 00073 timeout = chan->pbx->dtimeout; 00074 else if(!timeout) 00075 timeout = 5; 00076 00077 ts = ast_get_indication_tone(chan->zone,"dial"); 00078 if (ts && ts->data[0]) 00079 res = ast_playtones_start(chan, 0, ts->data, 0); 00080 else 00081 ast_log(LOG_NOTICE,"Huh....? no dial for indications?\n"); 00082 00083 for (x = strlen(collect); strlen(collect) < maxlen; ) { 00084 res = ast_waitfordigit(chan, timeout); 00085 if (!ast_ignore_pattern(context, collect)) 00086 ast_playtones_stop(chan); 00087 if (res < 1) 00088 break; 00089 if (res == '#') 00090 break; 00091 collect[x++] = res; 00092 if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) 00093 break; 00094 } 00095 if (res >= 0) { 00096 if (ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num)) 00097 res = 1; 00098 else 00099 res = 0; 00100 } 00101 return res; 00102 }
| int ast_app_getdata | ( | struct ast_channel * | c, | |
| char * | prompt, | |||
| char * | s, | |||
| int | maxlen, | |||
| int | timeout | |||
| ) |
Plays a stream and gets DTMF data from a channel.
| timeout | set timeout to 0 for "standard" timeouts. Set timeout to -1 for "ludicrous time" (essentially never times out) |
Definition at line 108 of file app.c.
References ast_readstring(), ast_streamfile(), ast_pbx::dtimeout, ast_channel::language, ast_channel::pbx, and ast_pbx::rtimeout.
Referenced by __login_exec(), auth_exec(), conf_exec(), dictate_exec(), find_conf(), read_exec(), testclient_exec(), testserver_exec(), and vm_exec().
00109 { 00110 int res,to,fto; 00111 /* XXX Merge with full version? XXX */ 00112 if (maxlen) 00113 s[0] = '\0'; 00114 if (prompt) { 00115 res = ast_streamfile(c, prompt, c->language); 00116 if (res < 0) 00117 return res; 00118 } 00119 fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000; 00120 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000; 00121 00122 if (timeout > 0) 00123 fto = to = timeout; 00124 if (timeout < 0) 00125 fto = to = 1000000000; 00126 res = ast_readstring(c, s, maxlen, to, fto, "#"); 00127 return res; 00128 }
| int ast_app_getdata_full | ( | struct ast_channel * | c, | |
| char * | prompt, | |||
| char * | s, | |||
| int | maxlen, | |||
| int | timeout, | |||
| int | audiofd, | |||
| int | ctrlfd | |||
| ) |
Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions.
Definition at line 131 of file app.c.
References ast_readstring_full(), ast_streamfile(), and ast_channel::language.
Referenced by handle_getdata().
00132 { 00133 int res,to,fto; 00134 if (prompt) { 00135 res = ast_streamfile(c, prompt, c->language); 00136 if (res < 0) 00137 return res; 00138 } 00139 fto = 6000; 00140 to = 2000; 00141 if (timeout > 0) 00142 fto = to = timeout; 00143 if (timeout < 0) 00144 fto = to = 1000000000; 00145 res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd); 00146 return res; 00147 }
| int ast_app_getvoice | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| char * | dstfmt, | |||
| char * | prompt, | |||
| int | silence, | |||
| int | maxsec | |||
| ) |
Record voice (after playing prompt if specified), waiting for silence (in ms) up to a given timeout (in s) or '#'
Definition at line 149 of file app.c.
References ast_closestream(), ast_dsp_free(), ast_dsp_new(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_set_read_format(), ast_streamfile(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), ast_frame::frametype, ast_channel::language, LOG_NOTICE, LOG_WARNING, ast_channel::name, ast_channel::readformat, ast_frame::samples, ast_frame::subclass, and total.
00150 { 00151 int res; 00152 struct ast_filestream *writer; 00153 int rfmt; 00154 int totalms=0, total; 00155 00156 struct ast_frame *f; 00157 struct ast_dsp *sildet; 00158 /* Play prompt if requested */ 00159 if (prompt) { 00160 res = ast_streamfile(c, prompt, c->language); 00161 if (res < 0) 00162 return res; 00163 res = ast_waitstream(c,""); 00164 if (res < 0) 00165 return res; 00166 } 00167 rfmt = c->readformat; 00168 res = ast_set_read_format(c, AST_FORMAT_SLINEAR); 00169 if (res < 0) { 00170 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00171 return -1; 00172 } 00173 sildet = ast_dsp_new(); 00174 if (!sildet) { 00175 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00176 return -1; 00177 } 00178 writer = ast_writefile(dest, dstfmt, "Voice file", 0, 0, 0666); 00179 if (!writer) { 00180 ast_log(LOG_WARNING, "Unable to open file '%s' in format '%s' for writing\n", dest, dstfmt); 00181 ast_dsp_free(sildet); 00182 return -1; 00183 } 00184 for(;;) { 00185 if ((res = ast_waitfor(c, 2000)) < 0) { 00186 ast_log(LOG_NOTICE, "Waitfor failed while recording file '%s' format '%s'\n", dest, dstfmt); 00187 break; 00188 } 00189 if (res) { 00190 f = ast_read(c); 00191 if (!f) { 00192 ast_log(LOG_NOTICE, "Hungup while recording file '%s' format '%s'\n", dest, dstfmt); 00193 break; 00194 } 00195 if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { 00196 /* Ended happily with DTMF */ 00197 ast_frfree(f); 00198 break; 00199 } else if (f->frametype == AST_FRAME_VOICE) { 00200 ast_dsp_silence(sildet, f, &total); 00201 if (total > silence) { 00202 /* Ended happily with silence */ 00203 ast_frfree(f); 00204 break; 00205 } 00206 totalms += f->samples / 8; 00207 if (totalms > maxsec * 1000) { 00208 /* Ended happily with too much stuff */ 00209 ast_log(LOG_NOTICE, "Constraining voice on '%s' to %d seconds\n", c->name, maxsec); 00210 ast_frfree(f); 00211 break; 00212 } 00213 res = ast_writestream(writer, f); 00214 if (res < 0) { 00215 ast_log(LOG_WARNING, "Failed to write to stream at %s!\n", dest); 00216 ast_frfree(f); 00217 break; 00218 } 00219 00220 } 00221 ast_frfree(f); 00222 } 00223 } 00224 res = ast_set_read_format(c, rfmt); 00225 if (res) 00226 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", c->name); 00227 ast_dsp_free(sildet); 00228 ast_closestream(writer); 00229 return 0; 00230 }
| int ast_app_group_discard | ( | struct ast_channel * | chan | ) |
Discard all group counting for a channel
Definition at line 1134 of file app.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_group_info::chan, free, and list.
Referenced by ast_channel_free().
01135 { 01136 struct ast_group_info *gi = NULL; 01137 01138 AST_LIST_LOCK(&groups); 01139 AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { 01140 if (gi->chan == chan) { 01141 AST_LIST_REMOVE_CURRENT(&groups, list); 01142 free(gi); 01143 } 01144 } 01145 AST_LIST_TRAVERSE_SAFE_END 01146 AST_LIST_UNLOCK(&groups); 01147 01148 return 0; 01149 }
| int ast_app_group_get_count | ( | char * | group, | |
| char * | category | |||
| ) |
Get the current channel count of the specified group and category.
Definition at line 1077 of file app.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_group_info::category, ast_group_info::group, and list.
Referenced by group_check_exec(), group_count_exec(), and group_count_function_read().
01078 { 01079 struct ast_group_info *gi = NULL; 01080 int count = 0; 01081 01082 if (ast_strlen_zero(group)) 01083 return 0; 01084 01085 AST_LIST_LOCK(&groups); 01086 AST_LIST_TRAVERSE(&groups, gi, list) { 01087 if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) 01088 count++; 01089 } 01090 AST_LIST_UNLOCK(&groups); 01091 01092 return count; 01093 }
| struct ast_group_info* ast_app_group_list_head | ( | void | ) | [read] |
Get the head of the group count list
Definition at line 1156 of file app.c.
References AST_LIST_FIRST.
Referenced by group_function_read(), group_list_function_read(), and group_show_channels().
01157 { 01158 return AST_LIST_FIRST(&groups); 01159 }
| int ast_app_group_list_lock | ( | void | ) |
Lock the group count list
Definition at line 1151 of file app.c.
References AST_LIST_LOCK.
Referenced by group_function_read(), group_list_function_read(), and group_show_channels().
01152 { 01153 return AST_LIST_LOCK(&groups); 01154 }
| int ast_app_group_list_unlock | ( | void | ) |
Unlock the group count list
Definition at line 1161 of file app.c.
References AST_LIST_UNLOCK.
Referenced by group_function_read(), group_list_function_read(), and group_show_channels().
01162 { 01163 return AST_LIST_UNLOCK(&groups); 01164 }
| int ast_app_group_match_get_count | ( | char * | groupmatch, | |
| char * | category | |||
| ) |
Get the current channel count of all groups that match the specified pattern and category.
Definition at line 1095 of file app.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_group_info::category, ast_group_info::group, and list.
Referenced by group_match_count_exec(), and group_match_count_function_read().
01096 { 01097 struct ast_group_info *gi = NULL; 01098 regex_t regexbuf; 01099 int count = 0; 01100 01101 if (ast_strlen_zero(groupmatch)) 01102 return 0; 01103 01104 /* if regex compilation fails, return zero matches */ 01105 if (regcomp(®exbuf, groupmatch, REG_EXTENDED | REG_NOSUB)) 01106 return 0; 01107 01108 AST_LIST_LOCK(&groups); 01109 AST_LIST_TRAVERSE(&groups, gi, list) { 01110 if (!regexec(®exbuf, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) 01111 count++; 01112 } 01113 AST_LIST_UNLOCK(&groups); 01114 01115 regfree(®exbuf); 01116 01117 return count; 01118 }
| int ast_app_group_set_channel | ( | struct ast_channel * | chan, | |
| char * | data | |||
| ) |
Set the group for a channel, splitting the provided data into group and category, if specified.
Definition at line 1034 of file app.c.
References ast_app_group_split_group(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_strlen_zero(), calloc, ast_group_info::category, ast_group_info::chan, free, ast_group_info::group, group, and list.
Referenced by dial_exec_full(), group_function_write(), and group_set_exec().
01035 { 01036 int res = 0; 01037 char group[80] = "", category[80] = ""; 01038 struct ast_group_info *gi = NULL; 01039 size_t len = 0; 01040 01041 if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) 01042 return -1; 01043 01044 /* Calculate memory we will need if this is new */ 01045 len = sizeof(*gi) + strlen(group) + 1; 01046 if (!ast_strlen_zero(category)) 01047 len += strlen(category) + 1; 01048 01049 AST_LIST_LOCK(&groups); 01050 AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { 01051 if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) { 01052 AST_LIST_REMOVE_CURRENT(&groups, list); 01053 free(gi); 01054 break; 01055 } 01056 } 01057 AST_LIST_TRAVERSE_SAFE_END 01058 01059 if ((gi = calloc(1, len))) { 01060 gi->chan = chan; 01061 gi->group = (char *) gi + sizeof(*gi); 01062 strcpy(gi->group, group); 01063 if (!ast_strlen_zero(category)) { 01064 gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1; 01065 strcpy(gi->category, category); 01066 } 01067 AST_LIST_INSERT_TAIL(&groups, gi, list); 01068 } else { 01069 res = -1; 01070 } 01071 01072 AST_LIST_UNLOCK(&groups); 01073 01074 return res; 01075 }
| int ast_app_group_split_group | ( | char * | data, | |
| char * | group, | |||
| int | group_max, | |||
| char * | category, | |||
| int | category_max | |||
| ) |
Split a group string into group and category, returning a default category if none is provided.
Definition at line 1007 of file app.c.
References ast_strlen_zero().
Referenced by ast_app_group_set_channel(), group_check_exec(), group_count_exec(), group_count_function_read(), group_match_count_exec(), and group_match_count_function_read().
01008 { 01009 int res=0; 01010 char tmp[256]; 01011 char *grp=NULL, *cat=NULL; 01012 01013 if (!ast_strlen_zero(data)) { 01014 ast_copy_string(tmp, data, sizeof(tmp)); 01015 grp = tmp; 01016 cat = strchr(tmp, '@'); 01017 if (cat) { 01018 *cat = '\0'; 01019 cat++; 01020 } 01021 } 01022 01023 if (!ast_strlen_zero(grp)) 01024 ast_copy_string(group, grp, group_max); 01025 else 01026 res = -1; 01027 01028 if (!ast_strlen_zero(cat)) 01029 ast_copy_string(category, cat, category_max); 01030 01031 return res; 01032 }
| int ast_app_group_update | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) |
Update all group counting for a channel to a new one
Definition at line 1120 of file app.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_group_info::chan, and list.
Referenced by ast_do_masquerade().
01121 { 01122 struct ast_group_info *gi = NULL; 01123 01124 AST_LIST_LOCK(&groups); 01125 AST_LIST_TRAVERSE(&groups, gi, list) { 01126 if (gi->chan == old) 01127 gi->chan = new; 01128 } 01129 AST_LIST_UNLOCK(&groups); 01130 01131 return 0; 01132 }
| int ast_app_has_voicemail | ( | const char * | mailbox, | |
| const char * | folder | |||
| ) |
Determine if a given mailbox has any voicemail
Definition at line 248 of file app.c.
References ast_has_voicemail_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.
Referenced by action_mailboxstatus(), do_monitor(), has_voicemail(), notify_new_message(), play_dialtone(), and update_registry().
00249 { 00250 static int warned = 0; 00251 if (ast_has_voicemail_func) 00252 return ast_has_voicemail_func(mailbox, folder); 00253 00254 if ((option_verbose > 2) && !warned) { 00255 ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX"); 00256 warned++; 00257 } 00258 return 0; 00259 }
| int ast_app_messagecount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) |
Determine number of new/old messages in a mailbox
Definition at line 262 of file app.c.
References ast_messagecount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.
Referenced by action_mailboxcount(), do_housekeeping(), notify_new_message(), sip_send_mwi_to_peer(), and update_registry().
00263 { 00264 static int warned = 0; 00265 if (newmsgs) 00266 *newmsgs = 0; 00267 if (oldmsgs) 00268 *oldmsgs = 0; 00269 if (ast_messagecount_func) 00270 return ast_messagecount_func(mailbox, newmsgs, oldmsgs); 00271 00272 if (!warned && (option_verbose > 2)) { 00273 warned++; 00274 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox); 00275 } 00276 00277 return 0; 00278 }
| int ast_app_parse_options | ( | const struct ast_app_option * | options, | |
| struct ast_flags * | flags, | |||
| char ** | args, | |||
| char * | optstr | |||
| ) |
Parses a string containing application options and sets flags/arguments.
| options | The array of possible options declared with AST_APP_OPTIONS | |
| flags | The flag structure to have option flags set | |
| args | The array of argument pointers to hold arguments found | |
| optstr | The string containing the options to be parsed |
Definition at line 1596 of file app.c.
References ast_app_option::arg_index, ast_clear_flag, AST_FLAGS_ALL, ast_log(), ast_set_flag, LOG_WARNING, and s.
Referenced by app_exec(), chanspy_exec(), conf_exec(), dial_exec_full(), mixmonitor_exec(), page_exec(), pbx_builtin_background(), pbx_builtin_resetcdr(), pbx_builtin_waitexten(), vm_exec(), and vm_execmain().
01597 { 01598 char *s; 01599 int curarg; 01600 unsigned int argloc; 01601 char *arg; 01602 int res = 0; 01603 01604 ast_clear_flag(flags, AST_FLAGS_ALL); 01605 01606 if (!optstr) 01607 return 0; 01608 01609 s = optstr; 01610 while (*s) { 01611 curarg = *s++ & 0x7f; 01612 ast_set_flag(flags, options[curarg].flag); 01613 argloc = options[curarg].arg_index; 01614 if (*s == '(') { 01615 /* Has argument */ 01616 arg = ++s; 01617 while (*s && (*s != ')')) 01618 s++; 01619 if (*s) { 01620 if (argloc) 01621 args[argloc - 1] = arg; 01622 *s++ = '\0'; 01623 } else { 01624 ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg); 01625 res = -1; 01626 } 01627 } else if (argloc) { 01628 args[argloc - 1] = NULL; 01629 } 01630 } 01631 01632 return res; 01633 }
| unsigned int ast_app_separate_args | ( | char * | buf, | |
| char | delim, | |||
| char ** | array, | |||
| int | arraylen | |||
| ) |
Separate a string into arguments in an array.
| buf | The string to be parsed (this must be a writable copy, as it will be modified) | |
| delim | The character to be used to delimit arguments | |
| array | An array of 'char *' to be filled in with pointers to the found arguments | |
| arraylen | The number of elements in the array (i.e. the number of arguments you will accept) |
The array will be completely zeroed by this function before it populates any entries.
Definition at line 1166 of file app.c.
Referenced by add_agent(), app_exec(), astman_get_variables(), builtin_function_cdr_read(), builtin_function_cdr_write(), builtin_function_checkmd5(), builtin_function_math(), chanspy_exec(), controlplayback_exec(), cut_internal(), dictate_exec(), function_db_exists(), function_db_read(), function_db_write(), pbx_builtin_background(), pbx_builtin_setvar(), pbx_builtin_waitexten(), read_exec(), record_exec(), vm_exec(), and vm_execmain().
01167 { 01168 int argc; 01169 char *scan; 01170 int paren = 0; 01171 01172 if (!buf || !array || !arraylen) 01173 return 0; 01174 01175 memset(array, 0, arraylen * sizeof(*array)); 01176 01177 scan = buf; 01178 01179 for (argc = 0; *scan && (argc < arraylen - 1); argc++) { 01180 array[argc] = scan; 01181 for (; *scan; scan++) { 01182 if (*scan == '(') 01183 paren++; 01184 else if (*scan == ')') { 01185 if (paren) 01186 paren--; 01187 } else if ((*scan == delim) && !paren) { 01188 *scan++ = '\0'; 01189 break; 01190 } 01191 } 01192 } 01193 01194 if (*scan) 01195 array[argc++] = scan; 01196 01197 return argc; 01198 }
| int ast_control_streamfile | ( | struct ast_channel * | chan, | |
| const char * | file, | |||
| const char * | fwd, | |||
| const char * | rev, | |||
| const char * | stop, | |||
| const char * | pause, | |||
| const char * | restart, | |||
| int | skipms | |||
| ) |
Stream a file with fast forward, pause, reverse, restart.
Definition at line 431 of file app.c.
References ast_channel::_state, ast_answer(), ast_log(), ast_seekstream(), AST_STATE_UP, ast_stopstream(), ast_streamfile(), ast_tellstream(), ast_waitfordigit(), ast_waitstream_fr(), ast_channel::language, LOG_DEBUG, and ast_channel::stream.
Referenced by controlplayback_exec(), handle_controlstreamfile(), and wait_file().
00435 { 00436 char *breaks = NULL; 00437 char *end = NULL; 00438 int blen = 2; 00439 int res; 00440 long pause_restart_point = 0; 00441 00442 if (stop) 00443 blen += strlen(stop); 00444 if (pause) 00445 blen += strlen(pause); 00446 if (restart) 00447 blen += strlen(restart); 00448 00449 if (blen > 2) { 00450 breaks = alloca(blen + 1); 00451 breaks[0] = '\0'; 00452 if (stop) 00453 strcat(breaks, stop); 00454 if (pause) 00455 strcat(breaks, pause); 00456 if (restart) 00457 strcat(breaks, restart); 00458 } 00459 if (chan->_state != AST_STATE_UP) 00460 res = ast_answer(chan); 00461 00462 if (file) { 00463 if ((end = strchr(file,':'))) { 00464 if (!strcasecmp(end, ":end")) { 00465 *end = '\0'; 00466 end++; 00467 } 00468 } 00469 } 00470 00471 for (;;) { 00472 ast_stopstream(chan); 00473 res = ast_streamfile(chan, file, chan->language); 00474 if (!res) { 00475 if (pause_restart_point) { 00476 ast_seekstream(chan->stream, pause_restart_point, SEEK_SET); 00477 pause_restart_point = 0; 00478 } 00479 else if (end) { 00480 ast_seekstream(chan->stream, 0, SEEK_END); 00481 end = NULL; 00482 }; 00483 res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms); 00484 } 00485 00486 if (res < 1) 00487 break; 00488 00489 /* We go at next loop if we got the restart char */ 00490 if (restart && strchr(restart, res)) { 00491 ast_log(LOG_DEBUG, "we'll restart the stream here at next loop\n"); 00492 pause_restart_point = 0; 00493 continue; 00494 } 00495 00496 if (pause && strchr(pause, res)) { 00497 pause_restart_point = ast_tellstream(chan->stream); 00498 for (;;) { 00499 ast_stopstream(chan); 00500 res = ast_waitfordigit(chan, 1000); 00501 if (!res) 00502 continue; 00503 else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res))) 00504 break; 00505 } 00506 if (res == *pause) { 00507 res = 0; 00508 continue; 00509 } 00510 } 00511 00512 if (res == -1) 00513 break; 00514 00515 /* if we get one of our stop chars, return it to the calling function */ 00516 if (stop && strchr(stop, res)) 00517 break; 00518 } 00519 00520 ast_stopstream(chan); 00521 00522 return res; 00523 }
| int ast_dtmf_stream | ( | struct ast_channel * | chan, | |
| struct ast_channel * | peer, | |||
| char * | digits, | |||
| int | between | |||
| ) |
Send DTMF to chan (optionally entertain peer)
Definition at line 280 of file app.c.
References ast_autoservice_start(), ast_autoservice_stop(), AST_FRAME_DTMF, ast_log(), ast_safe_sleep(), ast_waitfor(), ast_write(), ast_frame::frametype, LOG_WARNING, ast_frame::src, and ast_frame::subclass.
Referenced by ast_bridge_call(), dial_exec_full(), misdn_send_digit(), senddtmf_exec(), testclient_exec(), and testserver_exec().
00281 { 00282 char *ptr; 00283 int res = 0; 00284 struct ast_frame f; 00285 if (!between) 00286 between = 100; 00287 00288 if (peer) 00289 res = ast_autoservice_start(peer); 00290 00291 if (!res) { 00292 res = ast_waitfor(chan,100); 00293 if (res > -1) { 00294 for (ptr=digits; *ptr; ptr++) { 00295 if (*ptr == 'w') { 00296 res = ast_safe_sleep(chan, 500); 00297 if (res) 00298 break; 00299 continue; 00300 } 00301 memset(&f, 0, sizeof(f)); 00302 f.frametype = AST_FRAME_DTMF; 00303 f.subclass = *ptr; 00304 f.src = "ast_dtmf_stream"; 00305 if (strchr("0123456789*#abcdABCD",*ptr)==NULL) { 00306 ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr); 00307 } else { 00308 res = ast_write(chan, &f); 00309 if (res) 00310 break; 00311 /* pause between digits */ 00312 res = ast_safe_sleep(chan,between); 00313 if (res) 00314 break; 00315 } 00316 } 00317 } 00318 if (peer) { 00319 /* Stop autoservice on the peer channel, but don't overwrite any error condition 00320 that has occurred previously while acting on the primary channel */ 00321 if (ast_autoservice_stop(peer) && !res) 00322 res = -1; 00323 } 00324 } 00325 return res; 00326 }
| void ast_install_vm_functions | ( | int(*)(const char *mailbox, const char *folder) | has_voicemail_func, | |
| int(*)(const char *mailbox, int *newmsgs, int *oldmsgs) | messagecount_func | |||
| ) |
Definition at line 235 of file app.c.
References ast_has_voicemail_func, and ast_messagecount_func.
Referenced by load_module().
00237 { 00238 ast_has_voicemail_func = has_voicemail_func; 00239 ast_messagecount_func = messagecount_func; 00240 }
| int ast_ivr_menu_run | ( | struct ast_channel * | c, | |
| struct ast_ivr_menu * | menu, | |||
| void * | cbdata | |||
| ) |
Runs an IVR menu.
Definition at line 1553 of file app.c.
References ast_ivr_menu_run_internal().
Referenced by skel_exec().
01554 { 01555 int res; 01556 res = ast_ivr_menu_run_internal(chan, menu, cbdata); 01557 /* Hide internal coding */ 01558 if (res > 0) 01559 res = 0; 01560 return res; 01561 }
| static int ast_ivr_menu_run_internal | ( | struct ast_channel * | chan, | |
| struct ast_ivr_menu * | menu, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 1473 of file app.c.
References AST_DIGIT_ANY, ast_log(), AST_MAX_EXTENSION, exten, ivr_dispatch(), LOG_DEBUG, LOG_WARNING, maxretries, ast_ivr_option::option, option_exists(), ast_ivr_menu::options, read_newoption(), RES_EXIT, RES_REPEAT, RES_RESTART, RES_UPONE, and ast_ivr_menu::title.
Referenced by ast_ivr_menu_run(), and ivr_dispatch().
01474 { 01475 /* Execute an IVR menu structure */ 01476 int res=0; 01477 int pos = 0; 01478 int retries = 0; 01479 char exten[AST_MAX_EXTENSION] = "s"; 01480 if (option_exists(menu, "s") < 0) { 01481 strcpy(exten, "g"); 01482 if (option_exists(menu, "g") < 0) { 01483 ast_log(LOG_WARNING, "No 's' nor 'g' extension in menu '%s'!\n", menu->title); 01484 return -1; 01485 } 01486 } 01487 while(!res) { 01488 while(menu->options[pos].option) { 01489 if (!strcasecmp(menu->options[pos].option, exten)) { 01490 res = ivr_dispatch(chan, menu->options + pos, exten, cbdata); 01491 ast_log(LOG_DEBUG, "IVR Dispatch of '%s' (pos %d) yields %d\n", exten, pos, res); 01492 if (res < 0) 01493 break; 01494 else if (res & RES_UPONE) 01495 return 0; 01496 else if (res & RES_EXIT) 01497 return res; 01498 else if (res & RES_REPEAT) { 01499 int maxretries = res & 0xffff; 01500 if ((res & RES_RESTART) == RES_RESTART) { 01501 retries = 0; 01502 } else 01503 retries++; 01504 if (!maxretries) 01505 maxretries = 3; 01506 if ((maxretries > 0) && (retries >= maxretries)) { 01507 ast_log(LOG_DEBUG, "Max retries %d exceeded\n", maxretries); 01508 return -2; 01509 } else { 01510 if (option_exists(menu, "g") > -1) 01511 strcpy(exten, "g"); 01512 else if (option_exists(menu, "s") > -1) 01513 strcpy(exten, "s"); 01514 } 01515 pos=0; 01516 continue; 01517 } else if (res && strchr(AST_DIGIT_ANY, res)) { 01518 ast_log(LOG_DEBUG, "Got start of extension, %c\n", res); 01519 exten[1] = '\0'; 01520 exten[0] = res; 01521 if ((res = read_newoption(chan, menu, exten, sizeof(exten)))) 01522 break; 01523 if (option_exists(menu, exten) < 0) { 01524 if (option_exists(menu, "i")) { 01525 ast_log(LOG_DEBUG, "Invalid extension entered, going to 'i'!\n"); 01526 strcpy(exten, "i"); 01527 pos = 0; 01528 continue; 01529 } else { 01530 ast_log(LOG_DEBUG, "Aborting on invalid entry, with no 'i' option!\n"); 01531 res = -2; 01532 break; 01533 } 01534 } else { 01535 ast_log(LOG_DEBUG, "New existing extension: %s\n", exten); 01536 pos = 0; 01537 continue; 01538 } 01539 } 01540 } 01541 pos++; 01542 } 01543 ast_log(LOG_DEBUG, "Stopping option '%s', res is %d\n", exten, res); 01544 pos = 0; 01545 if (!strcasecmp(exten, "s")) 01546 strcpy(exten, "g"); 01547 else 01548 break; 01549 } 01550 return res; 01551 }
| int ast_linear_stream | ( | struct ast_channel * | chan, | |
| const char * | filename, | |||
| int | fd, | |||
| int | allowoverride | |||
| ) |
Stream a filename (or file descriptor) as a generator.
Definition at line 400 of file app.c.
References linear_state::allowoverride, ast_activate_generator(), ast_config_AST_VAR_DIR, ast_log(), ast_strlen_zero(), linear_state::autoclose, linear_state::fd, LOG_WARNING, and malloc.
00401 { 00402 struct linear_state *lin; 00403 char tmpf[256]; 00404 int res = -1; 00405 int autoclose = 0; 00406 if (fd < 0) { 00407 if (ast_strlen_zero(filename)) 00408 return -1; 00409 autoclose = 1; 00410 if (filename[0] == '/') 00411 ast_copy_string(tmpf, filename, sizeof(tmpf)); 00412 else 00413 snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", (char *)ast_config_AST_VAR_DIR, "sounds", filename); 00414 fd = open(tmpf, O_RDONLY); 00415 if (fd < 0){ 00416 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); 00417 return -1; 00418 } 00419 } 00420 lin = malloc(sizeof(struct linear_state)); 00421 if (lin) { 00422 memset(lin, 0, sizeof(lin)); 00423 lin->fd = fd; 00424 lin->allowoverride = allowoverride; 00425 lin->autoclose = autoclose; 00426 res = ast_activate_generator(chan, &linearstream, lin); 00427 } 00428 return res; 00429 }
| static AST_LIST_HEAD_STATIC | ( | groups | , | |
| ast_group_info | ||||
| ) | [static] |
| enum AST_LOCK_RESULT ast_lock_path | ( | const char * | path | ) |
Lock a filesystem path.
| path | the path to be locked |
Definition at line 1200 of file app.c.
References AST_LOCK_FAILURE, AST_LOCK_PATH_NOT_FOUND, AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, and s.
Referenced by vm_lock_path().
01201 { 01202 char *s; 01203 char *fs; 01204 int res; 01205 int fd; 01206 time_t start; 01207 01208 s = alloca(strlen(path) + 10); 01209 fs = alloca(strlen(path) + 20); 01210 01211 if (!fs || !s) { 01212 ast_log(LOG_WARNING, "Out of memory!\n"); 01213 return AST_LOCK_FAILURE; 01214 } 01215 01216 snprintf(fs, strlen(path) + 19, "%s/.lock-%08x", path, rand()); 01217 fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600); 01218 if (fd < 0) { 01219 ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno)); 01220 return AST_LOCK_PATH_NOT_FOUND; 01221 } 01222 close(fd); 01223 01224 snprintf(s, strlen(path) + 9, "%s/.lock", path); 01225 time(&start); 01226 while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) 01227 usleep(1); 01228 01229 unlink(fs); 01230 01231 if (res) { 01232 ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno)); 01233 return AST_LOCK_TIMEOUT; 01234 } else { 01235 ast_log(LOG_DEBUG, "Locked path '%s'\n", path); 01236 return AST_LOCK_SUCCESS; 01237 } 01238 }
| int ast_play_and_prepend | ( | struct ast_channel * | chan, | |
| char * | playfile, | |||
| char * | recordfile, | |||
| int | maxtime_sec, | |||
| char * | fmt, | |||
| int * | duration, | |||
| int | beep, | |||
| int | silencethreshold, | |||
| int | maxsilence_ms | |||
| ) |
Record a message and prepend the message to the given record file after playing the optional playfile (or a beep), storing the duration in 'duration' and with a maximum
permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults.
Definition at line 771 of file app.c.
References ast_closestream(), ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), ast_filedelete(), ast_filerename(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), ast_play_and_wait(), ast_read(), ast_readfile(), ast_readframe(), ast_set_read_format(), ast_strdupa, ast_stream_rewind(), ast_streamfile(), ast_truncstream(), ast_verbose(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), ast_frame::frametype, ast_channel::language, LOG_DEBUG, LOG_WARNING, MAX_OTHER_FORMATS, ast_channel::name, option_verbose, ast_channel::readformat, strsep(), ast_frame::subclass, ast_dsp::totalsilence, and VERBOSE_PREFIX_3.
Referenced by vm_forwardoptions().
00772 { 00773 int d = 0; 00774 char *fmts; 00775 char comment[256]; 00776 int x, fmtcnt=1, res=-1,outmsg=0; 00777 struct ast_frame *f; 00778 struct ast_filestream *others[MAX_OTHER_FORMATS]; 00779 struct ast_filestream *realfiles[MAX_OTHER_FORMATS]; 00780 char *sfmt[MAX_OTHER_FORMATS]; 00781 char *stringp=NULL; 00782 time_t start, end; 00783 struct ast_dsp *sildet; /* silence detector dsp */ 00784 int totalsilence = 0; 00785 int dspsilence = 0; 00786 int rfmt=0; 00787 char prependfile[80]; 00788 00789 if (silencethreshold < 0) 00790 silencethreshold = global_silence_threshold; 00791 00792 if (maxsilence < 0) 00793 maxsilence = global_maxsilence; 00794 00795 /* barf if no pointer passed to store duration in */ 00796 if (duration == NULL) { 00797 ast_log(LOG_WARNING, "Error play_and_prepend called without duration pointer\n"); 00798 return -1; 00799 } 00800 00801 ast_log(LOG_DEBUG,"play_and_prepend: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt); 00802 snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name); 00803 00804 if (playfile || beep) { 00805 if (!beep) 00806 d = ast_play_and_wait(chan, playfile); 00807 if (d > -1) 00808 d = ast_streamfile(chan, "beep",chan->language); 00809 if (!d) 00810 d = ast_waitstream(chan,""); 00811 if (d < 0) 00812 return -1; 00813 } 00814 ast_copy_string(prependfile, recordfile, sizeof(prependfile)); 00815 strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1); 00816 00817 fmts = ast_strdupa(fmt); 00818 00819 stringp=fmts; 00820 strsep(&stringp, "|"); 00821 ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts); 00822 sfmt[0] = ast_strdupa(fmts); 00823 00824 while((fmt = strsep(&stringp, "|"))) { 00825 if (fmtcnt > MAX_OTHER_FORMATS - 1) { 00826 ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n"); 00827 break; 00828 } 00829 sfmt[fmtcnt++] = ast_strdupa(fmt); 00830 } 00831 00832 time(&start); 00833 end=start; /* pre-initialize end to be same as start in case we never get into loop */ 00834 for (x=0;x<fmtcnt;x++) { 00835 others[x] = ast_writefile(prependfile, sfmt[x], comment, O_TRUNC, 0, 0700); 00836 ast_verbose( VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, prependfile, sfmt[x], others[x]); 00837 if (!others[x]) { 00838 break; 00839 } 00840 } 00841 00842 sildet = ast_dsp_new(); /* Create the silence detector */ 00843 if (!sildet) { 00844 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00845 return -1; 00846 } 00847 ast_dsp_set_threshold(sildet, silencethreshold); 00848 00849 if (maxsilence > 0) { 00850 rfmt = chan->readformat; 00851 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00852 if (res < 0) { 00853 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00854 ast_dsp_free(sildet); 00855 return -1; 00856 } 00857 } 00858 00859 if (x == fmtcnt) { 00860 /* Loop forever, writing the packets we read to the writer(s), until 00861 we read a # or get a hangup */ 00862 f = NULL; 00863 for(;;) { 00864 res = ast_waitfor(chan, 2000); 00865 if (!res) { 00866 ast_log(LOG_DEBUG, "One waitfor failed, trying another\n"); 00867 /* Try one more time in case of masq */ 00868 res = ast_waitfor(chan, 2000); 00869 if (!res) { 00870 ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name); 00871 res = -1; 00872 } 00873 } 00874 00875 if (res < 0) { 00876 f = NULL; 00877 break; 00878 } 00879 f = ast_read(chan); 00880 if (!f) 00881 break; 00882 if (f->frametype == AST_FRAME_VOICE) { 00883 /* write each format */ 00884 for (x=0;x<fmtcnt;x++) { 00885 if (!others[x]) 00886 break; 00887 res = ast_writestream(others[x], f); 00888 } 00889 00890 /* Silence Detection */ 00891 if (maxsilence > 0) { 00892 dspsilence = 0; 00893 ast_dsp_silence(sildet, f, &dspsilence); 00894 if (dspsilence) 00895 totalsilence = dspsilence; 00896 else 00897 totalsilence = 0; 00898 00899 if (totalsilence > maxsilence) { 00900 /* Ended happily with silence */ 00901 if (option_verbose > 2) 00902 ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); 00903 ast_frfree(f); 00904 res = 'S'; 00905 outmsg=2; 00906 break; 00907 } 00908 } 00909 /* Exit on any error */ 00910 if (res) { 00911 ast_log(LOG_WARNING, "Error writing frame\n"); 00912 ast_frfree(f); 00913 break; 00914 } 00915 } else if (f->frametype == AST_FRAME_VIDEO) { 00916 /* Write only once */ 00917 ast_writestream(others[0], f); 00918 } else if (f->frametype == AST_FRAME_DTMF) { 00919 /* stop recording with any digit */ 00920 if (option_verbose > 2) 00921 ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); 00922 res = 't'; 00923 outmsg = 2; 00924 ast_frfree(f); 00925 break; 00926 } 00927 if (maxtime) { 00928 time(&end); 00929 if (maxtime < (end - start)) { 00930 if (option_verbose > 2) 00931 ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); 00932 res = 't'; 00933 outmsg=2; 00934 ast_frfree(f); 00935 break; 00936 } 00937 } 00938 ast_frfree(f); 00939 } 00940 if (end == start) time(&end); 00941 if (!f) { 00942 if (option_verbose > 2) 00943 ast_verbose( VERBOSE_PREFIX_3 "User hung up\n"); 00944 res = -1; 00945 outmsg=1; 00946 #if 0 00947 /* delete all the prepend files */ 00948 for (x=0;x<fmtcnt;x++) { 00949 if (!others[x]) 00950 break; 00951 ast_closestream(others[x]); 00952 ast_filedelete(prependfile, sfmt[x]); 00953 } 00954 #endif 00955 } 00956 } else { 00957 ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); 00958 } 00959 ast_dsp_free(sildet); 00960 *duration = end - start; 00961 #if 0 00962 if (outmsg > 1) { 00963 #else 00964 if (outmsg) { 00965 #endif 00966 struct ast_frame *fr; 00967 for (x=0;x<fmtcnt;x++) { 00968 snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]); 00969 realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0); 00970 if (!others[x] || !realfiles[x]) 00971 break; 00972 if (totalsilence) 00973 ast_stream_rewind(others[x], totalsilence-200); 00974 else 00975 ast_stream_rewind(others[x], 200); 00976 ast_truncstream(others[x]); 00977 /* add the original file too */ 00978 while ((fr = ast_readframe(realfiles[x]))) { 00979 ast_writestream(others[x],fr); 00980 } 00981 ast_closestream(others[x]); 00982 ast_closestream(realfiles[x]); 00983 ast_filerename(prependfile, recordfile, sfmt[x]); 00984 #if 0 00985 ast_verbose("Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x],prependfile,recordfile); 00986 #endif 00987 ast_filedelete(prependfile, sfmt[x]); 00988 } 00989 } 00990 if (rfmt) { 00991 if (ast_set_read_format(chan, rfmt)) { 00992 ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name); 00993 } 00994 } 00995 if (outmsg) { 00996 if (outmsg > 1) { 00997 /* Let them know it worked */ 00998 ast_streamfile(chan, "auth-thankyou", chan->language); 00999 ast_waitstream(chan, ""); 01000 } 01001 } 01002 return res; 01003 }
| int ast_play_and_record | ( | struct ast_channel * | chan, | |
| const char * | playfile, | |||
| const char * | recordfile, | |||
| int | maxtime_sec, | |||
| const char * | fmt, | |||
| int * | duration, | |||
| int | silencethreshold, | |||
| int | maxsilence_ms, | |||
| const char * | path | |||
| ) |
Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum
permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. calls ast_unlock_path() on 'path' if passed
Definition at line 766 of file app.c.
References ast_play_and_record_full().
Referenced by ast_record_review(), and dial_exec_full().
00767 { 00768 return ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path, default_acceptdtmf, default_canceldtmf); 00769 }
| int ast_play_and_record_full | ( | struct ast_channel * | chan, | |
| const char * | playfile, | |||
| const char * | recordfile, | |||
| int | maxtime, | |||
| const char * | fmt, | |||
| int * | duration, | |||
| int | silencethreshold, | |||
| int | maxsilence, | |||
| const char * | path, | |||
| const char * | acceptdtmf, | |||
| const char * | canceldtmf | |||
| ) |
Definition at line 539 of file app.c.
References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), 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_getformatname(), ast_indicate(), ast_log(), ast_play_and_wait(), ast_read(), ast_set_read_format(), ast_strdupa, ast_stream_rewind(), ast_streamfile(), ast_truncstream(), ast_unlock_path(), ast_verbose(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), ast_frame::frametype, ast_channel::language, LOG_DEBUG, LOG_WARNING, MAX_OTHER_FORMATS, ast_channel::name, option_transmit_silence_during_record, option_verbose, ast_channel::readformat, strsep(), ast_frame::subclass, ast_dsp::totalsilence, and VERBOSE_PREFIX_3.
Referenced by ast_play_and_record(), and play_record_review().
00540 { 00541 int d; 00542 char *fmts; 00543 char comment[256]; 00544 int x, fmtcnt=1, res=-1,outmsg=0; 00545 struct ast_frame *f; 00546 struct ast_filestream *others[MAX_OTHER_FORMATS]; 00547 char *sfmt[MAX_OTHER_FORMATS]; 00548 char *stringp=NULL; 00549 time_t start, end; 00550 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00551 int totalsilence = 0; 00552 int dspsilence = 0; 00553 int rfmt=0; 00554 struct ast_silence_generator *silgen = NULL; 00555 00556 if (silencethreshold < 0) 00557 silencethreshold = global_silence_threshold; 00558 00559 if (maxsilence < 0) 00560 maxsilence = global_maxsilence; 00561 00562 /* barf if no pointer passed to store duration in */ 00563 if (duration == NULL) { 00564 ast_log(LOG_WARNING, "Error play_and_record called without duration pointer\n"); 00565 return -1; 00566 } 00567 00568 ast_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt); 00569 snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name); 00570 00571 if (playfile) { 00572 d = ast_play_and_wait(chan, playfile); 00573 if (d > -1) 00574 d = ast_streamfile(chan, "beep",chan->language); 00575 if (!d) 00576 d = ast_waitstream(chan,""); 00577 if (d < 0) 00578 return -1; 00579 } 00580 00581 fmts = ast_strdupa(fmt); 00582 00583 stringp=fmts; 00584 strsep(&stringp, "|"); 00585 ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts); 00586 sfmt[0] = ast_strdupa(fmts); 00587 00588 while((fmt = strsep(&stringp, "|"))) { 00589 if (fmtcnt > MAX_OTHER_FORMATS - 1) { 00590 ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n"); 00591 break; 00592 } 00593 sfmt[fmtcnt++] = ast_strdupa(fmt); 00594 } 00595 00596 time(&start); 00597 end=start; /* pre-initialize end to be same as start in case we never get into loop */ 00598 for (x=0;x<fmtcnt;x++) { 00599 others[x] = ast_writefile(recordfile, sfmt[x], comment, O_TRUNC, 0, 0700); 00600 ast_verbose( VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, recordfile, sfmt[x], others[x]); 00601 00602 if (!others[x]) { 00603 break; 00604 } 00605 } 00606 00607 if (path) 00608 ast_unlock_path(path); 00609 00610 if (maxsilence > 0) { 00611 sildet = ast_dsp_new(); /* Create the silence detector */ 00612 if (!sildet) { 00613 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00614 return -1; 00615 } 00616 ast_dsp_set_threshold(sildet, silencethreshold); 00617 rfmt = chan->readformat; 00618 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00619 if (res < 0) { 00620 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00621 ast_dsp_free(sildet); 00622 return -1; 00623 } 00624 } 00625 00626 /* Request a video update */ 00627 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00628 00629 if (option_transmit_silence_during_record) 00630 silgen = ast_channel_start_silence_generator(chan); 00631 00632 if (x == fmtcnt) { 00633 /* Loop forever, writing the packets we read to the writer(s), until 00634 we read a # or get a hangup */ 00635 f = NULL; 00636 for(;;) { 00637 res = ast_waitfor(chan, 2000); 00638 if (!res) { 00639 ast_log(LOG_DEBUG, "One waitfor failed, trying another\n"); 00640 /* Try one more time in case of masq */ 00641 res = ast_waitfor(chan, 2000); 00642 if (!res) { 00643 ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name); 00644 res = -1; 00645 } 00646 } 00647 00648 if (res < 0) { 00649 f = NULL; 00650 break; 00651 } 00652 f = ast_read(chan); 00653 if (!f) 00654 break; 00655 if (f->frametype == AST_FRAME_VOICE) { 00656 /* write each format */ 00657 for (x=0;x<fmtcnt;x++) { 00658 res = ast_writestream(others[x], f); 00659 } 00660 00661 /* Silence Detection */ 00662 if (maxsilence > 0) { 00663 dspsilence = 0; 00664 ast_dsp_silence(sildet, f, &dspsilence); 00665 if (dspsilence) 00666 totalsilence = dspsilence; 00667 else 00668 totalsilence = 0; 00669 00670 if (totalsilence > maxsilence) { 00671 /* Ended happily with silence */ 00672 if (option_verbose > 2) 00673 ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); 00674 ast_frfree(f); 00675 res = 'S'; 00676 outmsg=2; 00677 break; 00678 } 00679 } 00680 /* Exit on any error */ 00681 if (res) { 00682 ast_log(LOG_WARNING, "Error writing frame\n"); 00683 ast_frfree(f); 00684 break; 00685 } 00686 } else if (f->frametype == AST_FRAME_VIDEO) { 00687 /* Write only once */ 00688 ast_writestream(others[0], f); 00689 } else if (f->frametype == AST_FRAME_DTMF) { 00690 if (strchr(acceptdtmf, f->subclass)) { 00691 if (option_verbose > 2) 00692 ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); 00693 res = f->subclass; 00694 outmsg = 2; 00695 ast_frfree(f); 00696 break; 00697 } 00698 if (strchr(canceldtmf, f->subclass)) { 00699 if (option_verbose > 2) 00700 ast_verbose(VERBOSE_PREFIX_3 "User cancelled message by pressing %c\n", f->subclass); 00701 res = f->subclass; 00702 outmsg = 0; 00703 ast_frfree(f); 00704 break; 00705 } 00706 } 00707 if (maxtime) { 00708 time(&end); 00709 if (maxtime < (end - start)) { 00710 if (option_verbose > 2) 00711 ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); 00712 outmsg = 2; 00713 res = 't'; 00714 ast_frfree(f); 00715 break; 00716 } 00717 } 00718 ast_frfree(f); 00719 } 00720 if (end == start) time(&end); 00721 if (!f) { 00722 if (option_verbose > 2) 00723 ast_verbose( VERBOSE_PREFIX_3 "User hung up\n"); 00724 res = -1; 00725 outmsg=1; 00726 } 00727 } else { 00728 ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]); 00729 } 00730 00731 if (silgen) 00732 ast_channel_stop_silence_generator(chan, silgen); 00733 00734 *duration = end - start; 00735 00736 for (x=0;x<fmtcnt;x++) { 00737 if (!others[x]) 00738 break; 00739 if (res > 0) { 00740 if (totalsilence) 00741 ast_stream_rewind(others[x], totalsilence-200); 00742 else 00743 ast_stream_rewind(others[x], 200); 00744 } 00745 ast_truncstream(others[x]); 00746 ast_closestream(others[x]); 00747 } 00748 if (rfmt) { 00749 if (ast_set_read_format(chan, rfmt)) { 00750 ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name); 00751 } 00752 } 00753 if (outmsg > 1) { 00754 /* Let them know recording is stopped */ 00755 if(!ast_streamfile(chan, "auth-thankyou", chan->language)) 00756 ast_waitstream(chan, ""); 00757 } 00758 if (sildet) 00759 ast_dsp_free(sildet); 00760 return res; 00761 }
| int ast_play_and_wait | ( | struct ast_channel * | chan, | |
| const char * | fn | |||
| ) |
Play a stream and wait for a digit, returning the digit that was pressed
Definition at line 525 of file app.c.
References AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_channel::language.
Referenced by advanced_options(), ast_play_and_prepend(), ast_play_and_record_full(), ast_record_review(), dial_exec_full(), dialout(), forward_message(), get_folder(), get_folder2(), leave_voicemail(), play_message_category(), play_record_review(), vm_authenticate(), vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pt(), vm_intro_se(), vm_newuser(), vm_options(), vm_play_folder_name(), vm_play_folder_name_gr(), vm_tempgreeting(), and vmauthenticate().
00526 { 00527 int d; 00528 d = ast_streamfile(chan, fn, chan->language); 00529 if (d) 00530 return d; 00531 d = ast_waitstream(chan, AST_DIGIT_ANY); 00532 ast_stopstream(chan); 00533 return d; 00534 }
| char* ast_read_textfile | ( | const char * | file | ) |
Read a file into asterisk
Definition at line 1563 of file app.c.
References ast_log(), free, LOG_WARNING, and malloc.
Referenced by readfile_exec().
01564 { 01565 int fd; 01566 char *output=NULL; 01567 struct stat filesize; 01568 int count=0; 01569 int res; 01570 if(stat(filename,&filesize)== -1){ 01571 ast_log(LOG_WARNING,"Error can't stat %s\n", filename); 01572 return NULL; 01573 } 01574 count=filesize.st_size + 1; 01575 fd = open(filename, O_RDONLY); 01576 if (fd < 0) { 01577 ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno)); 01578 return NULL; 01579 } 01580 output=(char *)malloc(count); 01581 if (output) { 01582 res = read(fd, output, count - 1); 01583 if (res == count - 1) { 01584 output[res] = '\0'; 01585 } else { 01586 ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno)); 01587 free(output); 01588 output = NULL; 01589 } 01590 } else 01591 ast_log(LOG_WARNING, "Out of memory!\n"); 01592 close(fd); 01593 return output; 01594 }
| int ast_record_review | ( | struct ast_channel * | chan, | |
| const char * | playfile, | |||
| const char * | recordfile, | |||
| int | maxtime, | |||
| const char * | fmt, | |||
| int * | duration, | |||
| const char * | path | |||
| ) |
Allow to record message and have a review option
Definition at line 1261 of file app.c.
References AST_DIGIT_ANY, ast_log(), ast_play_and_record(), ast_play_and_wait(), ast_streamfile(), ast_verbose(), ast_waitfordigit(), ast_waitstream(), ast_channel::language, LOG_WARNING, and VERBOSE_PREFIX_3.
Referenced by conf_run().
01262 { 01263 int silencethreshold = 128; 01264 int maxsilence=0; 01265 int res = 0; 01266 int cmd = 0; 01267 int max_attempts = 3; 01268 int attempts = 0; 01269 int recorded = 0; 01270 int message_exists = 0; 01271 /* Note that urgent and private are for flagging messages as such in the future */ 01272 01273 /* barf if no pointer passed to store duration in */ 01274 if (duration == NULL) { 01275 ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n"); 01276 return -1; 01277 } 01278 01279 cmd = '3'; /* Want to start by recording */ 01280 01281 while ((cmd >= 0) && (cmd != 't')) { 01282 switch (cmd) { 01283 case '1': 01284 if (!message_exists) { 01285 /* In this case, 1 is to record a message */ 01286 cmd = '3'; 01287 break; 01288 } else { 01289 ast_streamfile(chan, "vm-msgsaved", chan->language); 01290 ast_waitstream(chan, ""); 01291 cmd = 't'; 01292 return res; 01293 } 01294 case '2': 01295 /* Review */ 01296 ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n"); 01297 ast_streamfile(chan, recordfile, chan->language); 01298 cmd = ast_waitstream(chan, AST_DIGIT_ANY); 01299 break; 01300 case '3': 01301 message_exists = 0; 01302 /* Record */ 01303 if (recorded == 1) 01304 ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n"); 01305 else 01306 ast_verbose(VERBOSE_PREFIX_3 "Recording\n"); 01307 recorded = 1; 01308 cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path); 01309 if (cmd == -1) { 01310 /* User has hung up, no options to give */ 01311 return cmd; 01312 } 01313 if (cmd == '0') { 01314 break; 01315 } else if (cmd == '*') { 01316 break; 01317 } 01318 else { 01319 /* If all is well, a message exists */ 01320 message_exists = 1; 01321 cmd = 0; 01322 } 01323 break; 01324 case '4': 01325 case '5': 01326 case '6': 01327 case '7': 01328 case '8': 01329 case '9': 01330 case '*': 01331 case '#': 01332 cmd = ast_play_and_wait(chan, "vm-sorry"); 01333 break; 01334 default: 01335 if (message_exists) { 01336 cmd = ast_play_and_wait(chan, "vm-review"); 01337 } 01338 else { 01339 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01340 if (!cmd) 01341 cmd = ast_waitfordigit(chan, 600); 01342 } 01343 01344 if (!cmd) 01345 cmd = ast_waitfordigit(chan, 6000); 01346 if (!cmd) { 01347 attempts++; 01348 } 01349 if (attempts > max_attempts) { 01350 cmd = 't'; 01351 } 01352 } 01353 } 01354 if (cmd == 't') 01355 cmd = 0; 01356 return cmd; 01357 }
| void ast_uninstall_vm_functions | ( | void | ) |
Definition at line 242 of file app.c.
References ast_has_voicemail_func, and ast_messagecount_func.
Referenced by unload_module().
00243 { 00244 ast_has_voicemail_func = NULL; 00245 ast_messagecount_func = NULL; 00246 }
| int ast_unlock_path | ( | const char * | path | ) |
Unlock a path
Definition at line 1240 of file app.c.
References ast_log(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, and s.
Referenced by ast_play_and_record_full(), close_mailbox(), copy_message(), count_messages(), last_message_index(), leave_voicemail(), resequence_mailbox(), and save_to_folder().
01241 { 01242 char *s; 01243 int res; 01244 01245 s = alloca(strlen(path) + 10); 01246 if (!s) { 01247 ast_log(LOG_WARNING, "Out of memory!\n"); 01248 return -1; 01249 } 01250 01251 snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock"); 01252 01253 if ((res = unlink(s))) 01254 ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno)); 01255 else 01256 ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path); 01257 01258 return res; 01259 }
| static int ivr_dispatch | ( | struct ast_channel * | chan, | |
| struct ast_ivr_option * | option, | |||
| char * | exten, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 1365 of file app.c.
References ast_ivr_option::action, ast_ivr_option::adata, AST_ACTION_BACKGROUND, AST_ACTION_BACKLIST, AST_ACTION_CALLBACK, AST_ACTION_EXIT, AST_ACTION_MENU, AST_ACTION_NOOP, AST_ACTION_PLAYBACK, AST_ACTION_PLAYLIST, AST_ACTION_REPEAT, AST_ACTION_RESTART, AST_ACTION_TRANSFER, AST_ACTION_UPONE, AST_ACTION_WAITOPTION, AST_DIGIT_ANY, ast_ivr_menu_run_internal(), ast_log(), ast_parseable_goto(), ast_stopstream(), ast_strdupa, ast_streamfile(), ast_waitfordigit(), ast_waitstream(), ast_channel::language, LOG_NOTICE, n, ast_channel::pbx, RES_EXIT, RES_REPEAT, RES_RESTART, RES_UPONE, ast_pbx::rtimeout, and strsep().
Referenced by ast_ivr_menu_run_internal().
01366 { 01367 int res; 01368 int (*ivr_func)(struct ast_channel *, void *); 01369 char *c; 01370 char *n; 01371 01372 switch(option->action) { 01373 case AST_ACTION_UPONE: 01374 return RES_UPONE; 01375 case AST_ACTION_EXIT: 01376 return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff); 01377 case AST_ACTION_REPEAT: 01378 return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff); 01379 case AST_ACTION_RESTART: 01380 return RES_RESTART ; 01381 case AST_ACTION_NOOP: 01382 return 0; 01383 case AST_ACTION_BACKGROUND: 01384 res = ast_streamfile(chan, (char *)option->adata, chan->language); 01385 if (!res) { 01386 res = ast_waitstream(chan, AST_DIGIT_ANY); 01387 } else { 01388 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata); 01389 res = 0; 01390 } 01391 return res; 01392 case AST_ACTION_PLAYBACK: 01393 res = ast_streamfile(chan, (char *)option->adata, chan->language); 01394 if (!res) { 01395 res = ast_waitstream(chan, ""); 01396 } else { 01397 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata); 01398 res = 0; 01399 } 01400 return res; 01401 case AST_ACTION_MENU: 01402 res = ast_ivr_menu_run_internal(chan, (struct ast_ivr_menu *)option->adata, cbdata); 01403 /* Do not pass entry errors back up, treaat ast though ti was an "UPONE" */ 01404 if (res == -2) 01405 res = 0; 01406 return res; 01407 case AST_ACTION_WAITOPTION: 01408 res = ast_waitfordigit(chan, 1000 * (chan->pbx ? chan->pbx->rtimeout : 10)); 01409 if (!res) 01410 return 't'; 01411 return res; 01412 case AST_ACTION_CALLBACK: 01413 ivr_func = option->adata; 01414 res = ivr_func(chan, cbdata); 01415 return res; 01416 case AST_ACTION_TRANSFER: 01417 res = ast_parseable_goto(chan, option->adata); 01418 return 0; 01419 case AST_ACTION_PLAYLIST: 01420 case AST_ACTION_BACKLIST: 01421 res = 0; 01422 c = ast_strdupa(option->adata); 01423 if (c) { 01424 while((n = strsep(&c, ";"))) 01425 if ((res = ast_streamfile(chan, n, chan->language)) || (res = ast_waitstream(chan, (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : ""))) 01426 break; 01427 ast_stopstream(chan); 01428 } 01429 return res; 01430 default: 01431 ast_log(LOG_NOTICE, "Unknown dispatch function %d, ignoring!\n", option->action); 01432 return 0; 01433 }; 01434 return -1; 01435 }
| static void* linear_alloc | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 373 of file app.c.
References linear_state::allowoverride, ast_clear_flag, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), free, LOG_WARNING, ast_channel::name, linear_state::origwfmt, and ast_channel::writeformat.
00374 { 00375 struct linear_state *ls; 00376 /* In this case, params is already malloc'd */ 00377 if (params) { 00378 ls = params; 00379 if (ls->allowoverride) 00380 ast_set_flag(chan, AST_FLAG_WRITE_INT); 00381 else 00382 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 00383 ls->origwfmt = chan->writeformat; 00384 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00385 ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name); 00386 free(ls); 00387 ls = params = NULL; 00388 } 00389 } 00390 return params; 00391 }
| static int linear_generator | ( | struct ast_channel * | chan, | |
| void * | data, | |||
| int | len, | |||
| int | samples | |||
| ) | [static] |
Definition at line 346 of file app.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, ast_frame::datalen, linear_state::fd, ast_frame::frametype, LOG_WARNING, ast_frame::offset, ast_frame::samples, and ast_frame::subclass.
00347 { 00348 struct ast_frame f; 00349 short buf[2048 + AST_FRIENDLY_OFFSET / 2]; 00350 struct linear_state *ls = data; 00351 int res; 00352 len = samples * 2; 00353 if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) { 00354 ast_log(LOG_WARNING, "Can't generate %d bytes of data!\n" ,len); 00355 len = sizeof(buf) - AST_FRIENDLY_OFFSET; 00356 } 00357 memset(&f, 0, sizeof(f)); 00358 res = read(ls->fd, buf + AST_FRIENDLY_OFFSET/2, len); 00359 if (res > 0) { 00360 f.frametype = AST_FRAME_VOICE; 00361 f.subclass = AST_FORMAT_SLINEAR; 00362 f.data = buf + AST_FRIENDLY_OFFSET/2; 00363 f.datalen = res; 00364 f.samples = res / 2; 00365 f.offset = AST_FRIENDLY_OFFSET; 00366 ast_write(chan, &f); 00367 if (res == len) 00368 return 0; 00369 } 00370 return -1; 00371 }
| static void linear_release | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 335 of file app.c.
References ast_log(), ast_set_write_format(), linear_state::autoclose, linear_state::fd, free, LOG_WARNING, ast_channel::name, and linear_state::origwfmt.
00336 { 00337 struct linear_state *ls = params; 00338 if (ls->origwfmt && ast_set_write_format(chan, ls->origwfmt)) { 00339 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, ls->origwfmt); 00340 } 00341 if (ls->autoclose) 00342 close(ls->fd); 00343 free(params); 00344 }
| static int option_exists | ( | struct ast_ivr_menu * | menu, | |
| char * | option | |||
| ) | [static] |
Definition at line 1437 of file app.c.
References ast_ivr_option::option, and ast_ivr_menu::options.
Referenced by ast_ivr_menu_run_internal().
01438 { 01439 int x; 01440 for (x=0;menu->options[x].option;x++) 01441 if (!strcasecmp(menu->options[x].option, option)) 01442 return x; 01443 return -1; 01444 }
| static int option_matchmore | ( | struct ast_ivr_menu * | menu, | |
| char * | option | |||
| ) | [static] |
Definition at line 1446 of file app.c.
References ast_ivr_option::option, and ast_ivr_menu::options.
Referenced by read_newoption().
01447 { 01448 int x; 01449 for (x=0;menu->options[x].option;x++) 01450 if ((!strncasecmp(menu->options[x].option, option, strlen(option))) && 01451 (menu->options[x].option[strlen(option)])) 01452 return x; 01453 return -1; 01454 }
| static int read_newoption | ( | struct ast_channel * | chan, | |
| struct ast_ivr_menu * | menu, | |||
| char * | exten, | |||
| int | maxexten | |||
| ) | [static] |
Definition at line 1456 of file app.c.
References ast_waitfordigit(), ast_pbx::dtimeout, option_matchmore(), and ast_channel::pbx.
Referenced by ast_ivr_menu_run_internal().
01457 { 01458 int res=0; 01459 int ms; 01460 while(option_matchmore(menu, exten)) { 01461 ms = chan->pbx ? chan->pbx->dtimeout : 5000; 01462 if (strlen(exten) >= maxexten - 1) 01463 break; 01464 res = ast_waitfordigit(chan, ms); 01465 if (res < 1) 01466 break; 01467 exten[strlen(exten) + 1] = '\0'; 01468 exten[strlen(exten)] = res; 01469 } 01470 return res > 0 ? 0 : res; 01471 }
int(* ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL [static] |
Referenced by ast_app_has_voicemail(), ast_install_vm_functions(), and ast_uninstall_vm_functions().
int(* ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL [static] |
Referenced by ast_app_messagecount(), ast_install_vm_functions(), and ast_uninstall_vm_functions().
char default_acceptdtmf[] = "#" [static] |
char default_canceldtmf[] = "0" [static] |
int global_maxsilence = 0 [static] |
int global_silence_threshold = 128 [static] |
struct ast_generator linearstream [static] |
1.5.6