#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.h>
#include <math.h>
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include "asterisk/mod_format.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/sched.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"
#include "asterisk/astobj2.h"
Go to the source code of this file.
Data Structures | |
struct | formats |
Defines | |
#define | FORMAT "%-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) |
Register a new file format capability. Adds a format to Asterisk's format abilities. | |
int | ast_applystream (struct ast_channel *chan, struct ast_filestream *s) |
Applys a open stream to a channel. | |
int | ast_closestream (struct ast_filestream *f) |
Closes a stream. | |
int | ast_file_init (void) |
int | ast_filecopy (const char *filename, const char *filename2, const char *fmt) |
Copies a file. | |
int | ast_filedelete (const char *filename, const char *fmt) |
Deletes a file. | |
int | ast_fileexists (const char *filename, const char *fmt, const char *preflang) |
Checks for the existence of a given file. | |
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) |
Renames a file. | |
void | ast_filestream_frame_freed (struct ast_frame *fr) |
destroy a filestream using an ast_frame as input | |
int | ast_format_unregister (const char *name) |
Unregisters a file format. | |
static int | ast_fsread_audio (const void *data) |
static int | ast_fsread_video (const void *data) |
ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
Opens stream for use in seeking, playing. | |
ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
Opens stream for use in seeking, playing. | |
ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang) |
Opens stream for use in seeking, playing. | |
int | ast_playstream (struct ast_filestream *s) |
Play a open stream on a channel. | |
static enum fsread_res | ast_readaudio_callback (struct ast_filestream *s) |
ast_filestream * | ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
Starts reading from a file. | |
ast_frame * | ast_readframe (struct ast_filestream *s) |
Read a frame from a filestream. | |
static enum fsread_res | ast_readvideo_callback (struct ast_filestream *s) |
int | ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence) |
Seeks into stream. | |
int | ast_stopstream (struct ast_channel *tmp) |
Stops a stream. | |
int | ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits) |
stream file until digit If the file name is non-empty, try to play it. | |
int | ast_stream_fastforward (struct ast_filestream *fs, off_t ms) |
Fast forward stream ms. | |
int | ast_stream_rewind (struct ast_filestream *fs, off_t ms) |
Rewind stream ms. | |
int | ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang) |
Streams a file. | |
off_t | ast_tellstream (struct ast_filestream *fs) |
Tell where we are in a stream. | |
int | ast_truncstream (struct ast_filestream *fs) |
Trunc stream at current location. | |
int | ast_waitstream (struct ast_channel *c, const char *breakon) |
Waits for a stream to stop or digit to be pressed. | |
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. | |
int | ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms) |
Same as waitstream but allows stream to be forwarded or rewound. | |
int | ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd) |
ast_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
Starts writing a file. | |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
Writes a frame to a stream. | |
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 | fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen) |
static void | filestream_destructor (void *arg) |
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 char * | handle_cli_core_show_file_formats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | is_absolute_path (const char *filename) |
static int | open_wrapper (struct ast_filestream *s) |
static int | rewrite_wrapper (struct ast_filestream *s, const char *comment) |
static int | waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int skip_ms, int audiofd, int cmdfd, const char *context) |
the core of all waitstream() functions | |
Variables | |
int | ast_language_is_prefix = 1 |
ast_cli_entry | cli_file [] |
Definition in file file.c.
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
Referenced by __iax2_show_peers(), _sip_show_peers(), dahdi_show_channels(), dahdi_show_status(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), handle_cli_core_show_file_formats(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_users(), handle_core_show_image_formats(), sip_show_channels(), sip_show_channelstats(), sip_show_inuse(), sip_show_registry(), and sip_show_tcp().
enum file_action |
Definition at line 382 of file file.c.
00382 { 00383 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00384 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00385 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00386 ACTION_OPEN, 00387 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00388 };
enum fsread_res |
Definition at line 699 of file file.c.
00699 { 00700 FSREAD_FAILURE, 00701 FSREAD_SUCCESS_SCHED, 00702 FSREAD_SUCCESS_NOSCHED, 00703 };
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.
0 | on success | |
-1 | on failure |
Definition at line 61 of file file.c.
References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::buf_size, ast_format::exts, f, ast_format::list, LOG_WARNING, ast_format::module, and ast_format::name.
00062 { 00063 struct ast_format *tmp; 00064 00065 AST_RWLIST_WRLOCK(&formats); 00066 AST_RWLIST_TRAVERSE(&formats, tmp, list) { 00067 if (!strcasecmp(f->name, tmp->name)) { 00068 AST_RWLIST_UNLOCK(&formats); 00069 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00070 return -1; 00071 } 00072 } 00073 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00074 AST_RWLIST_UNLOCK(&formats); 00075 return -1; 00076 } 00077 *tmp = *f; 00078 tmp->module = mod; 00079 if (tmp->buf_size) { 00080 /* 00081 * Align buf_size properly, rounding up to the machine-specific 00082 * alignment for pointers. 00083 */ 00084 struct _test_align { void *a, *b; } p; 00085 int align = (char *)&p.b - (char *)&p.a; 00086 tmp->buf_size = ((f->buf_size + align - 1) / align) * align; 00087 } 00088 00089 memset(&tmp->list, 0, sizeof(tmp->list)); 00090 00091 AST_RWLIST_INSERT_HEAD(&formats, tmp, list); 00092 AST_RWLIST_UNLOCK(&formats); 00093 ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00094 00095 return 0; 00096 }
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 |
0 | on success. | |
-1 | on failure. |
Definition at line 818 of file file.c.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
int ast_closestream | ( | struct ast_filestream * | f | ) |
Closes a stream.
f | filestream to close Close a playback or recording stream |
0 | on success. | |
-1 | on failure. |
Definition at line 861 of file file.c.
References ao2_ref, AST_FRFLAG_FROM_FILESTREAM, ast_test_flag, and f.
Referenced by __ast_play_and_record(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_readfile(), ast_stopstream(), ast_writefile(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_cli_file_convert(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), and rpt().
00862 { 00863 if (ast_test_flag(&f->fr, AST_FRFLAG_FROM_FILESTREAM)) { 00864 /* If this flag is still set, it essentially means that the reference 00865 * count of f is non-zero. We can't destroy this filestream until 00866 * whatever is using the filestream's frame has finished. 00867 * 00868 * Since this was called, however, we need to remove the reference from 00869 * when this filestream was first allocated. That way, when the embedded 00870 * frame is freed, the refcount will reach 0 and we can finish destroying 00871 * this filestream properly. 00872 */ 00873 ao2_ref(f, -1); 00874 return 0; 00875 } 00876 00877 ao2_ref(f, -1); 00878 return 0; 00879 }
int ast_file_init | ( | void | ) |
Provided by file.c
Definition at line 1369 of file file.c.
References ast_cli_register_multiple(), and cli_file.
Referenced by main().
01370 { 01371 ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry)); 01372 return 0; 01373 }
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 909 of file file.c.
References ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00910 { 00911 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00912 }
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 899 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by __ast_play_and_record(), announce_thread(), ast_monitor_start(), ast_monitor_stop(), conf_free(), conf_run(), handle_cli_file_convert(), leave_voicemail(), play_record_review(), setup_privacy_args(), vm_delete(), and vm_forwardoptions().
00900 { 00901 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00902 }
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. |
Definition at line 885 of file file.c.
References buf, and fileexists_core().
Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), eivr_comm(), forward_message(), function_playback(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_message(), play_message_callerid(), record_exec(), retrydial_exec(), rpt_tele_thread(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), saynode(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
00886 { 00887 char *buf; 00888 int buflen; 00889 00890 if (preflang == NULL) 00891 preflang = ""; 00892 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00893 buf = alloca(buflen); 00894 if (buf == NULL) 00895 return 0; 00896 return fileexists_core(filename, fmt, preflang, buf, buflen); 00897 }
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 399 of file file.c.
References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), chan, copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_format::format, get_filestream(), ast_format::list, LOG_WARNING, open_wrapper(), s, ast_channel::stream, strsep(), ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), ast_openvstream(), and fileexists_test().
00400 { 00401 struct ast_format *f; 00402 int res = (action == ACTION_EXISTS) ? 0 : -1; 00403 00404 AST_RWLIST_RDLOCK(&formats); 00405 /* Check for a specific format */ 00406 AST_RWLIST_TRAVERSE(&formats, f, list) { 00407 char *stringp, *ext = NULL; 00408 00409 if (fmt && !exts_compare(f->exts, fmt)) 00410 continue; 00411 00412 /* Look for a file matching the supported extensions. 00413 * The file must exist, and for OPEN, must match 00414 * one of the formats supported by the channel. 00415 */ 00416 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00417 while ( (ext = strsep(&stringp, "|")) ) { 00418 struct stat st; 00419 char *fn = build_filename(filename, ext); 00420 00421 if (fn == NULL) 00422 continue; 00423 00424 if ( stat(fn, &st) ) { /* file not existent */ 00425 ast_free(fn); 00426 continue; 00427 } 00428 /* for 'OPEN' we need to be sure that the format matches 00429 * what the channel can process 00430 */ 00431 if (action == ACTION_OPEN) { 00432 struct ast_channel *chan = (struct ast_channel *)arg2; 00433 FILE *bfile; 00434 struct ast_filestream *s; 00435 00436 if ( !(chan->writeformat & f->format) && 00437 !((f->format & AST_FORMAT_AUDIO_MASK && fmt) || 00438 (f->format & AST_FORMAT_VIDEO_MASK && fmt))) { 00439 ast_free(fn); 00440 continue; /* not a supported format */ 00441 } 00442 if ( (bfile = fopen(fn, "r")) == NULL) { 00443 ast_free(fn); 00444 continue; /* cannot open file */ 00445 } 00446 s = get_filestream(f, bfile); 00447 if (!s) { 00448 fclose(bfile); 00449 ast_free(fn); /* cannot allocate descriptor */ 00450 continue; 00451 } 00452 if (open_wrapper(s)) { 00453 ast_free(fn); 00454 ast_closestream(s); 00455 continue; /* cannot run open on file */ 00456 } 00457 if (st.st_size == 0) { 00458 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn); 00459 } 00460 /* ok this is good for OPEN */ 00461 res = 1; /* found */ 00462 s->lasttimeout = -1; 00463 s->fmt = f; 00464 s->trans = NULL; 00465 s->filename = NULL; 00466 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) { 00467 if (chan->stream) 00468 ast_closestream(chan->stream); 00469 chan->stream = s; 00470 } else { 00471 if (chan->vstream) 00472 ast_closestream(chan->vstream); 00473 chan->vstream = s; 00474 } 00475 ast_free(fn); 00476 break; 00477 } 00478 switch (action) { 00479 case ACTION_OPEN: 00480 break; /* will never get here */ 00481 00482 case ACTION_EXISTS: /* return the matching format */ 00483 res |= f->format; 00484 break; 00485 00486 case ACTION_DELETE: 00487 if ( (res = unlink(fn)) ) 00488 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00489 break; 00490 00491 case ACTION_RENAME: 00492 case ACTION_COPY: { 00493 char *nfn = build_filename((const char *)arg2, ext); 00494 if (!nfn) 00495 ast_log(LOG_WARNING, "Out of memory\n"); 00496 else { 00497 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00498 if (res) 00499 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00500 action == ACTION_COPY ? "copy" : "rename", 00501 fn, nfn, strerror(errno)); 00502 ast_free(nfn); 00503 } 00504 } 00505 break; 00506 00507 default: 00508 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00509 } 00510 ast_free(fn); 00511 } 00512 } 00513 AST_RWLIST_UNLOCK(&formats); 00514 return res; 00515 }
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 |
Definition at line 904 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().
00905 { 00906 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00907 }
void ast_filestream_frame_freed | ( | struct ast_frame * | fr | ) |
destroy a filestream using an ast_frame as input
This is a hack that is used also by the ast_trans_pvt and ast_dsp structures. When a structure contains an ast_frame pointer as one of its fields. It may be that the frame is still used after the outer structure is freed. This leads to invalid memory accesses. This function allows for us to hold off on destroying the ast_filestream until we are done using the ast_frame pointer that is part of it
fr | The ast_frame that is part of an ast_filestream we wish to free. |
Definition at line 1301 of file file.c.
References ao2_ref, ast_clear_flag, AST_FRFLAG_FROM_FILESTREAM, and ast_filestream::fr.
Referenced by ast_frame_free().
01302 { 01303 struct ast_filestream *fs; 01304 01305 ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM); 01306 01307 fs = (struct ast_filestream *) (((char *) fr) - offsetof(struct ast_filestream, fr)); 01308 01309 ao2_ref(fs, -1); 01310 }
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. |
0 | on success | |
-1 | on failure to unregister |
Definition at line 98 of file file.c.
References ast_free, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::list, LOG_WARNING, and ast_format::name.
Referenced by unload_module().
00099 { 00100 struct ast_format *tmp; 00101 int res = -1; 00102 00103 AST_RWLIST_WRLOCK(&formats); 00104 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00105 if (!strcasecmp(name, tmp->name)) { 00106 AST_RWLIST_REMOVE_CURRENT(list); 00107 ast_free(tmp); 00108 res = 0; 00109 } 00110 } 00111 AST_RWLIST_TRAVERSE_SAFE_END; 00112 AST_RWLIST_UNLOCK(&formats); 00113 00114 if (!res) 00115 ast_verb(2, "Unregistered format %s\n", name); 00116 else 00117 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00118 00119 return res; 00120 }
static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 756 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00757 { 00758 struct ast_filestream *fs = (struct ast_filestream *)data; 00759 enum fsread_res res; 00760 00761 res = ast_readaudio_callback(fs); 00762 00763 if (res == FSREAD_SUCCESS_SCHED) 00764 return 1; 00765 00766 return 0; 00767 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 805 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00806 { 00807 struct ast_filestream *fs = (struct ast_filestream *)data; 00808 enum fsread_res res; 00809 00810 res = ast_readvideo_callback(fs); 00811 00812 if (res == FSREAD_SUCCESS_SCHED) 00813 return 1; 00814 00815 return 0; 00816 }
struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
Opens stream for use in seeking, playing.
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use |
a | ast_filestream pointer if it opens the file. | |
NULL | on error. |
Definition at line 610 of file file.c.
References ast_openstream_full(), and chan.
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00611 { 00612 return ast_openstream_full(chan, filename, preflang, 0); 00613 }
struct ast_filestream* ast_openstream_full | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang, | |||
int | asis | |||
) |
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 |
a | ast_filestream pointer if it opens the file. | |
NULL | on error. |
Definition at line 615 of file file.c.
References ACTION_OPEN, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), buf, chan, fileexists_core(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.
Referenced by ast_moh_files_next(), ast_openstream(), and gen_nextfile().
00616 { 00617 /* 00618 * Use fileexists_core() to find a file in a compatible 00619 * language and format, set up a suitable translator, 00620 * and open the stream. 00621 */ 00622 int fmts, res, buflen; 00623 char *buf; 00624 00625 if (!asis) { 00626 /* do this first, otherwise we detect the wrong writeformat */ 00627 ast_stopstream(chan); 00628 if (chan->generator) 00629 ast_deactivate_generator(chan); 00630 } 00631 if (preflang == NULL) 00632 preflang = ""; 00633 buflen = strlen(preflang) + strlen(filename) + 4; 00634 buf = alloca(buflen); 00635 if (buf == NULL) 00636 return NULL; 00637 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00638 if (fmts > 0) 00639 fmts &= AST_FORMAT_AUDIO_MASK; 00640 if (fmts < 1) { 00641 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00642 return NULL; 00643 } 00644 chan->oldwriteformat = chan->writeformat; 00645 /* Set the channel to a format we can work with */ 00646 res = ast_set_write_format(chan, fmts); 00647 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00648 if (res >= 0) 00649 return chan->stream; 00650 return NULL; 00651 }
struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
Opens stream for use in seeking, playing.
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use |
a | ast_filestream pointer if it opens the file. | |
NULL | on error. |
Definition at line 653 of file file.c.
References ACTION_OPEN, ast_filehelper(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), buf, chan, fileexists_core(), ast_filestream::fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00654 { 00655 /* As above, but for video. But here we don't have translators 00656 * so we must enforce a format. 00657 */ 00658 unsigned int format; 00659 char *buf; 00660 int buflen; 00661 00662 if (preflang == NULL) 00663 preflang = ""; 00664 buflen = strlen(preflang) + strlen(filename) + 4; 00665 buf = alloca(buflen); 00666 if (buf == NULL) 00667 return NULL; 00668 00669 for (format = AST_FORMAT_AUDIO_MASK + 1; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) { 00670 int fd; 00671 const char *fmt; 00672 00673 if (!(chan->nativeformats & format)) 00674 continue; 00675 fmt = ast_getformatname(format); 00676 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00677 continue; 00678 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00679 if (fd >= 0) 00680 return chan->vstream; 00681 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00682 } 00683 return NULL; 00684 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
Play a open stream on a channel.
s | filestream to play |
0 | on success. | |
-1 | on failure. |
Definition at line 824 of file file.c.
References AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), FSREAD_FAILURE, and s.
Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00825 { 00826 enum fsread_res res; 00827 00828 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) 00829 res = ast_readaudio_callback(s); 00830 else 00831 res = ast_readvideo_callback(s); 00832 00833 return (res == FSREAD_FAILURE) ? -1 : 0; 00834 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 707 of file file.c.
References ao2_ref, ast_format_rate(), AST_FRFLAG_FROM_FILESTREAM, ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_set_flag, ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.
Referenced by ast_fsread_audio(), and ast_playstream().
00708 { 00709 int whennext = 0; 00710 00711 while (!whennext) { 00712 struct ast_frame *fr; 00713 00714 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) 00715 goto return_failure; 00716 00717 fr = s->fmt->read(s, &whennext); 00718 if (fr) { 00719 ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM); 00720 ao2_ref(s, +1); 00721 } 00722 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00723 if (fr) { 00724 ast_log(LOG_WARNING, "Failed to write frame\n"); 00725 ast_frfree(fr); 00726 } 00727 goto return_failure; 00728 } 00729 if (fr) { 00730 ast_frfree(fr); 00731 } 00732 } 00733 if (whennext != s->lasttimeout) { 00734 if (s->owner->timingfd > -1) { 00735 float samp_rate = (float) ast_format_rate(s->fmt->format); 00736 unsigned int rate; 00737 00738 rate = (unsigned int) roundf(samp_rate / ((float) whennext)); 00739 00740 ast_settimeout(s->owner, rate, ast_fsread_audio, s); 00741 } else { 00742 s->owner->streamid = ast_sched_add(s->owner->sched, 00743 whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s); 00744 } 00745 s->lasttimeout = whennext; 00746 return FSREAD_SUCCESS_NOSCHED; 00747 } 00748 return FSREAD_SUCCESS_SCHED; 00749 00750 return_failure: 00751 s->owner->streamid = -1; 00752 ast_settimeout(s->owner, 0, NULL, NULL); 00753 return FSREAD_FAILURE; 00754 }
struct ast_filestream* ast_readfile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) |
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. |
a | struct ast_filestream on success. | |
NULL | on failure. |
Definition at line 956 of file file.c.
References ast_closestream(), ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), and handle_cli_file_convert().
00957 { 00958 FILE *bfile; 00959 struct ast_format *f; 00960 struct ast_filestream *fs = NULL; 00961 char *fn; 00962 int format_found = 0; 00963 00964 AST_RWLIST_RDLOCK(&formats); 00965 00966 AST_RWLIST_TRAVERSE(&formats, f, list) { 00967 fs = NULL; 00968 if (!exts_compare(f->exts, type)) 00969 continue; 00970 else 00971 format_found = 1; 00972 00973 fn = build_filename(filename, type); 00974 errno = 0; 00975 bfile = fopen(fn, "r"); 00976 00977 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) { 00978 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00979 if (fs) { 00980 ast_closestream(fs); 00981 } 00982 fs = NULL; 00983 bfile = NULL; 00984 ast_free(fn); 00985 break; 00986 } 00987 /* found it */ 00988 fs->trans = NULL; 00989 fs->fmt = f; 00990 fs->flags = flags; 00991 fs->mode = mode; 00992 fs->filename = ast_strdup(filename); 00993 fs->vfs = NULL; 00994 break; 00995 } 00996 00997 AST_RWLIST_UNLOCK(&formats); 00998 if (!format_found) 00999 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01000 01001 return fs; 01002 }
struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) |
Read a frame from a filestream.
s | ast_filestream to act on |
NULL | if read failed. |
Definition at line 686 of file file.c.
References ao2_ref, AST_FRFLAG_FROM_FILESTREAM, ast_set_flag, f, and s.
Referenced by __ast_play_and_record(), dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().
00687 { 00688 struct ast_frame *f = NULL; 00689 int whennext = 0; 00690 if (s && s->fmt) 00691 f = s->fmt->read(s, &whennext); 00692 if (f) { 00693 ast_set_flag(f, AST_FRFLAG_FROM_FILESTREAM); 00694 ao2_ref(s, +1); 00695 } 00696 return f; 00697 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 771 of file file.c.
References ao2_ref, ast_format_rate(), AST_FRFLAG_FROM_FILESTREAM, ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_set_flag, ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.
Referenced by ast_fsread_video(), and ast_playstream().
00772 { 00773 int whennext = 0; 00774 00775 while (!whennext) { 00776 struct ast_frame *fr = s->fmt->read(s, &whennext); 00777 if (fr) { 00778 ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM); 00779 ao2_ref(s, +1); 00780 } 00781 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00782 if (fr) { 00783 ast_log(LOG_WARNING, "Failed to write frame\n"); 00784 ast_frfree(fr); 00785 } 00786 s->owner->vstreamid = -1; 00787 return FSREAD_FAILURE; 00788 } 00789 if (fr) { 00790 ast_frfree(fr); 00791 } 00792 } 00793 00794 if (whennext != s->lasttimeout) { 00795 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00796 whennext / (ast_format_rate(s->fmt->format) / 1000), 00797 ast_fsread_video, s); 00798 s->lasttimeout = whennext; 00799 return FSREAD_SUCCESS_NOSCHED; 00800 } 00801 00802 return FSREAD_SUCCESS_SCHED; 00803 }
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 |
0 | on success. | |
-1 | on failure. |
Definition at line 836 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by __ast_read(), ast_control_streamfile(), ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_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 122 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_enumeration_full_he(), 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_hu(), 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_th(), ast_say_number_full_tw(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), read_exec(), readexten_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_seq(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00123 { 00124 ast_channel_lock(tmp); 00125 00126 /* Stop a running stream if there is one */ 00127 if (tmp->stream) { 00128 ast_closestream(tmp->stream); 00129 tmp->stream = NULL; 00130 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00131 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00132 } 00133 /* Stop the video stream too */ 00134 if (tmp->vstream != NULL) { 00135 ast_closestream(tmp->vstream); 00136 tmp->vstream = NULL; 00137 } 00138 00139 ast_channel_unlock(tmp); 00140 00141 return 0; 00142 }
int ast_stream_and_wait | ( | struct ast_channel * | chan, | |
const char * | file, | |||
const char * | digits | |||
) |
stream file until digit If the file name is non-empty, try to play it.
-1 | if error. | |
digit | if interrupted by a digit. |
Definition at line 1317 of file file.c.
References ast_streamfile(), ast_strlen_zero(), ast_waitstream(), chan, and ast_channel::language.
Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), directory_exec(), forward_message(), invent_message(), ivr_dispatch(), leave_voicemail(), masq_park_call(), park_exec_full(), play_mailbox_owner(), play_message_callerid(), play_message_in_bridged_call(), play_record_review(), sayname(), select_item_seq(), and wait_file2().
01318 { 01319 int res = 0; 01320 if (!ast_strlen_zero(file)) { 01321 res = ast_streamfile(chan, file, chan->language); 01322 if (!res) { 01323 res = ast_waitstream(chan, digits); 01324 } 01325 } 01326 return res; 01327 }
int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Fast forward stream ms.
fs | filestream to act on | |
ms | milliseconds to move |
0 | on success. | |
-1 | on failure. |
Definition at line 851 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00852 { 00853 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00854 }
int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Rewind stream ms.
fs | filestream to act on | |
ms | milliseconds to move |
0 | on success. | |
-1 | on failure. |
Definition at line 856 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), and waitstream_core().
00857 { 00858 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00859 }
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. |
0 | on success. | |
-1 | on failure. |
Definition at line 914 of file file.c.
References ast_applystream(), ast_debug, AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_strdup, ast_test_flag, ast_verb, chan, errno, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, ast_filestream::vfs, and ast_channel::writeformat.
Referenced by action_bridge(), agent_call(), announce_thread(), app_exec(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), 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_he(), ast_say_date_hu(), ast_say_date_nl(), ast_say_date_th(), 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_from_now_he(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), 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_hu(), 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_th(), 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_hu(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), login_exec(), minivm_greet_exec(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), select_item_menu(), setup_privacy_args(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().
00915 { 00916 struct ast_filestream *fs; 00917 struct ast_filestream *vfs=NULL; 00918 char fmt[256]; 00919 int seekattempt; 00920 int res; 00921 00922 fs = ast_openstream(chan, filename, preflang); 00923 if (!fs) { 00924 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00925 return -1; 00926 } 00927 00928 /* check to see if there is any data present (not a zero length file), 00929 * done this way because there is no where for ast_openstream_full to 00930 * return the file had no data. */ 00931 seekattempt = fseek(fs->f, -1, SEEK_END); 00932 if (!seekattempt) 00933 ast_seekstream(fs, 0, SEEK_SET); 00934 else 00935 return 0; 00936 00937 vfs = ast_openvstream(chan, filename, preflang); 00938 if (vfs) { 00939 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00940 } 00941 00942 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00943 fs->orig_chan_name = ast_strdup(chan->name); 00944 if (ast_applystream(chan, fs)) 00945 return -1; 00946 if (vfs && ast_applystream(chan, vfs)) 00947 return -1; 00948 res = ast_playstream(fs); 00949 if (!res && vfs) 00950 res = ast_playstream(vfs); 00951 ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default"); 00952 00953 return res; 00954 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream.
fs | fs to act on |
Definition at line 846 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(), handle_speechrecognize(), and handle_streamfile().
int ast_truncstream | ( | struct ast_filestream * | fs | ) |
Trunc stream at current location.
fs | filestream to act on |
0 | on success. | |
-1 | on failure. |
Definition at line 841 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by __ast_play_and_record(), and handle_recordfile().
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, |
0 | if the stream finishes | |
the | character if it was interrupted, | |
-1 | on error |
Definition at line 1279 of file file.c.
References waitstream_core().
Referenced by action_bridge(), agent_call(), announce_thread(), app_exec(), ast_play_and_wait(), 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_he(), ast_say_date_hu(), ast_say_date_nl(), ast_say_date_th(), 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_from_now_he(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), 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_hu(), 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_th(), ast_say_number_full_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), login_exec(), minivm_greet_exec(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), ss_thread(), vm_authenticate(), and wait_file().
01280 { 01281 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01282 }
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, |
0 | if the stream finishes. | |
the | character if it was interrupted. | |
-1 | on error. |
Definition at line 1290 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01291 { 01292 /* Waitstream, with return in the case of a valid 1 digit extension */ 01293 /* in the current or specified context being pressed */ 01294 01295 if (!context) 01296 context = c->context; 01297 return waitstream_core(c, NULL, NULL, NULL, 0, 01298 -1, -1, context); 01299 }
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, |
0 | if the stream finishes. | |
the | character if it was interrupted. | |
-1 | on error. |
Definition at line 1273 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01274 { 01275 return waitstream_core(c, breakon, forward, reverse, ms, 01276 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01277 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | monfd | |||
) |
Same as waitstream, but with audio output to fd and monitored fd checking.
Definition at line 1284 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_enumeration_full_he(), 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_hu(), 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_th(), 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().
01285 { 01286 return waitstream_core(c, breakon, NULL, NULL, 0, 01287 audiofd, cmdfd, NULL /* no context */); 01288 }
struct ast_filestream* ast_writefile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) |
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. |
a | struct ast_filestream on success. | |
NULL | on failure. |
Definition at line 1004 of file file.c.
References ast_closestream(), ast_free, ast_log(), ast_malloc, ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_strdupa, buf, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, ast_filestream::trans, ast_filestream::vfs, and ast_filestream::write_buffer.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().
01005 { 01006 int fd, myflags = 0; 01007 /* compiler claims this variable can be used before initialization... */ 01008 FILE *bfile = NULL; 01009 struct ast_format *f; 01010 struct ast_filestream *fs = NULL; 01011 char *buf = NULL; 01012 size_t size = 0; 01013 int format_found = 0; 01014 01015 AST_RWLIST_RDLOCK(&formats); 01016 01017 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 01018 /* We really can't use O_APPEND as it will break WAV header updates */ 01019 if (flags & O_APPEND) { 01020 flags &= ~O_APPEND; 01021 } else { 01022 myflags = O_TRUNC; 01023 } 01024 01025 myflags |= O_WRONLY | O_CREAT; 01026 01027 /* XXX need to fix this - we should just do the fopen, 01028 * not open followed by fdopen() 01029 */ 01030 AST_RWLIST_TRAVERSE(&formats, f, list) { 01031 char *fn, *orig_fn = NULL; 01032 if (fs) 01033 break; 01034 01035 if (!exts_compare(f->exts, type)) 01036 continue; 01037 else 01038 format_found = 1; 01039 01040 fn = build_filename(filename, type); 01041 fd = open(fn, flags | myflags, mode); 01042 if (fd > -1) { 01043 /* fdopen() the resulting file stream */ 01044 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01045 if (!bfile) { 01046 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01047 close(fd); 01048 fd = -1; 01049 } 01050 } 01051 01052 if (ast_opt_cache_record_files && (fd > -1)) { 01053 char *c; 01054 01055 fclose(bfile); /* this also closes fd */ 01056 /* 01057 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01058 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01059 */ 01060 orig_fn = ast_strdupa(fn); 01061 for (c = fn; *c; c++) 01062 if (*c == '/') 01063 *c = '_'; 01064 01065 size = strlen(fn) + strlen(record_cache_dir) + 2; 01066 buf = alloca(size); 01067 strcpy(buf, record_cache_dir); 01068 strcat(buf, "/"); 01069 strcat(buf, fn); 01070 ast_free(fn); 01071 fn = buf; 01072 fd = open(fn, flags | myflags, mode); 01073 if (fd > -1) { 01074 /* fdopen() the resulting file stream */ 01075 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01076 if (!bfile) { 01077 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01078 close(fd); 01079 fd = -1; 01080 } 01081 } 01082 } 01083 if (fd > -1) { 01084 errno = 0; 01085 fs = get_filestream(f, bfile); 01086 if (!fs || rewrite_wrapper(fs, comment)) { 01087 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01088 close(fd); 01089 if (orig_fn) { 01090 unlink(fn); 01091 unlink(orig_fn); 01092 } 01093 if (fs) { 01094 ast_closestream(fs); 01095 fs = NULL; 01096 } 01097 continue; 01098 } 01099 fs->trans = NULL; 01100 fs->fmt = f; 01101 fs->flags = flags; 01102 fs->mode = mode; 01103 if (orig_fn) { 01104 fs->realfilename = ast_strdup(orig_fn); 01105 fs->filename = ast_strdup(fn); 01106 } else { 01107 fs->realfilename = NULL; 01108 fs->filename = ast_strdup(filename); 01109 } 01110 fs->vfs = NULL; 01111 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01112 01113 if ((fs->write_buffer = ast_malloc(32768))){ 01114 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768); 01115 } 01116 01117 f->seek(fs, 0, SEEK_END); 01118 } else if (errno != EEXIST) { 01119 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01120 if (orig_fn) 01121 unlink(orig_fn); 01122 } 01123 /* if buf != NULL then fn is already free and pointing to it */ 01124 if (!buf) 01125 ast_free(fn); 01126 } 01127 01128 AST_RWLIST_UNLOCK(&formats); 01129 01130 if (!format_found) 01131 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01132 01133 return fs; 01134 }
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 |
0 | on success. | |
-1 | on failure. |
Definition at line 144 of file file.c.
References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.
Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().
00145 { 00146 int res = -1; 00147 int alt = 0; 00148 if (f->frametype == AST_FRAME_VIDEO) { 00149 if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) { 00150 /* This is the audio portion. Call the video one... */ 00151 if (!fs->vfs && fs->filename) { 00152 const char *type = ast_getformatname(f->subclass & ~0x1); 00153 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00154 ast_debug(1, "Opened video output file\n"); 00155 } 00156 if (fs->vfs) 00157 return ast_writestream(fs->vfs, f); 00158 /* else ignore */ 00159 return 0; 00160 } else { 00161 /* Might / might not have mark set */ 00162 alt = 1; 00163 } 00164 } else if (f->frametype != AST_FRAME_VOICE) { 00165 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00166 return -1; 00167 } 00168 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00169 res = fs->fmt->write(fs, f); 00170 if (res < 0) 00171 ast_log(LOG_WARNING, "Natural write failed\n"); 00172 else if (res > 0) 00173 ast_log(LOG_WARNING, "Huh??\n"); 00174 } else { 00175 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00176 the one we've setup a translator for, we do the "wrong thing" XXX */ 00177 if (fs->trans && f->subclass != fs->lastwriteformat) { 00178 ast_translator_free_path(fs->trans); 00179 fs->trans = NULL; 00180 } 00181 if (!fs->trans) 00182 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00183 if (!fs->trans) 00184 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00185 fs->fmt->name, ast_getformatname(f->subclass)); 00186 else { 00187 struct ast_frame *trf; 00188 fs->lastwriteformat = f->subclass; 00189 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00190 trf = ast_translate(fs->trans, f, 0); 00191 if (trf) { 00192 res = fs->fmt->write(fs, trf); 00193 ast_frfree(trf); 00194 if (res) 00195 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00196 } else 00197 res = 0; 00198 } 00199 } 00200 return res; 00201 }
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 246 of file file.c.
References asprintf, ast_config_AST_DATA_DIR, ast_log(), errno, and LOG_WARNING.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00247 { 00248 char *fn = NULL; 00249 00250 if (!strcmp(ext, "wav49")) 00251 ext = "WAV"; 00252 00253 if (filename[0] == '/') { 00254 if (asprintf(&fn, "%s.%s", filename, ext) < 0) { 00255 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00256 fn = NULL; 00257 } 00258 } else { 00259 if (asprintf(&fn, "%s/sounds/%s.%s", 00260 ast_config_AST_DATA_DIR, filename, ext) < 0) { 00261 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00262 fn = NULL; 00263 } 00264 } 00265 return fn; 00266 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 203 of file file.c.
References AST_FILE_MODE, ast_log(), buf, errno, len(), and LOG_WARNING.
Referenced by ast_filehelper(), ast_func_read(), ast_func_write(), handle_cli_transcoder_show(), and iax2_register().
00204 { 00205 int ifd, ofd, len; 00206 char buf[4096]; /* XXX make it lerger. */ 00207 00208 if ((ifd = open(infile, O_RDONLY)) < 0) { 00209 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00210 return -1; 00211 } 00212 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) { 00213 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00214 close(ifd); 00215 return -1; 00216 } 00217 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00218 int res; 00219 if (len < 0) { 00220 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00221 break; 00222 } 00223 /* XXX handle partial writes */ 00224 res = write(ofd, buf, len); 00225 if (res != len) { 00226 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00227 len = -1; /* error marker */ 00228 break; 00229 } 00230 } 00231 close(ifd); 00232 close(ofd); 00233 if (len < 0) { 00234 unlink(outfile); 00235 return -1; /* error */ 00236 } 00237 return 0; /* success */ 00238 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 270 of file file.c.
References ast_copy_string(), ext, and strsep().
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00271 { 00272 char tmp[256]; 00273 char *stringp = tmp, *ext; 00274 00275 ast_copy_string(tmp, exts, sizeof(tmp)); 00276 while ((ext = strsep(&stringp, "|"))) { 00277 if (!strcmp(ext, type)) 00278 return 1; 00279 } 00280 00281 return 0; 00282 }
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 559 of file file.c.
References ast_strdupa, ast_strlen_zero(), DEFAULT_LANGUAGE, fileexists_test(), and strsep().
Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().
00561 { 00562 int res = -1; 00563 char *lang = NULL; 00564 00565 if (buf == NULL) { 00566 return -1; 00567 } 00568 00569 /* We try languages in the following order: 00570 * preflang (may include dialect) 00571 * lang (preflang without dialect - if any) 00572 * <none> 00573 * default (unless the same as preflang or lang without dialect) 00574 */ 00575 00576 /* Try preferred language */ 00577 if (!ast_strlen_zero(preflang)) { 00578 /* try the preflang exactly as it was requested */ 00579 if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) { 00580 return res; 00581 } else { 00582 /* try without a dialect */ 00583 char *postfix = NULL; 00584 postfix = lang = ast_strdupa(preflang); 00585 00586 strsep(&postfix, "_"); 00587 if (postfix) { 00588 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00589 return res; 00590 } 00591 } 00592 } 00593 } 00594 00595 /* Try without any language */ 00596 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00597 return res; 00598 } 00599 00600 /* Finally try the default language unless it was already tried before */ 00601 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00602 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00603 return res; 00604 } 00605 } 00606 00607 return 0; 00608 }
static int fileexists_test | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | lang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 522 of file file.c.
References ACTION_EXISTS, ast_filehelper(), and is_absolute_path().
Referenced by fileexists_core().
00524 { 00525 if (buf == NULL) { 00526 return -1; 00527 } 00528 00529 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */ 00530 if (lang) { 00531 snprintf(buf, buflen, "%s/%s", lang, filename); 00532 } else { 00533 snprintf(buf, buflen, "%s", filename); 00534 } 00535 } else { /* old layout */ 00536 strcpy(buf, filename); /* first copy the full string */ 00537 if (lang) { 00538 /* insert the language and suffix if needed */ 00539 const char *c = strrchr(filename, '/'); 00540 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00541 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00542 } 00543 } 00544 00545 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00546 }
static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 284 of file file.c.
References ast_closestream(), AST_FORMAT_AUDIO_MASK, ast_module_unref(), ast_safe_system(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, f, ast_format::format, free, and ast_format::module.
Referenced by get_filestream().
00285 { 00286 char *cmd = NULL; 00287 size_t size = 0; 00288 struct ast_filestream *f = arg; 00289 00290 /* Stop a running stream if there is one */ 00291 if (f->owner) { 00292 if (f->fmt->format < AST_FORMAT_AUDIO_MASK) { 00293 f->owner->stream = NULL; 00294 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00295 ast_settimeout(f->owner, 0, NULL, NULL); 00296 } else { 00297 f->owner->vstream = NULL; 00298 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00299 } 00300 } 00301 /* destroy the translator on exit */ 00302 if (f->trans) 00303 ast_translator_free_path(f->trans); 00304 00305 if (f->realfilename && f->filename) { 00306 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00307 cmd = alloca(size); 00308 memset(cmd,0,size); 00309 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00310 ast_safe_system(cmd); 00311 } 00312 00313 if (f->filename) 00314 free(f->filename); 00315 if (f->realfilename) 00316 free(f->realfilename); 00317 if (f->fmt->close) { 00318 void (*closefn)(struct ast_filestream *) = f->fmt->close; 00319 closefn(f); 00320 } 00321 if (f->f) 00322 fclose(f->f); 00323 if (f->vfs) 00324 ast_closestream(f->vfs); 00325 if (f->orig_chan_name) 00326 free((void *) f->orig_chan_name); 00327 ast_module_unref(f->fmt->module); 00328 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 354 of file file.c.
References ast_log(), ast_module_ref(), f, LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, s, and WRAP_OPEN.
Referenced by open_wrapper(), and rewrite_wrapper().
00355 { 00356 struct ast_format *f = s->fmt; 00357 int ret = -1; 00358 int (*openfn)(struct ast_filestream *s); 00359 00360 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s)) 00361 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00362 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00363 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00364 else { 00365 /* preliminary checks succeed. update usecount */ 00366 ast_module_ref(f->module); 00367 ret = 0; 00368 } 00369 return ret; 00370 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static] |
Definition at line 330 of file file.c.
References ao2_alloc, ast_format::buf_size, ast_format::desc_size, filestream_destructor(), ast_filestream::fmt, ast_format::name, and s.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00331 { 00332 struct ast_filestream *s; 00333 00334 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00335 if ( (s = ao2_alloc(l, filestream_destructor)) == NULL) 00336 return NULL; 00337 s->fmt = fmt; 00338 s->f = bfile; 00339 00340 if (fmt->desc_size) 00341 s->_private = ((char *)(s + 1)) + fmt->buf_size; 00342 if (fmt->buf_size) 00343 s->buf = (char *)(s + 1); 00344 s->fr.src = fmt->name; 00345 return s; 00346 }
static char* handle_cli_core_show_file_formats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1329 of file file.c.
References ast_cli_args::argc, ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_format::exts, f, ast_cli_args::fd, ast_format::format, FORMAT, FORMAT2, ast_format::list, ast_format::name, and ast_cli_entry::usage.
01330 { 01331 #define FORMAT "%-10s %-10s %-20s\n" 01332 #define FORMAT2 "%-10s %-10s %-20s\n" 01333 struct ast_format *f; 01334 int count_fmt = 0; 01335 01336 switch (cmd) { 01337 case CLI_INIT: 01338 e->command = "core show file formats"; 01339 e->usage = 01340 "Usage: core show file formats\n" 01341 " Displays currently registered file formats (if any).\n"; 01342 return NULL; 01343 case CLI_GENERATE: 01344 return NULL; 01345 } 01346 01347 if (a->argc != 4) 01348 return CLI_SHOWUSAGE; 01349 01350 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions"); 01351 ast_cli(a->fd, FORMAT, "------", "----", "----------"); 01352 01353 AST_RWLIST_RDLOCK(&formats); 01354 AST_RWLIST_TRAVERSE(&formats, f, list) { 01355 ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01356 count_fmt++; 01357 } 01358 AST_RWLIST_UNLOCK(&formats); 01359 ast_cli(a->fd, "%d file formats registered.\n", count_fmt); 01360 return CLI_SUCCESS; 01361 #undef FORMAT 01362 #undef FORMAT2 01363 }
static int is_absolute_path | ( | const char * | filename | ) | [static] |
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 377 of file file.c.
References fn_wrapper(), s, and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00378 { 00379 return fn_wrapper(s, NULL, WRAP_OPEN); 00380 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 372 of file file.c.
References fn_wrapper(), and s.
Referenced by ast_writefile().
00373 { 00374 return fn_wrapper(s, comment, WRAP_REWRITE); 00375 }
static int waitstream_core | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | reverse, | |||
int | skip_ms, | |||
int | audiofd, | |||
int | cmdfd, | |||
const char * | context | |||
) | [static] |
the core of all waitstream() functions
Definition at line 1139 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_SRCUPDATE, 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_channel::name, ast_filestream::orig_chan_name, ast_frame::ptr, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.
Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().
01142 { 01143 const char *orig_chan_name = NULL; 01144 int err = 0; 01145 01146 if (!breakon) 01147 breakon = ""; 01148 if (!forward) 01149 forward = ""; 01150 if (!reverse) 01151 reverse = ""; 01152 01153 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01154 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01155 01156 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01157 orig_chan_name = ast_strdupa(c->name); 01158 01159 while (c->stream) { 01160 int res; 01161 int ms; 01162 01163 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01164 ast_stopstream(c); 01165 err = 1; 01166 break; 01167 } 01168 01169 ms = ast_sched_wait(c->sched); 01170 01171 if (ms < 0 && !c->timingfunc) { 01172 ast_stopstream(c); 01173 break; 01174 } 01175 if (ms < 0) 01176 ms = 1000; 01177 if (cmdfd < 0) { 01178 res = ast_waitfor(c, ms); 01179 if (res < 0) { 01180 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01181 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01182 return res; 01183 } 01184 } else { 01185 int outfd; 01186 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01187 if (!rchan && (outfd < 0) && (ms)) { 01188 /* Continue */ 01189 if (errno == EINTR) 01190 continue; 01191 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01192 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01193 return -1; 01194 } else if (outfd > -1) { /* this requires cmdfd set */ 01195 /* The FD we were watching has something waiting */ 01196 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01197 return 1; 01198 } 01199 /* if rchan is set, it is 'c' */ 01200 res = rchan ? 1 : 0; /* map into 'res' values */ 01201 } 01202 if (res > 0) { 01203 struct ast_frame *fr = ast_read(c); 01204 if (!fr) { 01205 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01206 return -1; 01207 } 01208 switch (fr->frametype) { 01209 case AST_FRAME_DTMF_END: 01210 if (context) { 01211 const char exten[2] = { fr->subclass, '\0' }; 01212 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01213 res = fr->subclass; 01214 ast_frfree(fr); 01215 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01216 return res; 01217 } 01218 } else { 01219 res = fr->subclass; 01220 if (strchr(forward, res)) { 01221 ast_stream_fastforward(c->stream, skip_ms); 01222 } else if (strchr(reverse, res)) { 01223 ast_stream_rewind(c->stream, skip_ms); 01224 } else if (strchr(breakon, res)) { 01225 ast_frfree(fr); 01226 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01227 return res; 01228 } 01229 } 01230 break; 01231 case AST_FRAME_CONTROL: 01232 switch (fr->subclass) { 01233 case AST_CONTROL_HANGUP: 01234 case AST_CONTROL_BUSY: 01235 case AST_CONTROL_CONGESTION: 01236 ast_frfree(fr); 01237 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01238 return -1; 01239 case AST_CONTROL_RINGING: 01240 case AST_CONTROL_ANSWER: 01241 case AST_CONTROL_VIDUPDATE: 01242 case AST_CONTROL_SRCUPDATE: 01243 case AST_CONTROL_HOLD: 01244 case AST_CONTROL_UNHOLD: 01245 case -1: 01246 /* Unimportant */ 01247 break; 01248 default: 01249 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01250 } 01251 break; 01252 case AST_FRAME_VOICE: 01253 /* Write audio if appropriate */ 01254 if (audiofd > -1) { 01255 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) { 01256 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01257 } 01258 } 01259 default: 01260 /* Ignore all others */ 01261 break; 01262 } 01263 ast_frfree(fr); 01264 } 01265 ast_sched_runq(c->sched); 01266 } 01267 01268 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01269 01270 return (err || c->_softhangup) ? -1 : 0; 01271 }
int ast_language_is_prefix = 1 |
struct ast_cli_entry cli_file[] |
Initial value:
{ { .handler = handle_cli_core_show_file_formats , .summary = "Displays file formats" ,__VA_ARGS__ } }
Definition at line 1365 of file file.c.
Referenced by ast_file_init().