#include "asterisk.h"
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
Go to the source code of this file.
Defines | |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT2 "%-10s %-10s %-20s\n" |
#define | FORMAT2 "%-10s %-10s %-20s\n" |
Enumerations | |
enum | file_action { ACTION_EXISTS = 1, ACTION_DELETE, ACTION_RENAME, ACTION_OPEN, ACTION_COPY } |
enum | fsread_res { FSREAD_FAILURE, FSREAD_SUCCESS_SCHED, FSREAD_SUCCESS_NOSCHED } |
enum | wrap_fn { WRAP_OPEN, WRAP_REWRITE } |
Functions | |
int | __ast_format_register (const struct ast_format *f, struct ast_module *mod) |
int | ast_applystream (struct ast_channel *chan, struct ast_filestream *s) |
int | ast_closestream (struct ast_filestream *f) |
int | ast_file_init (void) |
int | ast_filecopy (const char *filename, const char *filename2, const char *fmt) |
int | ast_filedelete (const char *filename, const char *fmt) |
int | ast_fileexists (const char *filename, const char *fmt, const char *preflang) |
static int | ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action) |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries. | |
int | ast_filerename (const char *filename, const char *filename2, const char *fmt) |
int | ast_format_unregister (const char *name) |
static int | ast_fsread_audio (const void *data) |
static int | ast_fsread_video (const void *data) |
static | AST_LIST_HEAD_STATIC (formats, ast_format) |
struct ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
struct ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
struct ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang) |
int | ast_playstream (struct ast_filestream *s) |
static enum fsread_res | ast_readaudio_callback (struct ast_filestream *s) |
struct ast_filestream * | ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
struct ast_frame * | ast_readframe (struct ast_filestream *s) |
static enum fsread_res | ast_readvideo_callback (struct ast_filestream *s) |
int | ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence) |
int | ast_stopstream (struct ast_channel *tmp) |
Stops a stream. | |
int | ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *language, const char *digits) |
int | ast_stream_fastforward (struct ast_filestream *fs, off_t ms) |
int | ast_stream_rewind (struct ast_filestream *fs, off_t ms) |
int | ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang) |
off_t | ast_tellstream (struct ast_filestream *fs) |
int | ast_truncstream (struct ast_filestream *fs) |
int | ast_waitstream (struct ast_channel *c, const char *breakon) |
int | ast_waitstream_exten (struct ast_channel *c, const char *context) |
int | ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms) |
int | ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd) |
struct ast_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
static char * | build_filename (const char *filename, const char *ext) |
construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller. | |
static int | copy (const char *infile, const char *outfile) |
static int | exts_compare (const char *exts, const char *type) |
static int | fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen) |
helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename. | |
static int | fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode) |
static struct ast_filestream * | get_filestream (struct ast_format *fmt, FILE *bfile) |
static int | open_wrapper (struct ast_filestream *s) |
static int | rewrite_wrapper (struct ast_filestream *s, const char *comment) |
static int | show_file_formats (int fd, int argc, char *argv[]) |
static int | show_file_formats_deprecated (int fd, int argc, char *argv[]) |
static int | waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int skip_ms, int audiofd, int cmdfd, const char *context) |
the core of all waitstream() functions | |
Variables | |
int | ast_language_is_prefix |
struct ast_cli_entry | cli_file [] |
struct ast_cli_entry | cli_show_file_formats_deprecated |
char | show_file_formats_usage [] |
Definition in file file.c.
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_inuse(), sip_show_registry(), zap_show_channels(), and zap_show_status().
enum file_action |
Definition at line 342 of file file.c.
00342 { 00343 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00344 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00345 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00346 ACTION_OPEN, 00347 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00348 };
enum fsread_res |
Definition at line 622 of file file.c.
00622 { 00623 FSREAD_FAILURE, 00624 FSREAD_SUCCESS_SCHED, 00625 FSREAD_SUCCESS_NOSCHED, 00626 };
enum wrap_fn |
int __ast_format_register | ( | const struct ast_format * | f, | |
struct ast_module * | mod | |||
) |
Register a new file format capability Adds a format to Asterisk's format abilities. returns 0 on success, -1 on failure
Definition at line 68 of file file.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verbose(), ast_format::buf_size, ast_format::exts, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.
00069 { 00070 struct ast_format *tmp; 00071 00072 if (AST_LIST_LOCK(&formats)) { 00073 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00074 return -1; 00075 } 00076 AST_LIST_TRAVERSE(&formats, tmp, list) { 00077 if (!strcasecmp(f->name, tmp->name)) { 00078 AST_LIST_UNLOCK(&formats); 00079 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00080 return -1; 00081 } 00082 } 00083 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00084 AST_LIST_UNLOCK(&formats); 00085 return -1; 00086 } 00087 *tmp = *f; 00088 tmp->module = mod; 00089 if (tmp->buf_size) { 00090 /* 00091 * Align buf_size properly, rounding up to the machine-specific 00092 * alignment for pointers. 00093 */ 00094 struct _test_align { void *a, *b; } p; 00095 int align = (char *)&p.b - (char *)&p.a; 00096 tmp->buf_size = ((f->buf_size + align - 1)/align)*align; 00097 } 00098 00099 memset(&tmp->list, 0, sizeof(tmp->list)); 00100 00101 AST_LIST_INSERT_HEAD(&formats, tmp, list); 00102 AST_LIST_UNLOCK(&formats); 00103 if (option_verbose > 1) 00104 ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00105 00106 return 0; 00107 }
int ast_applystream | ( | struct ast_channel * | chan, | |
struct ast_filestream * | s | |||
) |
Applys a open stream to a channel.
chan | channel to work | |
s | ast_filestream to apply Returns 0 for success, -1 on failure |
Definition at line 719 of file file.c.
References ast_filestream::owner.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00720 { 00721 s->owner = chan; 00722 return 0; 00723 }
int ast_closestream | ( | struct ast_filestream * | f | ) |
Closes a stream
f | filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure |
Definition at line 762 of file file.c.
References ast_closestream(), AST_FORMAT_MAX_AUDIO, ast_module_unref(), ast_safe_system(), ast_sched_del(), ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_format::module, ast_filestream::orig_chan_name, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_filestream::vfs, ast_channel::vstream, and ast_channel::vstreamid.
Referenced by __ast_play_and_record(), ast_closestream(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_stopstream(), channel_spy(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), record_exec(), recordthread(), and rpt().
00763 { 00764 char *cmd = NULL; 00765 size_t size = 0; 00766 /* Stop a running stream if there is one */ 00767 if (f->owner) { 00768 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00769 f->owner->stream = NULL; 00770 if (f->owner->streamid > -1) 00771 ast_sched_del(f->owner->sched, f->owner->streamid); 00772 f->owner->streamid = -1; 00773 #ifdef HAVE_ZAPTEL 00774 ast_settimeout(f->owner, 0, NULL, NULL); 00775 #endif 00776 } else { 00777 f->owner->vstream = NULL; 00778 if (f->owner->vstreamid > -1) 00779 ast_sched_del(f->owner->sched, f->owner->vstreamid); 00780 f->owner->vstreamid = -1; 00781 } 00782 } 00783 /* destroy the translator on exit */ 00784 if (f->trans) 00785 ast_translator_free_path(f->trans); 00786 00787 if (f->realfilename && f->filename) { 00788 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00789 cmd = alloca(size); 00790 memset(cmd,0,size); 00791 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00792 ast_safe_system(cmd); 00793 } 00794 00795 if (f->filename) 00796 free(f->filename); 00797 if (f->realfilename) 00798 free(f->realfilename); 00799 if (f->fmt->close) 00800 f->fmt->close(f); 00801 fclose(f->f); 00802 if (f->vfs) 00803 ast_closestream(f->vfs); 00804 if (f->orig_chan_name) 00805 free((void *) f->orig_chan_name); 00806 ast_module_unref(f->fmt->module); 00807 free(f); 00808 return 0; 00809 }
int ast_file_init | ( | void | ) |
Initialize file stuff
Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time
Definition at line 1297 of file file.c.
References ast_cli_register_multiple().
Referenced by main().
01298 { 01299 ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry)); 01300 return 0; 01301 }
int ast_filecopy | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
Copies a file
oldname | name of the file you wish to copy (minus extension) | |
newname | name you wish the file to be copied to (minus extension) | |
fmt | the format of the file Copy a given file in a given format, or if fmt is NULL, then do so for all |
Definition at line 839 of file file.c.
References ACTION_COPY, and ast_filehelper().
Referenced by copy_file().
00840 { 00841 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00842 }
int ast_filedelete | ( | const char * | filename, | |
const char * | fmt | |||
) |
Deletes a file
filename | name of the file you wish to delete (minus the extension) | |
fmt | of the file Delete a given file in a given format, or if fmt is NULL, then do so for all |
Definition at line 829 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), conf_run(), leave_voicemail(), play_mailbox_owner(), play_record_review(), and vm_delete().
00830 { 00831 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00832 }
int ast_fileexists | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang | |||
) |
Checks for the existence of a given file
filename | name of the file you wish to check, minus the extension | |
fmt | the format you wish to check (the extension) | |
preflang | (the preferred language you wisht to find the file in) See if a given file exists in a given format. If fmt is NULL, any format is accepted. Returns -1 if file does not exist, non-zero positive otherwise. |
Definition at line 815 of file file.c.
References ast_filestream::buf, and fileexists_core().
Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), and vm_tempgreeting().
00816 { 00817 char *buf; 00818 int buflen; 00819 00820 if (preflang == NULL) 00821 preflang = ""; 00822 buflen = strlen(preflang) + strlen(filename) + 2; /* room for everything */ 00823 buf = alloca(buflen); 00824 if (buf == NULL) 00825 return 0; 00826 return fileexists_core(filename, fmt, preflang, buf, buflen); 00827 }
static int ast_filehelper | ( | const char * | filename, | |
const void * | arg2, | |||
const char * | fmt, | |||
const enum file_action | action | |||
) | [static] |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
Definition at line 359 of file file.c.
References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_MAX_AUDIO, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strdupa, build_filename(), copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, get_filestream(), ast_filestream::lasttimeout, LOG_WARNING, open_wrapper(), s, ast_channel::stream, strsep(), ast_filestream::trans, ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), ast_openvstream(), and fileexists_core().
00360 { 00361 struct ast_format *f; 00362 int res = (action == ACTION_EXISTS) ? 0 : -1; 00363 00364 if (AST_LIST_LOCK(&formats)) { 00365 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00366 return res; 00367 } 00368 /* Check for a specific format */ 00369 AST_LIST_TRAVERSE(&formats, f, list) { 00370 char *stringp, *ext = NULL; 00371 00372 if (fmt && !exts_compare(f->exts, fmt)) 00373 continue; 00374 00375 /* Look for a file matching the supported extensions. 00376 * The file must exist, and for OPEN, must match 00377 * one of the formats supported by the channel. 00378 */ 00379 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00380 while ( (ext = strsep(&stringp, "|")) ) { 00381 struct stat st; 00382 char *fn = build_filename(filename, ext); 00383 00384 if (fn == NULL) 00385 continue; 00386 00387 if ( stat(fn, &st) ) { /* file not existent */ 00388 free(fn); 00389 continue; 00390 } 00391 /* for 'OPEN' we need to be sure that the format matches 00392 * what the channel can process 00393 */ 00394 if (action == ACTION_OPEN) { 00395 struct ast_channel *chan = (struct ast_channel *)arg2; 00396 FILE *bfile; 00397 struct ast_filestream *s; 00398 00399 if ( !(chan->writeformat & f->format) && 00400 !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) { 00401 free(fn); 00402 continue; /* not a supported format */ 00403 } 00404 if ( (bfile = fopen(fn, "r")) == NULL) { 00405 free(fn); 00406 continue; /* cannot open file */ 00407 } 00408 s = get_filestream(f, bfile); 00409 if (!s) { 00410 fclose(bfile); 00411 free(fn); /* cannot allocate descriptor */ 00412 continue; 00413 } 00414 if (open_wrapper(s)) { 00415 fclose(bfile); 00416 free(fn); 00417 free(s); 00418 continue; /* cannot run open on file */ 00419 } 00420 /* ok this is good for OPEN */ 00421 res = 1; /* found */ 00422 s->lasttimeout = -1; 00423 s->fmt = f; 00424 s->trans = NULL; 00425 s->filename = NULL; 00426 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) { 00427 if (chan->stream) 00428 ast_closestream(chan->stream); 00429 chan->stream = s; 00430 } else { 00431 if (chan->vstream) 00432 ast_closestream(chan->vstream); 00433 chan->vstream = s; 00434 } 00435 free(fn); 00436 break; 00437 } 00438 switch (action) { 00439 case ACTION_OPEN: 00440 break; /* will never get here */ 00441 00442 case ACTION_EXISTS: /* return the matching format */ 00443 res |= f->format; 00444 break; 00445 00446 case ACTION_DELETE: 00447 if ( (res = unlink(fn)) ) 00448 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00449 break; 00450 00451 case ACTION_RENAME: 00452 case ACTION_COPY: { 00453 char *nfn = build_filename((const char *)arg2, ext); 00454 if (!nfn) 00455 ast_log(LOG_WARNING, "Out of memory\n"); 00456 else { 00457 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00458 if (res) 00459 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00460 action == ACTION_COPY ? "copy" : "rename", 00461 fn, nfn, strerror(errno)); 00462 free(nfn); 00463 } 00464 } 00465 break; 00466 00467 default: 00468 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00469 } 00470 free(fn); 00471 } 00472 } 00473 AST_LIST_UNLOCK(&formats); 00474 return res; 00475 }
int ast_filerename | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
Renames a file
oldname | the name of the file you wish to act upon (minus the extension) | |
newname | the name you wish to rename the file to (minus the extension) | |
fmt | the format of the file Rename a given file in a given format, or if fmt is NULL, then do so for all Returns -1 on failure |
Definition at line 834 of file file.c.
References ACTION_RENAME, and ast_filehelper().
Referenced by __ast_play_and_record(), ast_monitor_stop(), leave_voicemail(), play_record_review(), and rename_file().
00835 { 00836 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00837 }
int ast_format_unregister | ( | const char * | name | ) |
Unregisters a file format
name | the name of the format you wish to unregister Unregisters a format based on the name of the format. Returns 0 on success, -1 on failure to unregister |
Definition at line 109 of file file.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), free, LOG_WARNING, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by unload_module().
00110 { 00111 struct ast_format *tmp; 00112 int res = -1; 00113 00114 if (AST_LIST_LOCK(&formats)) { 00115 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00116 return -1; 00117 } 00118 AST_LIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00119 if (!strcasecmp(name, tmp->name)) { 00120 AST_LIST_REMOVE_CURRENT(&formats, list); 00121 free(tmp); 00122 res = 0; 00123 } 00124 } 00125 AST_LIST_TRAVERSE_SAFE_END 00126 AST_LIST_UNLOCK(&formats); 00127 00128 if (!res) { 00129 if (option_verbose > 1) 00130 ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name); 00131 } else 00132 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00133 00134 return res; 00135 }
static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 667 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00668 { 00669 struct ast_filestream *fs = (struct ast_filestream *)data; 00670 enum fsread_res res; 00671 00672 res = ast_readaudio_callback(fs); 00673 00674 if (res == FSREAD_SUCCESS_SCHED) 00675 return 1; 00676 00677 return 0; 00678 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 706 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00707 { 00708 struct ast_filestream *fs = (struct ast_filestream *)data; 00709 enum fsread_res res; 00710 00711 res = ast_readvideo_callback(fs); 00712 00713 if (res == FSREAD_SUCCESS_SCHED) 00714 return 1; 00715 00716 return 0; 00717 }
static AST_LIST_HEAD_STATIC | ( | formats | , | |
ast_format | ||||
) | [static] |
struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) | [read] |
Opens stream for use in seeking, playing
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 537 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00538 { 00539 return ast_openstream_full(chan, filename, preflang, 0); 00540 }
struct ast_filestream* ast_openstream_full | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang, | |||
int | asis | |||
) | [read] |
Opens stream for use in seeking, playing
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use | |
asis | if set, don't clear generators Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 542 of file file.c.
References ACTION_OPEN, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), ast_filestream::buf, fileexists_core(), ast_channel::generator, LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.
Referenced by ast_moh_files_next(), ast_openstream(), channel_spy(), and gen_nextfile().
00543 { 00544 /* 00545 * Use fileexists_core() to find a file in a compatible 00546 * language and format, set up a suitable translator, 00547 * and open the stream. 00548 */ 00549 int fmts, res, buflen; 00550 char *buf; 00551 00552 if (!asis) { 00553 /* do this first, otherwise we detect the wrong writeformat */ 00554 ast_stopstream(chan); 00555 if (chan->generator) 00556 ast_deactivate_generator(chan); 00557 } 00558 if (preflang == NULL) 00559 preflang = ""; 00560 buflen = strlen(preflang) + strlen(filename) + 2; 00561 buf = alloca(buflen); 00562 if (buf == NULL) 00563 return NULL; 00564 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00565 if (fmts > 0) 00566 fmts &= AST_FORMAT_AUDIO_MASK; 00567 if (fmts < 1) { 00568 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00569 return NULL; 00570 } 00571 chan->oldwriteformat = chan->writeformat; 00572 /* Set the channel to a format we can work with */ 00573 res = ast_set_write_format(chan, fmts); 00574 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00575 if (res >= 0) 00576 return chan->stream; 00577 return NULL; 00578 }
struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) | [read] |
Opens stream for use in seeking, playing
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 580 of file file.c.
References ACTION_OPEN, ast_filehelper(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_getformatname(), ast_log(), ast_filestream::buf, fileexists_core(), fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00581 { 00582 /* As above, but for video. But here we don't have translators 00583 * so we must enforce a format. 00584 */ 00585 unsigned int format; 00586 char *buf; 00587 int buflen; 00588 00589 if (preflang == NULL) 00590 preflang = ""; 00591 buflen = strlen(preflang) + strlen(filename) + 2; 00592 buf = alloca(buflen); 00593 if (buf == NULL) 00594 return NULL; 00595 00596 for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) { 00597 int fd; 00598 const char *fmt; 00599 00600 if (!(chan->nativeformats & format)) 00601 continue; 00602 fmt = ast_getformatname(format); 00603 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00604 continue; 00605 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00606 if (fd >= 0) 00607 return chan->vstream; 00608 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00609 } 00610 return NULL; 00611 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
play a open stream on a channel.
s | filestream to play Returns 0 for success, -1 on failure |
Definition at line 725 of file file.c.
References AST_FORMAT_MAX_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, ast_format::format, and FSREAD_FAILURE.
Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00726 { 00727 enum fsread_res res; 00728 00729 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00730 res = ast_readaudio_callback(s); 00731 else 00732 res = ast_readvideo_callback(s); 00733 00734 return (res == FSREAD_FAILURE) ? -1 : 0; 00735 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 630 of file file.c.
References ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), ast_filestream::fmt, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::orig_chan_name, ast_filestream::owner, ast_format::read, ast_channel::sched, ast_channel::streamid, and ast_channel::timingfd.
Referenced by ast_fsread_audio(), and ast_playstream().
00631 { 00632 int whennext = 0; 00633 00634 while (!whennext) { 00635 struct ast_frame *fr; 00636 00637 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) 00638 goto return_failure; 00639 00640 fr = s->fmt->read(s, &whennext); 00641 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00642 if (fr) 00643 ast_log(LOG_WARNING, "Failed to write frame\n"); 00644 goto return_failure; 00645 } 00646 } 00647 if (whennext != s->lasttimeout) { 00648 #ifdef HAVE_ZAPTEL 00649 if (s->owner->timingfd > -1) 00650 ast_settimeout(s->owner, whennext, ast_fsread_audio, s); 00651 else 00652 #endif 00653 s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_fsread_audio, s); 00654 s->lasttimeout = whennext; 00655 return FSREAD_SUCCESS_NOSCHED; 00656 } 00657 return FSREAD_SUCCESS_SCHED; 00658 00659 return_failure: 00660 s->owner->streamid = -1; 00661 #ifdef HAVE_ZAPTEL 00662 ast_settimeout(s->owner, 0, NULL, NULL); 00663 #endif 00664 return FSREAD_FAILURE; 00665 }
struct ast_filestream* ast_readfile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) | [read] |
Starts reading from a file
filename | the name of the file to read from | |
type | format of file you wish to read from | |
comment | comment to go with | |
flags | file flags | |
check | (unimplemented, hence negligible) | |
mode | Open mode Open an incoming file stream. flags are flags for the open() command, and if check is non-zero, then it will not read a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 875 of file file.c.
References ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), strdup, ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), cli_audio_convert(), and cli_audio_convert_deprecated().
00876 { 00877 FILE *bfile; 00878 struct ast_format *f; 00879 struct ast_filestream *fs = NULL; 00880 char *fn; 00881 00882 if (AST_LIST_LOCK(&formats)) { 00883 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00884 return NULL; 00885 } 00886 00887 AST_LIST_TRAVERSE(&formats, f, list) { 00888 fs = NULL; 00889 if (!exts_compare(f->exts, type)) 00890 continue; 00891 00892 fn = build_filename(filename, type); 00893 errno = 0; 00894 bfile = fopen(fn, "r"); 00895 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || 00896 open_wrapper(fs) ) { 00897 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00898 if (fs) 00899 ast_free(fs); 00900 if (bfile) 00901 fclose(bfile); 00902 free(fn); 00903 continue; 00904 } 00905 /* found it */ 00906 fs->trans = NULL; 00907 fs->fmt = f; 00908 fs->flags = flags; 00909 fs->mode = mode; 00910 fs->filename = strdup(filename); 00911 fs->vfs = NULL; 00912 break; 00913 } 00914 00915 AST_LIST_UNLOCK(&formats); 00916 if (!fs) 00917 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00918 00919 return fs; 00920 }
struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) | [read] |
Read a frame from a filestream
s | ast_filestream to act on Returns a frame or NULL if read failed |
Definition at line 613 of file file.c.
References f, ast_filestream::fmt, and ast_format::read.
Referenced by __ast_play_and_record(), channel_spy(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().
00614 { 00615 struct ast_frame *f = NULL; 00616 int whennext = 0; 00617 if (s && s->fmt) 00618 f = s->fmt->read(s, &whennext); 00619 return f; 00620 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 682 of file file.c.
References ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), ast_filestream::fmt, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, ast_format::read, ast_channel::sched, and ast_channel::vstreamid.
Referenced by ast_fsread_video(), and ast_playstream().
00683 { 00684 int whennext = 0; 00685 00686 while (!whennext) { 00687 struct ast_frame *fr = s->fmt->read(s, &whennext); 00688 if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */ 00689 if (fr) 00690 ast_log(LOG_WARNING, "Failed to write frame\n"); 00691 s->owner->vstreamid = -1; 00692 return FSREAD_FAILURE; 00693 } 00694 } 00695 00696 if (whennext != s->lasttimeout) { 00697 s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext / 8, 00698 ast_fsread_video, s); 00699 s->lasttimeout = whennext; 00700 return FSREAD_SUCCESS_NOSCHED; 00701 } 00702 00703 return FSREAD_SUCCESS_SCHED; 00704 }
int ast_seekstream | ( | struct ast_filestream * | fs, | |
off_t | sample_offset, | |||
int | whence | |||
) |
Seeks into stream
fs | ast_filestream to perform seek on | |
sample_offset | numbers of samples to seek | |
whence | SEEK_SET, SEEK_CUR, SEEK_END Returns 0 for success, or -1 for error |
Definition at line 737 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by __ast_read(), ast_control_streamfile(), ast_moh_files_next(), ast_stream_fastforward(), ast_stream_rewind(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_stopstream | ( | struct ast_channel * | c | ) |
Stops a stream.
c | The channel you wish to stop playback on |
0 | always |
Definition at line 137 of file file.c.
References ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_log(), ast_set_write_format(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::vstream.
Referenced by ast_adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), record_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00138 { 00139 ast_channel_lock(tmp); 00140 00141 /* Stop a running stream if there is one */ 00142 if (tmp->stream) { 00143 ast_closestream(tmp->stream); 00144 tmp->stream = NULL; 00145 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00146 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00147 } 00148 /* Stop the video stream too */ 00149 if (tmp->vstream != NULL) { 00150 ast_closestream(tmp->vstream); 00151 tmp->vstream = NULL; 00152 } 00153 00154 ast_channel_unlock(tmp); 00155 00156 return 0; 00157 }
int ast_stream_and_wait | ( | struct ast_channel * | chan, | |
const char * | file, | |||
const char * | language, | |||
const char * | digits | |||
) |
Definition at line 1216 of file file.c.
References ast_streamfile(), ast_strlen_zero(), and ast_waitstream().
Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), directory_exec(), invent_message(), ivr_dispatch(), leave_voicemail(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().
01218 { 01219 int res = 0; 01220 if (!ast_strlen_zero(file)) { 01221 res = ast_streamfile(chan, file, language); 01222 if (!res) 01223 res = ast_waitstream(chan, digits); 01224 } 01225 return res; 01226 }
int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Fast forward stream ms
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 752 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00753 { 00754 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00755 }
int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Rewind stream ms
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 757 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), record_exec(), and waitstream_core().
00758 { 00759 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00760 }
int ast_streamfile | ( | struct ast_channel * | c, | |
const char * | filename, | |||
const char * | preflang | |||
) |
Streams a file
c | channel to stream the file to | |
filename | the name of the file you wish to stream, minus the extension | |
preflang | the preferred language you wish to have the file streamed to you in Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel Also, it will stop any existing streams on the channel. Returns 0 on success, or -1 on failure. |
Definition at line 844 of file file.c.
References ast_applystream(), AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_strdup, ast_test_flag, ast_verbose(), errno, ast_filestream::fmt, fmt, ast_format::format, LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_verbose, ast_filestream::orig_chan_name, VERBOSE_PREFIX_3, and ast_filestream::vfs.
Referenced by __login_exec(), agent_call(), app_exec(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), ast_retrieve_call(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_ge(), ast_say_date_gr(), ast_say_date_nl(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), auth_exec(), autoanswer_exec(), background_detect_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().
00845 { 00846 struct ast_filestream *fs; 00847 struct ast_filestream *vfs=NULL; 00848 char fmt[256]; 00849 00850 fs = ast_openstream(chan, filename, preflang); 00851 if (fs) 00852 vfs = ast_openvstream(chan, filename, preflang); 00853 if (vfs) 00854 ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00855 if (fs){ 00856 int res; 00857 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00858 fs->orig_chan_name = ast_strdup(chan->name); 00859 if (ast_applystream(chan, fs)) 00860 return -1; 00861 if (vfs && ast_applystream(chan, vfs)) 00862 return -1; 00863 res = ast_playstream(fs); 00864 if (!res && vfs) 00865 res = ast_playstream(vfs); 00866 if (option_verbose > 2) 00867 ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default"); 00868 00869 return res; 00870 } 00871 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00872 return -1; 00873 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream
fs | fs to act on Returns a long as a sample offset into stream |
Definition at line 747 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by __ast_play_and_record(), ast_control_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_truncstream | ( | struct ast_filestream * | fs | ) |
Trunc stream at current location
fs | filestream to act on Returns 0 for success, or -1 for error |
Definition at line 742 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by __ast_play_and_record(), handle_recordfile(), and record_exec().
int ast_waitstream | ( | struct ast_channel * | c, | |
const char * | breakon | |||
) |
Waits for a stream to stop or digit to be pressed
c | channel to waitstream on | |
breakon | string of DTMF digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1189 of file file.c.
References waitstream_core().
Referenced by __login_exec(), agent_call(), app_exec(), ast_play_and_wait(), ast_retrieve_call(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_ge(), ast_say_date_gr(), ast_say_date_nl(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), auth_exec(), autoanswer_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), and wait_file().
01190 { 01191 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01192 }
int ast_waitstream_exten | ( | struct ast_channel * | c, | |
const char * | context | |||
) |
Waits for a stream to stop or digit matching a valid one digit exten to be pressed
c | channel to waitstream on | |
context | string of context to match digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a valid extension digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1200 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01201 { 01202 /* Waitstream, with return in the case of a valid 1 digit extension */ 01203 /* in the current or specified context being pressed */ 01204 01205 if (!context) 01206 context = c->context; 01207 return waitstream_core(c, NULL, NULL, NULL, 0, 01208 -1, -1, context); 01209 }
int ast_waitstream_fr | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | rewind, | |||
int | ms | |||
) |
Same as waitstream but allows stream to be forwarded or rewound
c | channel to waitstream on | |
breakon | string of DTMF digits to break upon | |
forward | DTMF digit to fast forward upon | |
rewind | DTMF digit to rewind upon | |
ms | How many miliseconds to skip forward/back Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1183 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01184 { 01185 return waitstream_core(c, breakon, forward, rewind, ms, 01186 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01187 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1194 of file file.c.
References waitstream_core().
Referenced by ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().
01195 { 01196 return waitstream_core(c, breakon, NULL, NULL, 0, 01197 audiofd, cmdfd, NULL /* no context */); 01198 }
struct ast_filestream* ast_writefile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) | [read] |
Starts writing a file
filename | the name of the file to write to | |
type | format of file you wish to write out to | |
comment | comment to go with | |
flags | output file flags | |
check | (unimplemented, hence negligible) | |
mode | Open mode Create an outgoing file stream. oflags are flags for the open() command, and if check is non-zero, then it will not write a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 922 of file file.c.
References ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_opt_cache_record_files, ast_strdupa, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, strdup, ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().
00923 { 00924 int fd, myflags = 0; 00925 /* compiler claims this variable can be used before initialization... */ 00926 FILE *bfile = NULL; 00927 struct ast_format *f; 00928 struct ast_filestream *fs = NULL; 00929 char *buf = NULL; 00930 size_t size = 0; 00931 int format_found = 0; 00932 00933 if (AST_LIST_LOCK(&formats)) { 00934 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00935 return NULL; 00936 } 00937 00938 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00939 /* We really can't use O_APPEND as it will break WAV header updates */ 00940 if (flags & O_APPEND) { 00941 flags &= ~O_APPEND; 00942 } else { 00943 myflags = O_TRUNC; 00944 } 00945 00946 myflags |= O_WRONLY | O_CREAT; 00947 00948 /* XXX need to fix this - we should just do the fopen, 00949 * not open followed by fdopen() 00950 */ 00951 AST_LIST_TRAVERSE(&formats, f, list) { 00952 char *fn, *orig_fn = NULL; 00953 if (fs) 00954 break; 00955 00956 if (!exts_compare(f->exts, type)) 00957 continue; 00958 else 00959 format_found = 1; 00960 00961 fn = build_filename(filename, type); 00962 fd = open(fn, flags | myflags, mode); 00963 if (fd > -1) { 00964 /* fdopen() the resulting file stream */ 00965 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00966 if (!bfile) { 00967 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00968 close(fd); 00969 fd = -1; 00970 } 00971 } 00972 00973 if (ast_opt_cache_record_files && (fd > -1)) { 00974 char *c; 00975 00976 fclose(bfile); /* this also closes fd */ 00977 /* 00978 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 00979 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 00980 */ 00981 orig_fn = ast_strdupa(fn); 00982 for (c = fn; *c; c++) 00983 if (*c == '/') 00984 *c = '_'; 00985 00986 size = strlen(fn) + strlen(record_cache_dir) + 2; 00987 buf = alloca(size); 00988 strcpy(buf, record_cache_dir); 00989 strcat(buf, "/"); 00990 strcat(buf, fn); 00991 free(fn); 00992 fn = buf; 00993 fd = open(fn, flags | myflags, mode); 00994 if (fd > -1) { 00995 /* fdopen() the resulting file stream */ 00996 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00997 if (!bfile) { 00998 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00999 close(fd); 01000 fd = -1; 01001 } 01002 } 01003 } 01004 if (fd > -1) { 01005 errno = 0; 01006 fs = get_filestream(f, bfile); 01007 if (!fs || rewrite_wrapper(fs, comment)) { 01008 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01009 close(fd); 01010 if (orig_fn) { 01011 unlink(fn); 01012 unlink(orig_fn); 01013 } 01014 if (fs) 01015 ast_free(fs); 01016 fs = NULL; 01017 continue; 01018 } 01019 fs->trans = NULL; 01020 fs->fmt = f; 01021 fs->flags = flags; 01022 fs->mode = mode; 01023 if (orig_fn) { 01024 fs->realfilename = strdup(orig_fn); 01025 fs->filename = strdup(fn); 01026 } else { 01027 fs->realfilename = NULL; 01028 fs->filename = strdup(filename); 01029 } 01030 fs->vfs = NULL; 01031 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01032 f->seek(fs, 0, SEEK_END); 01033 } else if (errno != EEXIST) { 01034 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01035 if (orig_fn) 01036 unlink(orig_fn); 01037 } 01038 /* if buf != NULL then fn is already free and pointing to it */ 01039 if (!buf) 01040 free(fn); 01041 } 01042 01043 AST_LIST_UNLOCK(&formats); 01044 01045 if (!format_found) 01046 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01047 01048 return fs; 01049 }
int ast_writestream | ( | struct ast_filestream * | fs, | |
struct ast_frame * | f | |||
) |
Writes a frame to a stream
fs | filestream to write to | |
f | frame to write to the filestream Send a frame to a filestream -- note: does NOT free the frame, call ast_frfree manually Returns 0 on success, -1 on failure. |
Definition at line 159 of file file.c.
References AST_FORMAT_MAX_AUDIO, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_DEBUG, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.
Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().
00160 { 00161 int res = -1; 00162 int alt = 0; 00163 if (f->frametype == AST_FRAME_VIDEO) { 00164 if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) { 00165 /* This is the audio portion. Call the video one... */ 00166 if (!fs->vfs && fs->filename) { 00167 const char *type = ast_getformatname(f->subclass & ~0x1); 00168 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00169 ast_log(LOG_DEBUG, "Opened video output file\n"); 00170 } 00171 if (fs->vfs) 00172 return ast_writestream(fs->vfs, f); 00173 /* else ignore */ 00174 return 0; 00175 } else { 00176 /* Might / might not have mark set */ 00177 alt = 1; 00178 } 00179 } else if (f->frametype != AST_FRAME_VOICE) { 00180 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00181 return -1; 00182 } 00183 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00184 res = fs->fmt->write(fs, f); 00185 if (res < 0) 00186 ast_log(LOG_WARNING, "Natural write failed\n"); 00187 else if (res > 0) 00188 ast_log(LOG_WARNING, "Huh??\n"); 00189 } else { 00190 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00191 the one we've setup a translator for, we do the "wrong thing" XXX */ 00192 if (fs->trans && f->subclass != fs->lastwriteformat) { 00193 ast_translator_free_path(fs->trans); 00194 fs->trans = NULL; 00195 } 00196 if (!fs->trans) 00197 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00198 if (!fs->trans) 00199 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00200 fs->fmt->name, ast_getformatname(f->subclass)); 00201 else { 00202 struct ast_frame *trf; 00203 fs->lastwriteformat = f->subclass; 00204 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00205 trf = ast_translate(fs->trans, f, 0); 00206 if (trf) { 00207 res = fs->fmt->write(fs, trf); 00208 if (res) 00209 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00210 } else 00211 res = 0; 00212 } 00213 } 00214 return res; 00215 }
static char* build_filename | ( | const char * | filename, | |
const char * | ext | |||
) | [static] |
construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
Definition at line 260 of file file.c.
References asprintf, and ast_config_AST_DATA_DIR.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00261 { 00262 char *fn = NULL; 00263 00264 if (!strcmp(ext, "wav49")) 00265 ext = "WAV"; 00266 00267 if (filename[0] == '/') 00268 asprintf(&fn, "%s.%s", filename, ext); 00269 else 00270 asprintf(&fn, "%s/sounds/%s.%s", 00271 ast_config_AST_DATA_DIR, filename, ext); 00272 return fn; 00273 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 217 of file file.c.
References ast_log(), errno, len, and LOG_WARNING.
Referenced by action_getvar(), ast_filehelper(), copy_file(), and iax2_register().
00218 { 00219 int ifd, ofd, len; 00220 char buf[4096]; /* XXX make it lerger. */ 00221 00222 if ((ifd = open(infile, O_RDONLY)) < 0) { 00223 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00224 return -1; 00225 } 00226 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { 00227 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00228 close(ifd); 00229 return -1; 00230 } 00231 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00232 int res; 00233 if (len < 0) { 00234 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00235 break; 00236 } 00237 /* XXX handle partial writes */ 00238 res = write(ofd, buf, len); 00239 if (res != len) { 00240 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00241 len = -1; /* error marker */ 00242 break; 00243 } 00244 } 00245 close(ifd); 00246 close(ofd); 00247 if (len < 0) { 00248 unlink(outfile); 00249 return -1; /* error */ 00250 } 00251 return 0; /* success */ 00252 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 277 of file file.c.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00278 { 00279 char tmp[256]; 00280 char *stringp = tmp, *ext; 00281 00282 ast_copy_string(tmp, exts, sizeof(tmp)); 00283 while ((ext = strsep(&stringp, "|"))) { 00284 if (!strcmp(ext, type)) 00285 return 1; 00286 } 00287 00288 return 0; 00289 }
static int fileexists_core | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Definition at line 488 of file file.c.
References ACTION_EXISTS, ast_filehelper(), ast_log(), LOG_WARNING, and offset.
Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().
00490 { 00491 int res = -1; 00492 int langlen; /* length of language string */ 00493 const char *c = strrchr(filename, '/'); 00494 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00495 00496 if (preflang == NULL) 00497 preflang = ""; 00498 langlen = strlen(preflang); 00499 00500 if (buflen < langlen + strlen(filename) + 2) { 00501 ast_log(LOG_WARNING, "buffer too small\n"); 00502 buf[0] = '\0'; /* set to empty */ 00503 buf = alloca(langlen + strlen(filename) + 2); /* room for everything */ 00504 } 00505 if (buf == NULL) 00506 return 0; 00507 buf[0] = '\0'; 00508 for (;;) { 00509 if (ast_language_is_prefix) { /* new layout */ 00510 if (langlen) { 00511 strcpy(buf, preflang); 00512 buf[langlen] = '/'; 00513 strcpy(buf + langlen + 1, filename); 00514 } else 00515 strcpy(buf, filename); /* first copy the full string */ 00516 } else { /* old layout */ 00517 strcpy(buf, filename); /* first copy the full string */ 00518 if (langlen) { 00519 /* insert the language and suffix if needed */ 00520 strcpy(buf + offset, preflang); 00521 sprintf(buf + offset + langlen, "/%s", filename + offset); 00522 } 00523 } 00524 res = ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00525 if (res > 0) /* found format */ 00526 break; 00527 if (langlen == 0) /* no more formats */ 00528 break; 00529 if (preflang[langlen] == '_') /* we are on the local suffix */ 00530 langlen = 0; /* try again with no language */ 00531 else 00532 langlen = (c = strchr(preflang, '_')) ? c - preflang : 0; 00533 } 00534 return res; 00535 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 315 of file file.c.
References ast_log(), ast_module_ref(), f, ast_filestream::fmt, LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, WRAP_OPEN, and WRAP_REWRITE.
Referenced by open_wrapper(), and rewrite_wrapper().
00316 { 00317 struct ast_format *f = s->fmt; 00318 int ret = -1; 00319 00320 if (mode == WRAP_OPEN && f->open && f->open(s)) 00321 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00322 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00323 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00324 else { 00325 /* preliminary checks succeed. update usecount */ 00326 ast_module_ref(f->module); 00327 ret = 0; 00328 } 00329 return ret; 00330 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static, read] |
Definition at line 291 of file file.c.
References ast_filestream::_private, ast_calloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, ast_filestream::fmt, ast_filestream::fr, ast_format::name, s, and ast_frame::src.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00292 { 00293 struct ast_filestream *s; 00294 00295 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00296 if ( (s = ast_calloc(1, l)) == NULL) 00297 return NULL; 00298 s->fmt = fmt; 00299 s->f = bfile; 00300 00301 if (fmt->desc_size) 00302 s->_private = ((char *)(s+1)) + fmt->buf_size; 00303 if (fmt->buf_size) 00304 s->buf = (char *)(s+1); 00305 s->fr.src = fmt->name; 00306 return s; 00307 }
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 337 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00338 { 00339 return fn_wrapper(s, NULL, WRAP_OPEN); 00340 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 332 of file file.c.
References fn_wrapper(), and WRAP_REWRITE.
Referenced by ast_writefile().
00333 { 00334 return fn_wrapper(s, comment, WRAP_REWRITE); 00335 }
static int show_file_formats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1228 of file file.c.
References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01229 { 01230 #define FORMAT "%-10s %-10s %-20s\n" 01231 #define FORMAT2 "%-10s %-10s %-20s\n" 01232 struct ast_format *f; 01233 int count_fmt = 0; 01234 01235 if (argc != 4) 01236 return RESULT_SHOWUSAGE; 01237 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01238 01239 if (AST_LIST_LOCK(&formats)) { 01240 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01241 return -1; 01242 } 01243 01244 AST_LIST_TRAVERSE(&formats, f, list) { 01245 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01246 count_fmt++; 01247 } 01248 AST_LIST_UNLOCK(&formats); 01249 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01250 return RESULT_SUCCESS; 01251 #undef FORMAT 01252 #undef FORMAT2 01253 }
static int show_file_formats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1255 of file file.c.
References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01256 { 01257 #define FORMAT "%-10s %-10s %-20s\n" 01258 #define FORMAT2 "%-10s %-10s %-20s\n" 01259 struct ast_format *f; 01260 int count_fmt = 0; 01261 01262 if (argc != 3) 01263 return RESULT_SHOWUSAGE; 01264 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01265 01266 if (AST_LIST_LOCK(&formats)) { 01267 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01268 return -1; 01269 } 01270 01271 AST_LIST_TRAVERSE(&formats, f, list) { 01272 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01273 count_fmt++; 01274 } 01275 AST_LIST_UNLOCK(&formats); 01276 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01277 return RESULT_SUCCESS; 01278 #undef FORMAT 01279 #undef FORMAT2 01280 }
static int waitstream_core | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | rewind, | |||
int | skip_ms, | |||
int | audiofd, | |||
int | cmdfd, | |||
const char * | context | |||
) | [static] |
the core of all waitstream() functions
Definition at line 1054 of file file.c.
References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_MASQ_NOSTREAM, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_flag, ast_stopstream(), ast_strdupa, ast_stream_fastforward(), ast_stream_rewind(), ast_test_flag, ast_waitfor(), ast_waitfor_nandfds(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, ast_frame::datalen, errno, exten, ast_frame::frametype, LOG_WARNING, ast_filestream::orig_chan_name, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.
Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().
01057 { 01058 const char *orig_chan_name = NULL; 01059 int err = 0; 01060 01061 if (!breakon) 01062 breakon = ""; 01063 if (!forward) 01064 forward = ""; 01065 if (!rewind) 01066 rewind = ""; 01067 01068 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01069 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01070 01071 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01072 orig_chan_name = ast_strdupa(c->name); 01073 01074 while (c->stream) { 01075 int res; 01076 int ms; 01077 01078 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01079 ast_stopstream(c); 01080 err = 1; 01081 break; 01082 } 01083 01084 ms = ast_sched_wait(c->sched); 01085 01086 if (ms < 0 && !c->timingfunc) { 01087 ast_stopstream(c); 01088 break; 01089 } 01090 if (ms < 0) 01091 ms = 1000; 01092 if (cmdfd < 0) { 01093 res = ast_waitfor(c, ms); 01094 if (res < 0) { 01095 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01096 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01097 return res; 01098 } 01099 } else { 01100 int outfd; 01101 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01102 if (!rchan && (outfd < 0) && (ms)) { 01103 /* Continue */ 01104 if (errno == EINTR) 01105 continue; 01106 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01107 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01108 return -1; 01109 } else if (outfd > -1) { /* this requires cmdfd set */ 01110 /* The FD we were watching has something waiting */ 01111 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01112 return 1; 01113 } 01114 /* if rchan is set, it is 'c' */ 01115 res = rchan ? 1 : 0; /* map into 'res' values */ 01116 } 01117 if (res > 0) { 01118 struct ast_frame *fr = ast_read(c); 01119 if (!fr) { 01120 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01121 return -1; 01122 } 01123 switch(fr->frametype) { 01124 case AST_FRAME_DTMF_END: 01125 if (context) { 01126 const char exten[2] = { fr->subclass, '\0' }; 01127 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01128 res = fr->subclass; 01129 ast_frfree(fr); 01130 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01131 return res; 01132 } 01133 } else { 01134 res = fr->subclass; 01135 if (strchr(forward,res)) { 01136 ast_stream_fastforward(c->stream, skip_ms); 01137 } else if (strchr(rewind,res)) { 01138 ast_stream_rewind(c->stream, skip_ms); 01139 } else if (strchr(breakon, res)) { 01140 ast_frfree(fr); 01141 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01142 return res; 01143 } 01144 } 01145 break; 01146 case AST_FRAME_CONTROL: 01147 switch(fr->subclass) { 01148 case AST_CONTROL_HANGUP: 01149 case AST_CONTROL_BUSY: 01150 case AST_CONTROL_CONGESTION: 01151 ast_frfree(fr); 01152 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01153 return -1; 01154 case AST_CONTROL_RINGING: 01155 case AST_CONTROL_ANSWER: 01156 case AST_CONTROL_VIDUPDATE: 01157 case AST_CONTROL_HOLD: 01158 case AST_CONTROL_UNHOLD: 01159 /* Unimportant */ 01160 break; 01161 default: 01162 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01163 } 01164 break; 01165 case AST_FRAME_VOICE: 01166 /* Write audio if appropriate */ 01167 if (audiofd > -1) 01168 write(audiofd, fr->data, fr->datalen); 01169 default: 01170 /* Ignore all others */ 01171 break; 01172 } 01173 ast_frfree(fr); 01174 } 01175 ast_sched_runq(c->sched); 01176 } 01177 01178 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01179 01180 return (err || c->_softhangup) ? -1 : 0; 01181 }
struct ast_cli_entry cli_file[] |
Initial value:
{ { { "core", "show", "file", "formats" }, show_file_formats, "Displays file formats", show_file_formats_usage, NULL, &cli_show_file_formats_deprecated }, }
Initial value:
{ { "show", "file", "formats" }, show_file_formats_deprecated, NULL, NULL }
char show_file_formats_usage[] |