![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
app.c File Reference
Definition in file app.c.
#include "asterisk.h"
#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/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 dependency graph for app.c:

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 | |
| static int | __ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf) |
| 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, const 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_group_get_count (const char *group, const char *category) |
| int | ast_app_group_match_get_count (const char *groupmatch, const char *category) |
| int | ast_app_group_set_channel (struct ast_channel *chan, const char *data) |
| int | ast_app_group_split_group (const char *data, char *group, int group_max, char *category, int category_max) |
| int | ast_app_has_voicemail (const char *mailbox, const char *folder) |
| int | ast_app_inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
| int | ast_app_messagecount (const char *context, const char *mailbox, const char *folder) |
| 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, const char *digits, int between) |
| Send DTMF to a channel. | |
| void | ast_install_vm_functions (int(*has_voicemail_func)(const char *mailbox, const char *folder), int(*inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs), int(*messagecount_func)(const char *context, const char *mailbox, const char *folder)) |
| 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) |
| 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_inboxcount_func )(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL |
| static int(* | ast_messagecount_func )(const char *context, const char *mailbox, const char *folder) = NULL |
| static char | default_acceptdtmf [] = "#" |
| static char | default_canceldtmf [] = "" |
| static int | global_maxsilence = 0 |
| static int | global_silence_threshold = 128 |
| static struct ast_generator | linearstream |
|
|
Definition at line 53 of file app.c. Referenced by __ast_play_and_record(). |
|
|
Definition at line 1089 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
|
Definition at line 1090 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
|
Definition at line 1091 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
|
Definition at line 1088 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Optionally play a sound file or a beep, then record audio and video from the channel.
Definition at line 510 of file app.c. References AST_FILE_MODE, ast_log(), ast_play_and_wait(), ast_strdupa, ast_stream_and_wait(), ast_verbose(), ast_writefile(), LOG_DEBUG, LOG_WARNING, MAX_OTHER_FORMATS, option_debug, option_verbose, strsep(), ast_dsp::totalsilence, and VERBOSE_PREFIX_3. Referenced by ast_play_and_prepend(), ast_play_and_record(), and ast_play_and_record_full(). 00511 { 00512 int d = 0; 00513 char *fmts; 00514 char comment[256]; 00515 int x, fmtcnt = 1, res = -1, outmsg = 0; 00516 struct ast_filestream *others[MAX_OTHER_FORMATS]; 00517 char *sfmt[MAX_OTHER_FORMATS]; 00518 char *stringp = NULL; 00519 time_t start, end; 00520 struct ast_dsp *sildet = NULL; /* silence detector dsp */ 00521 int totalsilence = 0; 00522 int rfmt = 0; 00523 struct ast_silence_generator *silgen = NULL; 00524 char prependfile[80]; 00525 00526 if (silencethreshold < 0) 00527 silencethreshold = global_silence_threshold; 00528 00529 if (maxsilence < 0) 00530 maxsilence = global_maxsilence; 00531 00532 /* barf if no pointer passed to store duration in */ 00533 if (duration == NULL) { 00534 ast_log(LOG_WARNING, "Error play_and_record called without duration pointer\n"); 00535 return -1; 00536 } 00537 00538 if (option_debug) 00539 ast_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt); 00540 snprintf(comment, sizeof(comment), "Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name); 00541 00542 if (playfile || beep) { 00543 if (!beep) 00544 d = ast_play_and_wait(chan, playfile); 00545 if (d > -1) 00546 d = ast_stream_and_wait(chan, "beep", ""); 00547 if (d < 0) 00548 return -1; 00549 } 00550 00551 if (prepend) { 00552 ast_copy_string(prependfile, recordfile, sizeof(prependfile)); 00553 strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1); 00554 } 00555 00556 fmts = ast_strdupa(fmt); 00557 00558 stringp = fmts; 00559 strsep(&stringp, "|"); 00560 if (option_debug) 00561 ast_log(LOG_DEBUG, "Recording Formats: sfmts=%s\n", fmts); 00562 sfmt[0] = ast_strdupa(fmts); 00563 00564 while ((fmt = strsep(&stringp, "|"))) { 00565 if (fmtcnt > MAX_OTHER_FORMATS - 1) { 00566 ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n"); 00567 break; 00568 } 00569 sfmt[fmtcnt++] = ast_strdupa(fmt); 00570 } 00571 00572 end = start = time(NULL); /* pre-initialize end to be same as start in case we never get into loop */ 00573 for (x = 0; x < fmtcnt; x++) { 00574 others[x] = ast_writefile(prepend ? prependfile : recordfile, sfmt[x], comment, O_TRUNC, 0, AST_FILE_MODE); 00575 if (option_verbose > 2) 00576 ast_verbose(VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]); 00577 00578 if (!others[x]) 00579 break; 00580 } 00581 00582 if (path) 00583 ast_unlock_path(path); 00584 00585 if (maxsilence > 0) { 00586 sildet = ast_dsp_new(); /* Create the silence detector */ 00587 if (!sildet) { 00588 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00589 return -1; 00590 } 00591 ast_dsp_set_threshold(sildet, silencethreshold); 00592 rfmt = chan->readformat; 00593 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00594 if (res < 0) { 00595 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00596 ast_dsp_free(sildet); 00597 return -1; 00598 } 00599 } 00600 00601 if (!prepend) { 00602 /* Request a video update */ 00603 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00604 00605 if (ast_opt_transmit_silence) 00606 silgen = ast_channel_start_silence_generator(chan); 00607 } 00608 00609 if (x == fmtcnt) { 00610 /* Loop forever, writing the packets we read to the writer(s), until 00611 we read a digit or get a hangup */ 00612 struct ast_frame *f; 00613 for (;;) { 00614 res = ast_waitfor(chan, 2000); 00615 if (!res) { 00616 if (option_debug) 00617 ast_log(LOG_DEBUG, "One waitfor failed, trying another\n"); 00618 /* Try one more time in case of masq */ 00619 res = ast_waitfor(chan, 2000); 00620 if (!res) { 00621 ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name); 00622 res = -1; 00623 } 00624 } 00625 00626 if (res < 0) { 00627 f = NULL; 00628 break; 00629 } 00630 f = ast_read(chan); 00631 if (!f) 00632 break; 00633 if (f->frametype == AST_FRAME_VOICE) { 00634 /* write each format */ 00635 for (x = 0; x < fmtcnt; x++) { 00636 if (prepend && !others[x]) 00637 break; 00638 res = ast_writestream(others[x], f); 00639 } 00640 00641 /* Silence Detection */ 00642 if (maxsilence > 0) { 00643 int dspsilence = 0; 00644 ast_dsp_silence(sildet, f, &dspsilence); 00645 if (dspsilence) 00646 totalsilence = dspsilence; 00647 else 00648 totalsilence = 0; 00649 00650 if (totalsilence > maxsilence) { 00651 /* Ended happily with silence */ 00652 if (option_verbose > 2) 00653 ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); 00654 res = 'S'; 00655 outmsg = 2; 00656 break; 00657 } 00658 } 00659 /* Exit on any error */ 00660 if (res) { 00661 ast_log(LOG_WARNING, "Error writing frame\n"); 00662 break; 00663 } 00664 } else if (f->frametype == AST_FRAME_VIDEO) { 00665 /* Write only once */ 00666 ast_writestream(others[0], f); 00667 } else if (f->frametype == AST_FRAME_DTMF) { 00668 if (prepend) { 00669 /* stop recording with any digit */ 00670 if (option_verbose > 2) 00671 ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); 00672 res = 't'; 00673 outmsg = 2; 00674 break; 00675 } 00676 if (strchr(acceptdtmf, f->subclass)) { 00677 if (option_verbose > 2) 00678 ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); 00679 res = f->subclass; 00680 outmsg = 2; 00681 break; 00682 } 00683 if (strchr(canceldtmf, f->subclass)) { 00684 if (option_verbose > 2) 00685 ast_verbose(VERBOSE_PREFIX_3 "User cancelled message by pressing %c\n", f->subclass); 00686 res = f->subclass; 00687 outmsg = 0; 00688 break; 00689 } 00690 } 00691 if (maxtime) { 00692 end = time(NULL); 00693 if (maxtime < (end - start)) { 00694 if (option_verbose > 2) 00695 ast_verbose(VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); 00696 res = 't'; 00697 outmsg = 2; 00698 break; 00699 } 00700 } 00701 ast_frfree(f); 00702 } 00703 if (!f) { 00704 if (option_verbose > 2) 00705 ast_verbose(VERBOSE_PREFIX_3 "User hung up\n"); 00706 res = -1; 00707 outmsg = 1; 00708 } else { 00709 ast_frfree(f); 00710 } 00711 if (end == start) 00712 end = time(NULL); 00713 } else { 00714 ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]); 00715 } 00716 00717 if (!prepend) { 00718 if (silgen) 00719 ast_channel_stop_silence_generator(chan, silgen); 00720 } 00721 *duration = end - start; 00722 00723 if (!prepend) { 00724 for (x = 0; x < fmtcnt; x++) { 00725 if (!others[x]) 00726 break; 00727 if (res > 0) 00728 ast_stream_rewind(others[x], totalsilence ? totalsilence - 200 : 200); 00729 ast_truncstream(others[x]); 00730 ast_closestream(others[x]); 00731 } 00732 } 00733 00734 if (prepend && outmsg) { 00735 struct ast_filestream *realfiles[MAX_OTHER_FORMATS]; 00736 struct ast_frame *fr; 00737 00738 for (x = 0; x < fmtcnt; x++) { 00739 snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]); 00740 realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0); 00741 if (!others[x] || !realfiles[x]) 00742 break; 00743 ast_stream_rewind(others[x], totalsilence ? totalsilence - 200 : 200); 00744 ast_truncstream(others[x]); 00745 /* add the original file too */ 00746 while ((fr = ast_readframe(realfiles[x]))) { 00747 ast_writestream(others[x], fr); 00748 ast_frfree(fr); 00749 } 00750 ast_closestream(others[x]); 00751 ast_closestream(realfiles[x]); 00752 ast_filerename(prependfile, recordfile, sfmt[x]); 00753 if (option_verbose > 3) 00754 ast_verbose(VERBOSE_PREFIX_4 "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile); 00755 ast_filedelete(prependfile, sfmt[x]); 00756 } 00757 } 00758 if (rfmt && ast_set_read_format(chan, rfmt)) { 00759 ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name); 00760 } 00761 if (outmsg == 2) { 00762 ast_stream_and_wait(chan, "auth-thankyou", ""); 00763 } 00764 if (sildet) 00765 ast_dsp_free(sildet); 00766 return res; 00767 }
|
|
||||||||||||||||||||||||||||
|
Present a dialtone and collect a certain length extension.
Definition at line 63 of file app.c. References ast_get_indication_tone(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), ast_waitfordigit(), ind_tone_zone_sound::data, ast_pbx::dtimeout, LOG_NOTICE, ast_channel::pbx, and ast_channel::zone. Referenced by builtin_atxfer(), and builtin_blindtransfer(). 00064 { 00065 struct ind_tone_zone_sound *ts; 00066 int res=0, x=0; 00067 00068 if (maxlen > size) 00069 maxlen = size; 00070 00071 if (!timeout && chan->pbx) 00072 timeout = chan->pbx->dtimeout; 00073 else if (!timeout) 00074 timeout = 5; 00075 00076 ts = ast_get_indication_tone(chan->zone,"dial"); 00077 if (ts && ts->data[0]) 00078 res = ast_playtones_start(chan, 0, ts->data, 0); 00079 else 00080 ast_log(LOG_NOTICE,"Huh....? no dial for indications?\n"); 00081 00082 for (x = strlen(collect); x < maxlen; ) { 00083 res = ast_waitfordigit(chan, timeout); 00084 if (!ast_ignore_pattern(context, collect)) 00085 ast_playtones_stop(chan); 00086 if (res < 1) 00087 break; 00088 collect[x++] = res; 00089 if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) { 00090 if (collect[x-1] == '#') { 00091 /* Not a valid extension, ending in #, assume the # was to finish dialing */ 00092 collect[x-1] = '\0'; 00093 } 00094 break; 00095 } 00096 } 00097 if (res >= 0) 00098 res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0; 00099 return res; 00100 }
|
|
||||||||||||||||||||||||
|
Plays a stream and gets DTMF data from a channel.
Definition at line 108 of file app.c. References ast_readstring(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_pbx::dtimeout, ast_channel::pbx, ast_pbx::rtimeout, and strsep(). Referenced by __login_exec(). 00109 { 00110 int res = 0, to, fto; 00111 char *front, *filename; 00112 00113 /* XXX Merge with full version? XXX */ 00114 00115 if (maxlen) 00116 s[0] = '\0'; 00117 00118 if (!prompt) 00119 prompt=""; 00120 00121 filename = ast_strdupa(prompt); 00122 while ((front = strsep(&filename, "&"))) { 00123 if (!ast_strlen_zero(front)) { 00124 res = ast_streamfile(c, front, c->language); 00125 if (res) 00126 continue; 00127 } 00128 if (ast_strlen_zero(filename)) { 00129 /* set timeouts for the last prompt */ 00130 fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000; 00131 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000; 00132 00133 if (timeout > 0) 00134 fto = to = timeout; 00135 if (timeout < 0) 00136 fto = to = 1000000000; 00137 } else { 00138 /* there is more than one prompt, so 00139 get rid of the long timeout between 00140 prompts, and make it 50ms */ 00141 fto = 50; 00142 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000; 00143 } 00144 res = ast_readstring(c, s, maxlen, to, fto, "#"); 00145 if (!ast_strlen_zero(s)) 00146 return res; 00147 } 00148 00149 return res; 00150 }
|
|
||||||||||||||||||||||||||||||||
|
Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions.
Definition at line 153 of file app.c. References ast_readstring_full(), and ast_streamfile(). Referenced by handle_getdata(). 00154 { 00155 int res, to, fto; 00156 if (prompt) { 00157 res = ast_streamfile(c, prompt, c->language); 00158 if (res < 0) 00159 return res; 00160 } 00161 fto = 6000; 00162 to = 2000; 00163 if (timeout > 0) 00164 fto = to = timeout; 00165 if (timeout < 0) 00166 fto = to = 1000000000; 00167 res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd); 00168 return res; 00169 }
|
|
||||||||||||
|
Get the current channel count of the specified group and category. Definition at line 832 of file app.c. References ast_channel_unlock, ast_channel_walk_locked(), ast_strlen_zero(), GROUP_CATEGORY_PREFIX, pbx_builtin_getvar_helper(), s, and S_OR. 00833 { 00834 struct ast_channel *chan; 00835 int count = 0; 00836 const char *test; 00837 char cat[80]; 00838 const char *s; 00839 00840 if (ast_strlen_zero(group)) 00841 return 0; 00842 00843 s = S_OR(category, GROUP_CATEGORY_PREFIX); 00844 ast_copy_string(cat, s, sizeof(cat)); 00845 00846 chan = NULL; 00847 while ((chan = ast_channel_walk_locked(chan)) != NULL) { 00848 test = pbx_builtin_getvar_helper(chan, cat); 00849 if (test && !strcasecmp(test, group)) 00850 count++; 00851 ast_channel_unlock(chan); 00852 } 00853 00854 return count; 00855 }
|
|
||||||||||||
|
Get the current channel count of all groups that match the specified pattern and category. Definition at line 857 of file app.c. References ast_channel_unlock, ast_channel_walk_locked(), ast_strlen_zero(), GROUP_CATEGORY_PREFIX, pbx_builtin_getvar_helper(), s, and S_OR. 00858 { 00859 regex_t regexbuf; 00860 struct ast_channel *chan; 00861 int count = 0; 00862 const char *test; 00863 char cat[80]; 00864 const char *s; 00865 00866 if (ast_strlen_zero(groupmatch)) 00867 return 0; 00868 00869 /* if regex compilation fails, return zero matches */ 00870 if (regcomp(®exbuf, groupmatch, REG_EXTENDED | REG_NOSUB)) 00871 return 0; 00872 00873 s = S_OR(category, GROUP_CATEGORY_PREFIX); 00874 ast_copy_string(cat, s, sizeof(cat)); 00875 00876 chan = NULL; 00877 while ((chan = ast_channel_walk_locked(chan)) != NULL) { 00878 test = pbx_builtin_getvar_helper(chan, cat); 00879 if (test && !regexec(®exbuf, test, 0, NULL, 0)) 00880 count++; 00881 ast_channel_unlock(chan); 00882 } 00883 00884 regfree(®exbuf); 00885 00886 return count; 00887 }
|
|
||||||||||||
|
Set the group for a channel, splitting the provided data into group and category, if specified. Definition at line 818 of file app.c. References ast_app_group_split_group(), group, and pbx_builtin_setvar_helper(). 00819 { 00820 int res=0; 00821 char group[80] = ""; 00822 char category[80] = ""; 00823 00824 if (!ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) { 00825 pbx_builtin_setvar_helper(chan, category, group); 00826 } else 00827 res = -1; 00828 00829 return res; 00830 }
|
|
||||||||||||||||||||||||
|
Split a group string into group and category, returning a default category if none is provided. Definition at line 789 of file app.c. References ast_strlen_zero(), and GROUP_CATEGORY_PREFIX. Referenced by ast_app_group_set_channel(). 00790 { 00791 int res=0; 00792 char tmp[256]; 00793 char *grp=NULL, *cat=NULL; 00794 00795 if (!ast_strlen_zero(data)) { 00796 ast_copy_string(tmp, data, sizeof(tmp)); 00797 grp = tmp; 00798 cat = strchr(tmp, '@'); 00799 if (cat) { 00800 *cat = '\0'; 00801 cat++; 00802 } 00803 } 00804 00805 if (!ast_strlen_zero(grp)) 00806 ast_copy_string(group, grp, group_max); 00807 else 00808 res = -1; 00809 00810 if (cat) 00811 snprintf(category, category_max, "%s_%s", GROUP_CATEGORY_PREFIX, cat); 00812 else 00813 ast_copy_string(category, GROUP_CATEGORY_PREFIX, category_max); 00814 00815 return res; 00816 }
|
|
||||||||||||
|
Determine if a given mailbox has any voicemail Definition at line 191 of file app.c. References ast_has_voicemail_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. Referenced by action_mailboxstatus(), and has_voicemail(). 00192 { 00193 static int warned = 0; 00194 if (ast_has_voicemail_func) 00195 return ast_has_voicemail_func(mailbox, folder); 00196 00197 if ((option_verbose > 2) && !warned) { 00198 ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX"); 00199 warned++; 00200 } 00201 return 0; 00202 }
|
|
||||||||||||||||
|
Determine number of new/old messages in a mailbox Definition at line 205 of file app.c. References ast_inboxcount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. Referenced by action_mailboxcount(), sip_send_mwi_to_peer(), and update_registry(). 00206 { 00207 static int warned = 0; 00208 if (newmsgs) 00209 *newmsgs = 0; 00210 if (oldmsgs) 00211 *oldmsgs = 0; 00212 if (ast_inboxcount_func) 00213 return ast_inboxcount_func(mailbox, newmsgs, oldmsgs); 00214 00215 if (!warned && (option_verbose > 2)) { 00216 warned++; 00217 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox); 00218 } 00219 00220 return 0; 00221 }
|
|
||||||||||||||||
|
Determine number of messages in a given mailbox and folder Definition at line 223 of file app.c. References ast_messagecount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. 00224 { 00225 static int warned = 0; 00226 if (ast_messagecount_func) 00227 return ast_messagecount_func(context, mailbox, folder); 00228 00229 if (!warned && (option_verbose > 2)) { 00230 warned++; 00231 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s@%s/%s but voicemail not loaded.\n", mailbox, context, folder); 00232 } 00233 00234 return 0; 00235 }
|
|
||||||||||||||||||||
|
Parses a string containing application options and sets flags/arguments.
Definition at line 1324 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 pbx_builtin_background(), pbx_builtin_resetcdr(), and pbx_builtin_waitexten(). 01325 { 01326 char *s; 01327 int curarg; 01328 unsigned int argloc; 01329 char *arg; 01330 int res = 0; 01331 01332 ast_clear_flag(flags, AST_FLAGS_ALL); 01333 01334 if (!optstr) 01335 return 0; 01336 01337 s = optstr; 01338 while (*s) { 01339 curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */ 01340 ast_set_flag(flags, options[curarg].flag); 01341 argloc = options[curarg].arg_index; 01342 if (*s == '(') { 01343 /* Has argument */ 01344 arg = ++s; 01345 if ((s = strchr(s, ')'))) { 01346 if (argloc) 01347 args[argloc - 1] = arg; 01348 *s++ = '\0'; 01349 } else { 01350 ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg); 01351 res = -1; 01352 break; 01353 } 01354 } else if (argloc) { 01355 args[argloc - 1] = NULL; 01356 } 01357 } 01358 01359 return res; 01360 }
|
|
||||||||||||||||||||
|
Separate a string into arguments in an array.
The array will be completely zeroed by this function before it populates any entries.
Definition at line 889 of file app.c. Referenced by pbx_builtin_setvar(). 00890 { 00891 int argc; 00892 char *scan; 00893 int paren = 0, quote = 0; 00894 00895 if (!buf || !array || !arraylen) 00896 return 0; 00897 00898 memset(array, 0, arraylen * sizeof(*array)); 00899 00900 scan = buf; 00901 00902 for (argc = 0; *scan && (argc < arraylen - 1); argc++) { 00903 array[argc] = scan; 00904 for (; *scan; scan++) { 00905 if (*scan == '(') 00906 paren++; 00907 else if (*scan == ')') { 00908 if (paren) 00909 paren--; 00910 } else if (*scan == '"' && delim != '"') { 00911 quote = quote ? 0 : 1; 00912 /* Remove quote character from argument */ 00913 memmove(scan, scan + 1, strlen(scan)); 00914 scan--; 00915 } else if (*scan == '\\') { 00916 /* Literal character, don't parse */ 00917 memmove(scan, scan + 1, strlen(scan)); 00918 } else if ((*scan == delim) && !paren && !quote) { 00919 *scan++ = '\0'; 00920 break; 00921 } 00922 } 00923 } 00924 00925 if (*scan) 00926 array[argc++] = scan; 00927 00928 return argc; 00929 }
|
|
||||||||||||||||||||||||||||||||||||
|
Stream a file with fast forward, pause, reverse, restart. Definition at line 385 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(), LOG_DEBUG, option_debug, and ast_channel::stream. Referenced by handle_controlstreamfile(). 00389 { 00390 char *breaks = NULL; 00391 char *end = NULL; 00392 int blen = 2; 00393 int res; 00394 long pause_restart_point = 0; 00395 00396 if (stop) 00397 blen += strlen(stop); 00398 if (pause) 00399 blen += strlen(pause); 00400 if (restart) 00401 blen += strlen(restart); 00402 00403 if (blen > 2) { 00404 breaks = alloca(blen + 1); 00405 breaks[0] = '\0'; 00406 if (stop) 00407 strcat(breaks, stop); 00408 if (pause) 00409 strcat(breaks, pause); 00410 if (restart) 00411 strcat(breaks, restart); 00412 } 00413 if (chan->_state != AST_STATE_UP) 00414 res = ast_answer(chan); 00415 00416 if (file) { 00417 if ((end = strchr(file,':'))) { 00418 if (!strcasecmp(end, ":end")) { 00419 *end = '\0'; 00420 end++; 00421 } 00422 } 00423 } 00424 00425 for (;;) { 00426 ast_stopstream(chan); 00427 res = ast_streamfile(chan, file, chan->language); 00428 if (!res) { 00429 if (pause_restart_point) { 00430 ast_seekstream(chan->stream, pause_restart_point, SEEK_SET); 00431 pause_restart_point = 0; 00432 } 00433 else if (end) { 00434 ast_seekstream(chan->stream, 0, SEEK_END); 00435 end = NULL; 00436 }; 00437 res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms); 00438 } 00439 00440 if (res < 1) 00441 break; 00442 00443 /* We go at next loop if we got the restart char */ 00444 if (restart && strchr(restart, res)) { 00445 if (option_debug) 00446 ast_log(LOG_DEBUG, "we'll restart the stream here at next loop\n"); 00447 pause_restart_point = 0; 00448 continue; 00449 } 00450 00451 if (pause && strchr(pause, res)) { 00452 pause_restart_point = ast_tellstream(chan->stream); 00453 for (;;) { 00454 ast_stopstream(chan); 00455 res = ast_waitfordigit(chan, 1000); 00456 if (!res) 00457 continue; 00458 else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res))) 00459 break; 00460 } 00461 if (res == *pause) { 00462 res = 0; 00463 continue; 00464 } 00465 } 00466 00467 if (res == -1) 00468 break; 00469 00470 /* if we get one of our stop chars, return it to the calling function */ 00471 if (stop && strchr(stop, res)) 00472 break; 00473 } 00474 00475 ast_stopstream(chan); 00476 00477 return res; 00478 }
|
|
||||||||||||||||||||
|
Send DTMF to a channel.
Definition at line 237 of file app.c. References ast_autoservice_start(), ast_safe_sleep(), and ast_waitfor(). Referenced by ast_bridge_call(), and misdn_send_digit(). 00238 { 00239 const char *ptr; 00240 int res = 0; 00241 00242 if (!between) 00243 between = 100; 00244 00245 if (peer) 00246 res = ast_autoservice_start(peer); 00247 00248 if (!res) 00249 res = ast_waitfor(chan, 100); 00250 00251 /* ast_waitfor will return the number of remaining ms on success */ 00252 if (res < 0) 00253 return res; 00254 00255 for (ptr = digits; *ptr; ptr++) { 00256 if (*ptr == 'w') { 00257 /* 'w' -- wait half a second */ 00258 if ((res = ast_safe_sleep(chan, 500))) 00259 break; 00260 } else if (strchr("0123456789*#abcdfABCDF", *ptr)) { 00261 /* Character represents valid DTMF */ 00262 if (*ptr == 'f' || *ptr == 'F') { 00263 /* ignore return values if not supported by channel */ 00264 ast_indicate(chan, AST_CONTROL_FLASH); 00265 } else 00266 ast_senddigit(chan, *ptr); 00267 /* pause between digits */ 00268 if ((res = ast_safe_sleep(chan, between))) 00269 break; 00270 } else 00271 ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr); 00272 } 00273 00274 if (peer) { 00275 /* Stop autoservice on the peer channel, but don't overwrite any error condition 00276 that has occurred previously while acting on the primary channel */ 00277 if (ast_autoservice_stop(peer) && !res) 00278 res = -1; 00279 } 00280 00281 return res; 00282 }
|
|
||||||||||||||||
|
Definition at line 175 of file app.c. References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func. 00178 { 00179 ast_has_voicemail_func = has_voicemail_func; 00180 ast_inboxcount_func = inboxcount_func; 00181 ast_messagecount_func = messagecount_func; 00182 }
|
|
||||||||||||||||
|
Runs an IVR menu.
Definition at line 1286 of file app.c. References ast_ivr_menu_run_internal(). 01287 { 01288 int res = ast_ivr_menu_run_internal(chan, menu, cbdata); 01289 /* Hide internal coding */ 01290 return res > 0 ? 0 : res; 01291 }
|
|
||||||||||||||||
|
Definition at line 1199 of file app.c. References AST_DIGIT_ANY, ast_log(), AST_MAX_EXTENSION, exten, ivr_dispatch(), 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(). 01200 { 01201 /* Execute an IVR menu structure */ 01202 int res=0; 01203 int pos = 0; 01204 int retries = 0; 01205 char exten[AST_MAX_EXTENSION] = "s"; 01206 if (option_exists(menu, "s") < 0) { 01207 strcpy(exten, "g"); 01208 if (option_exists(menu, "g") < 0) { 01209 ast_log(LOG_WARNING, "No 's' nor 'g' extension in menu '%s'!\n", menu->title); 01210 return -1; 01211 } 01212 } 01213 while (!res) { 01214 while (menu->options[pos].option) { 01215 if (!strcasecmp(menu->options[pos].option, exten)) { 01216 res = ivr_dispatch(chan, menu->options + pos, exten, cbdata); 01217 if (option_debug) 01218 ast_log(LOG_DEBUG, "IVR Dispatch of '%s' (pos %d) yields %d\n", exten, pos, res); 01219 if (res < 0) 01220 break; 01221 else if (res & RES_UPONE) 01222 return 0; 01223 else if (res & RES_EXIT) 01224 return res; 01225 else if (res & RES_REPEAT) { 01226 int maxretries = res & 0xffff; 01227 if ((res & RES_RESTART) == RES_RESTART) { 01228 retries = 0; 01229 } else 01230 retries++; 01231 if (!maxretries) 01232 maxretries = 3; 01233 if ((maxretries > 0) && (retries >= maxretries)) { 01234 if (option_debug) 01235 ast_log(LOG_DEBUG, "Max retries %d exceeded\n", maxretries); 01236 return -2; 01237 } else { 01238 if (option_exists(menu, "g") > -1) 01239 strcpy(exten, "g"); 01240 else if (option_exists(menu, "s") > -1) 01241 strcpy(exten, "s"); 01242 } 01243 pos = 0; 01244 continue; 01245 } else if (res && strchr(AST_DIGIT_ANY, res)) { 01246 if (option_debug) 01247 ast_log(LOG_DEBUG, "Got start of extension, %c\n", res); 01248 exten[1] = '\0'; 01249 exten[0] = res; 01250 if ((res = read_newoption(chan, menu, exten, sizeof(exten)))) 01251 break; 01252 if (option_exists(menu, exten) < 0) { 01253 if (option_exists(menu, "i")) { 01254 if (option_debug) 01255 ast_log(LOG_DEBUG, "Invalid extension entered, going to 'i'!\n"); 01256 strcpy(exten, "i"); 01257 pos = 0; 01258 continue; 01259 } else { 01260 if (option_debug) 01261 ast_log(LOG_DEBUG, "Aborting on invalid entry, with no 'i' option!\n"); 01262 res = -2; 01263 break; 01264 } 01265 } else { 01266 if (option_debug) 01267 ast_log(LOG_DEBUG, "New existing extension: %s\n", exten); 01268 pos = 0; 01269 continue; 01270 } 01271 } 01272 } 01273 pos++; 01274 } 01275 if (option_debug) 01276 ast_log(LOG_DEBUG, "Stopping option '%s', res is %d\n", exten, res); 01277 pos = 0; 01278 if (!strcasecmp(exten, "s")) 01279 strcpy(exten, "g"); 01280 else 01281 break; 01282 } 01283 return res; 01284 }
|
|
||||||||||||||||||||
|
Stream a filename (or file descriptor) as a generator. Definition at line 356 of file app.c. References ast_activate_generator(), ast_calloc, ast_config_AST_DATA_DIR, ast_log(), ast_strlen_zero(), linear_state::autoclose, linearstream, and LOG_WARNING. 00357 { 00358 struct linear_state *lin; 00359 char tmpf[256]; 00360 int res = -1; 00361 int autoclose = 0; 00362 if (fd < 0) { 00363 if (ast_strlen_zero(filename)) 00364 return -1; 00365 autoclose = 1; 00366 if (filename[0] == '/') 00367 ast_copy_string(tmpf, filename, sizeof(tmpf)); 00368 else 00369 snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", ast_config_AST_DATA_DIR, "sounds", filename); 00370 fd = open(tmpf, O_RDONLY); 00371 if (fd < 0){ 00372 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); 00373 return -1; 00374 } 00375 } 00376 if ((lin = ast_calloc(1, sizeof(*lin)))) { 00377 lin->fd = fd; 00378 lin->allowoverride = allowoverride; 00379 lin->autoclose = autoclose; 00380 res = ast_activate_generator(chan, &linearstream, lin); 00381 } 00382 return res; 00383 }
|
|
|
Lock a filesystem path.
Definition at line 931 of file app.c. References AST_FILE_MODE, AST_LOCK_FAILURE, AST_LOCK_PATH_NOT_FOUND, AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log(), ast_random(), LOG_ERROR, LOG_WARNING, and s. 00932 { 00933 char *s; 00934 char *fs; 00935 int res; 00936 int fd; 00937 int lp = strlen(path); 00938 time_t start; 00939 00940 if (!(s = alloca(lp + 10)) || !(fs = alloca(lp + 20))) { 00941 ast_log(LOG_WARNING, "Out of memory!\n"); 00942 return AST_LOCK_FAILURE; 00943 } 00944 00945 snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, ast_random()); 00946 fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, AST_FILE_MODE); 00947 if (fd < 0) { 00948 ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno)); 00949 return AST_LOCK_PATH_NOT_FOUND; 00950 } 00951 close(fd); 00952 00953 snprintf(s, strlen(path) + 9, "%s/.lock", path); 00954 start = time(NULL); 00955 while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) 00956 usleep(1); 00957 00958 unlink(fs); 00959 00960 if (res) { 00961 ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno)); 00962 return AST_LOCK_TIMEOUT; 00963 } else { 00964 if (option_debug) 00965 ast_log(LOG_DEBUG, "Locked path '%s'\n", path); 00966 return AST_LOCK_SUCCESS; 00967 } 00968 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 Definition at line 782 of file app.c. References __ast_play_and_record(). 00783 { 00784 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf); 00785 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 Definition at line 777 of file app.c. References __ast_play_and_record(). Referenced by ast_record_review(). 00778 { 00779 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf); 00780 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 772 of file app.c. References __ast_play_and_record(), and S_OR. 00773 { 00774 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf)); 00775 }
|
|
||||||||||||
|
Play a stream and wait for a digit, returning the digit that was pressed Definition at line 480 of file app.c. References AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), and ast_waitstream(). Referenced by __ast_play_and_record(), and ast_record_review(). 00481 { 00482 int d; 00483 d = ast_streamfile(chan, fn, chan->language); 00484 if (d) 00485 return d; 00486 d = ast_waitstream(chan, AST_DIGIT_ANY); 00487 ast_stopstream(chan); 00488 return d; 00489 }
|
|
|
Read a file into asterisk Definition at line 1293 of file app.c. References ast_log(), ast_malloc, free, and LOG_WARNING. 01294 { 01295 int fd; 01296 char *output = NULL; 01297 struct stat filesize; 01298 int count = 0; 01299 int res; 01300 if (stat(filename, &filesize) == -1) { 01301 ast_log(LOG_WARNING, "Error can't stat %s\n", filename); 01302 return NULL; 01303 } 01304 count = filesize.st_size + 1; 01305 fd = open(filename, O_RDONLY); 01306 if (fd < 0) { 01307 ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno)); 01308 return NULL; 01309 } 01310 if ((output = ast_malloc(count))) { 01311 res = read(fd, output, count - 1); 01312 if (res == count - 1) { 01313 output[res] = '\0'; 01314 } else { 01315 ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno)); 01316 free(output); 01317 output = NULL; 01318 } 01319 } 01320 close(fd); 01321 return output; 01322 }
|
|
||||||||||||||||||||||||||||||||
|
Allow to record message and have a review option Definition at line 992 of file app.c. References AST_DIGIT_ANY, ast_log(), ast_play_and_record(), ast_play_and_wait(), ast_stream_and_wait(), ast_verbose(), ast_waitfordigit(), LOG_WARNING, silencethreshold, and VERBOSE_PREFIX_3. 00993 { 00994 int silencethreshold = 128; 00995 int maxsilence=0; 00996 int res = 0; 00997 int cmd = 0; 00998 int max_attempts = 3; 00999 int attempts = 0; 01000 int recorded = 0; 01001 int message_exists = 0; 01002 /* Note that urgent and private are for flagging messages as such in the future */ 01003 01004 /* barf if no pointer passed to store duration in */ 01005 if (duration == NULL) { 01006 ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n"); 01007 return -1; 01008 } 01009 01010 cmd = '3'; /* Want to start by recording */ 01011 01012 while ((cmd >= 0) && (cmd != 't')) { 01013 switch (cmd) { 01014 case '1': 01015 if (!message_exists) { 01016 /* In this case, 1 is to record a message */ 01017 cmd = '3'; 01018 break; 01019 } else { 01020 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01021 cmd = 't'; 01022 return res; 01023 } 01024 case '2': 01025 /* Review */ 01026 ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n"); 01027 cmd = ast_stream_and_wait(chan, recordfile, AST_DIGIT_ANY); 01028 break; 01029 case '3': 01030 message_exists = 0; 01031 /* Record */ 01032 if (recorded == 1) 01033 ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n"); 01034 else 01035 ast_verbose(VERBOSE_PREFIX_3 "Recording\n"); 01036 recorded = 1; 01037 cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path); 01038 if (cmd == -1) { 01039 /* User has hung up, no options to give */ 01040 return cmd; 01041 } 01042 if (cmd == '0') { 01043 break; 01044 } else if (cmd == '*') { 01045 break; 01046 } 01047 else { 01048 /* If all is well, a message exists */ 01049 message_exists = 1; 01050 cmd = 0; 01051 } 01052 break; 01053 case '4': 01054 case '5': 01055 case '6': 01056 case '7': 01057 case '8': 01058 case '9': 01059 case '*': 01060 case '#': 01061 cmd = ast_play_and_wait(chan, "vm-sorry"); 01062 break; 01063 default: 01064 if (message_exists) { 01065 cmd = ast_play_and_wait(chan, "vm-review"); 01066 } 01067 else { 01068 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01069 if (!cmd) 01070 cmd = ast_waitfordigit(chan, 600); 01071 } 01072 01073 if (!cmd) 01074 cmd = ast_waitfordigit(chan, 6000); 01075 if (!cmd) { 01076 attempts++; 01077 } 01078 if (attempts > max_attempts) { 01079 cmd = 't'; 01080 } 01081 } 01082 } 01083 if (cmd == 't') 01084 cmd = 0; 01085 return cmd; 01086 }
|
|
|
Definition at line 184 of file app.c. References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func. 00185 { 00186 ast_has_voicemail_func = NULL; 00187 ast_inboxcount_func = NULL; 00188 ast_messagecount_func = NULL; 00189 }
|
|
|
Unlock a path Definition at line 970 of file app.c. References ast_log(), LOG_ERROR, LOG_WARNING, and s. 00971 { 00972 char *s; 00973 int res; 00974 00975 if (!(s = alloca(strlen(path) + 10))) { 00976 ast_log(LOG_WARNING, "Out of memory!\n"); 00977 return -1; 00978 } 00979 00980 snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock"); 00981 00982 if ((res = unlink(s))) 00983 ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno)); 00984 else { 00985 if (option_debug) 00986 ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path); 00987 } 00988 00989 return res; 00990 }
|
|
||||||||||||||||||||
|
Definition at line 1095 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_stream_and_wait(), ast_waitfordigit(), LOG_NOTICE, ast_channel::pbx, RES_EXIT, RES_REPEAT, RES_RESTART, RES_UPONE, ast_pbx::rtimeout, and strsep(). Referenced by ast_ivr_menu_run_internal(). 01096 { 01097 int res; 01098 int (*ivr_func)(struct ast_channel *, void *); 01099 char *c; 01100 char *n; 01101 01102 switch (option->action) { 01103 case AST_ACTION_UPONE: 01104 return RES_UPONE; 01105 case AST_ACTION_EXIT: 01106 return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff); 01107 case AST_ACTION_REPEAT: 01108 return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff); 01109 case AST_ACTION_RESTART: 01110 return RES_RESTART ; 01111 case AST_ACTION_NOOP: 01112 return 0; 01113 case AST_ACTION_BACKGROUND: 01114 res = ast_stream_and_wait(chan, (char *)option->adata, AST_DIGIT_ANY); 01115 if (res < 0) { 01116 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata); 01117 res = 0; 01118 } 01119 return res; 01120 case AST_ACTION_PLAYBACK: 01121 res = ast_stream_and_wait(chan, (char *)option->adata, ""); 01122 if (res < 0) { 01123 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata); 01124 res = 0; 01125 } 01126 return res; 01127 case AST_ACTION_MENU: 01128 res = ast_ivr_menu_run_internal(chan, (struct ast_ivr_menu *)option->adata, cbdata); 01129 /* Do not pass entry errors back up, treaat ast though ti was an "UPONE" */ 01130 if (res == -2) 01131 res = 0; 01132 return res; 01133 case AST_ACTION_WAITOPTION: 01134 res = ast_waitfordigit(chan, 1000 * (chan->pbx ? chan->pbx->rtimeout : 10)); 01135 if (!res) 01136 return 't'; 01137 return res; 01138 case AST_ACTION_CALLBACK: 01139 ivr_func = option->adata; 01140 res = ivr_func(chan, cbdata); 01141 return res; 01142 case AST_ACTION_TRANSFER: 01143 res = ast_parseable_goto(chan, option->adata); 01144 return 0; 01145 case AST_ACTION_PLAYLIST: 01146 case AST_ACTION_BACKLIST: 01147 res = 0; 01148 c = ast_strdupa(option->adata); 01149 while ((n = strsep(&c, ";"))) { 01150 if ((res = ast_stream_and_wait(chan, n, 01151 (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : ""))) 01152 break; 01153 } 01154 ast_stopstream(chan); 01155 return res; 01156 default: 01157 ast_log(LOG_NOTICE, "Unknown dispatch function %d, ignoring!\n", option->action); 01158 return 0; 01159 }; 01160 return -1; 01161 }
|
|
||||||||||||
|
Definition at line 329 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, linear_state::origwfmt, and ast_channel::writeformat. 00330 { 00331 struct linear_state *ls; 00332 /* In this case, params is already malloc'd */ 00333 if (params) { 00334 ls = params; 00335 if (ls->allowoverride) 00336 ast_set_flag(chan, AST_FLAG_WRITE_INT); 00337 else 00338 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 00339 ls->origwfmt = chan->writeformat; 00340 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00341 ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name); 00342 free(ls); 00343 ls = params = NULL; 00344 } 00345 } 00346 return params; 00347 }
|
|
||||||||||||||||||||
|
Definition at line 302 of file app.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), linear_state::fd, and LOG_WARNING. 00303 { 00304 struct ast_frame f; 00305 short buf[2048 + AST_FRIENDLY_OFFSET / 2]; 00306 struct linear_state *ls = data; 00307 int res; 00308 len = samples * 2; 00309 if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) { 00310 ast_log(LOG_WARNING, "Can't generate %d bytes of data!\n" ,len); 00311 len = sizeof(buf) - AST_FRIENDLY_OFFSET; 00312 } 00313 memset(&f, 0, sizeof(f)); 00314 res = read(ls->fd, buf + AST_FRIENDLY_OFFSET/2, len); 00315 if (res > 0) { 00316 f.frametype = AST_FRAME_VOICE; 00317 f.subclass = AST_FORMAT_SLINEAR; 00318 f.data = buf + AST_FRIENDLY_OFFSET/2; 00319 f.datalen = res; 00320 f.samples = res / 2; 00321 f.offset = AST_FRIENDLY_OFFSET; 00322 ast_write(chan, &f); 00323 if (res == len) 00324 return 0; 00325 } 00326 return -1; 00327 }
|
|
||||||||||||
|
Definition at line 291 of file app.c. References ast_log(), ast_set_write_format(), linear_state::autoclose, linear_state::fd, free, LOG_WARNING, and linear_state::origwfmt. 00292 { 00293 struct linear_state *ls = params; 00294 if (ls->origwfmt && ast_set_write_format(chan, ls->origwfmt)) { 00295 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, ls->origwfmt); 00296 } 00297 if (ls->autoclose) 00298 close(ls->fd); 00299 free(params); 00300 }
|
|
||||||||||||
|
Definition at line 1163 of file app.c. References ast_ivr_option::option, and ast_ivr_menu::options. Referenced by ast_ivr_menu_run_internal(). 01164 { 01165 int x; 01166 for (x = 0; menu->options[x].option; x++) 01167 if (!strcasecmp(menu->options[x].option, option)) 01168 return x; 01169 return -1; 01170 }
|
|
||||||||||||
|
Definition at line 1172 of file app.c. References ast_ivr_option::option, and ast_ivr_menu::options. Referenced by read_newoption(). 01173 { 01174 int x; 01175 for (x = 0; menu->options[x].option; x++) 01176 if ((!strncasecmp(menu->options[x].option, option, strlen(option))) && 01177 (menu->options[x].option[strlen(option)])) 01178 return x; 01179 return -1; 01180 }
|
|
||||||||||||||||||||
|
Definition at line 1182 of file app.c. References ast_waitfordigit(), ast_pbx::dtimeout, option_matchmore(), and ast_channel::pbx. Referenced by ast_ivr_menu_run_internal(). 01183 { 01184 int res=0; 01185 int ms; 01186 while (option_matchmore(menu, exten)) { 01187 ms = chan->pbx ? chan->pbx->dtimeout : 5000; 01188 if (strlen(exten) >= maxexten - 1) 01189 break; 01190 res = ast_waitfordigit(chan, ms); 01191 if (res < 1) 01192 break; 01193 exten[strlen(exten) + 1] = '\0'; 01194 exten[strlen(exten)] = res; 01195 } 01196 return res > 0 ? 0 : res; 01197 }
|
|
|
Definition at line 171 of file app.c. Referenced by ast_app_has_voicemail(), ast_install_vm_functions(), and ast_uninstall_vm_functions(). |
|
|
Definition at line 172 of file app.c. Referenced by ast_app_inboxcount(), ast_install_vm_functions(), and ast_uninstall_vm_functions(). |
|
|
Definition at line 173 of file app.c. Referenced by ast_app_messagecount(), ast_install_vm_functions(), and ast_uninstall_vm_functions(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 349 of file app.c. Referenced by ast_linear_stream(). |