Generic File Format Support. More...
#include "asterisk.h"#include <dirent.h>#include <sys/stat.h>#include <sys/wait.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"#include "asterisk/test.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 format_t | 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. | |
| char * | ast_format_str_reduce (char *fmts) |
| 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) |
| struct ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
| Opens stream for use in seeking, playing. | |
| 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. | |
| struct 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) |
| 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. | |
| struct 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) |
| 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. | |
| 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 format_t | 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 '_' suffices, or NULL. | |
| static format_t | 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 struct ast_frame * | read_frame (struct ast_filestream *s, int *whennext) |
| 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 |
| static struct ast_cli_entry | cli_file [] |
| static struct formats | formats |
Generic File Format Support.
Definition in file file.c.
| #define FORMAT "%-10s %-10s %-20s\n" |
| #define FORMAT2 "%-10s %-10s %-20s\n" |
| enum file_action |
Definition at line 397 of file file.c.
{
ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
ACTION_OPEN,
ACTION_COPY /* copy file. return 0 on success, -1 on error */
};
| enum fsread_res |
| enum wrap_fn |
Definition at line 367 of file file.c.
{ WRAP_OPEN, WRAP_REWRITE };
| 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 63 of file file.c.
References AST_RWLIST_WRLOCK, AST_RWLIST_TRAVERSE, ast_format::list, ast_format::name, AST_RWLIST_UNLOCK, ast_log(), LOG_WARNING, ast_calloc, f, ast_format::module, ast_format::buf_size, AST_RWLIST_INSERT_HEAD, ast_verb, and ast_format::exts.
{
struct ast_format *tmp;
AST_RWLIST_WRLOCK(&formats);
AST_RWLIST_TRAVERSE(&formats, tmp, list) {
if (!strcasecmp(f->name, tmp->name)) {
AST_RWLIST_UNLOCK(&formats);
ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
return -1;
}
}
if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
AST_RWLIST_UNLOCK(&formats);
return -1;
}
*tmp = *f;
tmp->module = mod;
if (tmp->buf_size) {
/*
* Align buf_size properly, rounding up to the machine-specific
* alignment for pointers.
*/
struct _test_align { void *a, *b; } p;
int align = (char *)&p.b - (char *)&p.a;
tmp->buf_size = ((f->buf_size + align - 1) / align) * align;
}
memset(&tmp->list, 0, sizeof(tmp->list));
AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
AST_RWLIST_UNLOCK(&formats);
ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts);
return 0;
}
| 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 850 of file file.c.
References ast_filestream::owner.
Referenced by speech_streamfile(), ast_streamfile(), handle_streamfile(), handle_getoption(), and handle_recordfile().
{
s->owner = chan;
return 0;
}
| 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 893 of file file.c.
References ast_filestream::owner, ast_filestream::fmt, ast_format::format, AST_FORMAT_AUDIO_MASK, ast_channel::stream, AST_SCHED_DEL, ast_channel::sched, ast_channel::streamid, ast_settimeout(), ast_channel::vstream, ast_channel::vstreamid, and ao2_ref.
Referenced by __ast_play_and_record(), dictate_exec(), gen_closestream(), recordthread(), mixmonitor_ds_close_fs(), record_exec(), rpt(), ast_hangup(), ast_stopstream(), filestream_destructor(), ast_filehelper(), ast_readfile(), ast_writefile(), handle_recordfile(), handle_cli_file_convert(), ast_monitor_start(), ast_monitor_stop(), moh_files_release(), ast_moh_files_next(), and local_ast_moh_stop().
{
/* This used to destroy the filestream, but it now just decrements a refcount.
* We need to force the stream to quit queuing frames now, because we might
* change the writeformat, which could result in a subsequent write error, if
* the format is different. */
/* Stop a running stream if there is one */
if (f->owner) {
if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
f->owner->stream = NULL;
AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
ast_settimeout(f->owner, 0, NULL, NULL);
} else {
f->owner->vstream = NULL;
AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
}
}
ao2_ref(f, -1);
return 0;
}
| int ast_file_init | ( | void | ) |
Provided by file.c
Definition at line 1484 of file file.c.
References ast_cli_register_multiple(), and ARRAY_LEN.
Referenced by main().
{
ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
return 0;
}
| 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 944 of file file.c.
References ast_filehelper(), and ACTION_COPY.
Referenced by copy_plain_file(), and vm_forwardoptions().
{
return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
}
| 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 934 of file file.c.
References ast_filehelper(), and ACTION_DELETE.
Referenced by __ast_play_and_record(), setup_privacy_args(), dial_exec_full(), conf_free(), announce_thread(), conf_run(), vm_delete(), leave_voicemail(), record_exec(), play_record_review(), handle_cli_file_convert(), ast_monitor_start(), and ast_monitor_stop().
{
return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
}
| 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 920 of file file.c.
References ast_filestream::buf, and fileexists_core().
Referenced by common_exec(), setup_privacy_args(), dial_exec_full(), retrydial_exec(), eivr_comm(), app_exec(), announce_thread(), conf_run(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), readexten_exec(), record_exec(), saynode(), rpt_tele_thread(), function_playback(), get_folder(), forward_message(), play_message_callerid(), play_message(), vm_intro(), vm_newuser(), vm_options(), vm_tempgreeting(), sayname(), ast_monitor_start(), ast_monitor_stop(), ast_moh_files_next(), say_character_str_full(), say_phonetic_str_full(), and say_digit_str_full().
{
char *buf;
int buflen;
if (preflang == NULL)
preflang = "";
buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
buf = alloca(buflen);
if (buf == NULL)
return 0;
return fileexists_core(filename, fmt, preflang, buf, buflen);
}
| static format_t 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 414 of file file.c.
References f, ACTION_EXISTS, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, ast_format::list, ext, exts_compare(), ast_format::exts, ast_strdupa, strsep(), build_filename(), ast_free, ACTION_OPEN, ast_channel::writeformat, ast_format::format, AST_FORMAT_AUDIO_MASK, ast_filestream::fmt, AST_FORMAT_VIDEO_MASK, get_filestream(), open_wrapper(), ast_closestream(), ast_log(), LOG_WARNING, ast_filestream::lasttimeout, ast_filestream::trans, ast_filestream::filename, ast_channel::stream, ast_channel::vstream, ACTION_DELETE, errno, ACTION_RENAME, ACTION_COPY, copy(), and AST_RWLIST_UNLOCK.
Referenced by fileexists_test(), ast_openstream_full(), ast_openvstream(), ast_filedelete(), ast_filerename(), and ast_filecopy().
{
struct ast_format *f;
format_t res = (action == ACTION_EXISTS) ? 0 : -1;
AST_RWLIST_RDLOCK(&formats);
/* Check for a specific format */
AST_RWLIST_TRAVERSE(&formats, f, list) {
char *stringp, *ext = NULL;
if (fmt && !exts_compare(f->exts, fmt))
continue;
/* Look for a file matching the supported extensions.
* The file must exist, and for OPEN, must match
* one of the formats supported by the channel.
*/
stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */
while ( (ext = strsep(&stringp, "|")) ) {
struct stat st;
char *fn = build_filename(filename, ext);
if (fn == NULL)
continue;
if ( stat(fn, &st) ) { /* file not existent */
ast_free(fn);
continue;
}
/* for 'OPEN' we need to be sure that the format matches
* what the channel can process
*/
if (action == ACTION_OPEN) {
struct ast_channel *chan = (struct ast_channel *)arg2;
FILE *bfile;
struct ast_filestream *s;
if ( !(chan->writeformat & f->format) &&
!((f->format & AST_FORMAT_AUDIO_MASK && fmt) ||
(f->format & AST_FORMAT_VIDEO_MASK && fmt))) {
ast_free(fn);
continue; /* not a supported format */
}
if ( (bfile = fopen(fn, "r")) == NULL) {
ast_free(fn);
continue; /* cannot open file */
}
s = get_filestream(f, bfile);
if (!s) {
fclose(bfile);
ast_free(fn); /* cannot allocate descriptor */
continue;
}
if (open_wrapper(s)) {
ast_free(fn);
ast_closestream(s);
continue; /* cannot run open on file */
}
if (st.st_size == 0) {
ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn);
}
/* ok this is good for OPEN */
res = 1; /* found */
s->lasttimeout = -1;
s->fmt = f;
s->trans = NULL;
s->filename = NULL;
if (s->fmt->format & AST_FORMAT_AUDIO_MASK) {
if (chan->stream)
ast_closestream(chan->stream);
chan->stream = s;
} else {
if (chan->vstream)
ast_closestream(chan->vstream);
chan->vstream = s;
}
ast_free(fn);
break;
}
switch (action) {
case ACTION_OPEN:
break; /* will never get here */
case ACTION_EXISTS: /* return the matching format */
res |= f->format;
break;
case ACTION_DELETE:
if ( (res = unlink(fn)) )
ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
break;
case ACTION_RENAME:
case ACTION_COPY: {
char *nfn = build_filename((const char *)arg2, ext);
if (!nfn)
ast_log(LOG_WARNING, "Out of memory\n");
else {
res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
if (res)
ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
action == ACTION_COPY ? "copy" : "rename",
fn, nfn, strerror(errno));
ast_free(nfn);
}
}
break;
default:
ast_log(LOG_WARNING, "Unknown helper %d\n", action);
}
ast_free(fn);
}
}
AST_RWLIST_UNLOCK(&formats);
return res;
}
| 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 939 of file file.c.
References ast_filehelper(), and ACTION_RENAME.
Referenced by __ast_play_and_record(), rename_file(), leave_voicemail(), vm_forwardoptions(), forward_message(), play_record_review(), and ast_monitor_stop().
{
return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
}
| char* ast_format_str_reduce | ( | char * | fmts | ) |
Remove duplicate formats from a format string.
| fmts | a format string, this string will be modified |
| NULL | error |
Definition at line 1368 of file file.c.
References f, AST_MAX_FORMATS, type, first, len(), AST_RWLIST_RDLOCK, ast_log(), LOG_WARNING, ast_strdupa, strsep(), AST_RWLIST_TRAVERSE, ast_format::list, exts_compare(), ast_format::exts, and AST_RWLIST_UNLOCK.
Referenced by load_config().
{
struct ast_format *f;
struct ast_format *fmts_ptr[AST_MAX_FORMATS];
char *fmts_str[AST_MAX_FORMATS];
char *stringp, *type;
char *orig = fmts;
int i, j, x, first, found = 0;
int len = strlen(fmts) + 1;
int res;
if (AST_RWLIST_RDLOCK(&formats)) {
ast_log(LOG_WARNING, "Unable to lock format list\n");
return NULL;
}
stringp = ast_strdupa(fmts);
for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
AST_RWLIST_TRAVERSE(&formats, f, list) {
if (exts_compare(f->exts, type)) {
found = 1;
break;
}
}
fmts_str[x] = type;
if (found) {
fmts_ptr[x] = f;
} else {
fmts_ptr[x] = NULL;
}
}
AST_RWLIST_UNLOCK(&formats);
first = 1;
for (i = 0; i < x; i++) {
/* ignore invalid entries */
if (!fmts_ptr[i]) {
ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
continue;
}
/* special handling for the first entry */
if (first) {
res = snprintf(fmts, len, "%s", fmts_str[i]);
fmts += res;
len -= res;
first = 0;
continue;
}
found = 0;
for (j = 0; j < i; j++) {
/* this is a duplicate */
if (fmts_ptr[j] == fmts_ptr[i]) {
found = 1;
break;
}
}
if (!found) {
res = snprintf(fmts, len, "|%s", fmts_str[i]);
fmts += res;
len -= res;
}
}
if (first) {
ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
return NULL;
}
return orig;
}
| 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 100 of file file.c.
References AST_RWLIST_WRLOCK, AST_RWLIST_TRAVERSE_SAFE_BEGIN, ast_format::list, ast_format::name, AST_RWLIST_REMOVE_CURRENT, ast_free, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, ast_verb, ast_log(), and LOG_WARNING.
Referenced by unload_module().
{
struct ast_format *tmp;
int res = -1;
AST_RWLIST_WRLOCK(&formats);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
if (!strcasecmp(name, tmp->name)) {
AST_RWLIST_REMOVE_CURRENT(list);
ast_free(tmp);
res = 0;
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&formats);
if (!res)
ast_verb(2, "Unregistered format %s\n", name);
else
ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
return res;
}
| static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 790 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
{
struct ast_filestream *fs = (struct ast_filestream *)data;
enum fsread_res res;
res = ast_readaudio_callback(fs);
if (res == FSREAD_SUCCESS_SCHED)
return 1;
return 0;
}
| static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 837 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
{
struct ast_filestream *fs = (struct ast_filestream *)data;
enum fsread_res res;
res = ast_readvideo_callback(fs);
if (res == FSREAD_SUCCESS_SCHED)
return 1;
return 0;
}
| 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 |
| a | ast_filestream pointer if it opens the file. |
| NULL | on error. |
Definition at line 621 of file file.c.
References ast_openstream_full().
Referenced by dictate_exec(), speech_streamfile(), ast_streamfile(), handle_streamfile(), and handle_getoption().
{
return ast_openstream_full(chan, filename, preflang, 0);
}
| 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 |
| a | ast_filestream pointer if it opens the file. |
| NULL | on error. |
Definition at line 626 of file file.c.
References ast_filestream::buf, ast_stopstream(), ast_channel::generator, ast_deactivate_generator(), fileexists_core(), AST_FORMAT_AUDIO_MASK, ast_log(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::writeformat, ast_set_write_format(), ast_filehelper(), ACTION_OPEN, and ast_channel::stream.
Referenced by gen_nextfile(), ast_openstream(), and ast_moh_files_next().
{
/*
* Use fileexists_core() to find a file in a compatible
* language and format, set up a suitable translator,
* and open the stream.
*/
format_t fmts, res;
int buflen;
char *buf;
if (!asis) {
/* do this first, otherwise we detect the wrong writeformat */
ast_stopstream(chan);
if (chan->generator)
ast_deactivate_generator(chan);
}
if (preflang == NULL)
preflang = "";
buflen = strlen(preflang) + strlen(filename) + 4;
buf = alloca(buflen);
if (buf == NULL)
return NULL;
fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
if (fmts > 0)
fmts &= AST_FORMAT_AUDIO_MASK;
if (fmts < 1) {
ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
return NULL;
}
chan->oldwriteformat = chan->writeformat;
/* Set the channel to a format we can work with */
res = ast_set_write_format(chan, fmts);
if (res == -1) { /* No format available that works with this channel */
return NULL;
}
res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
if (res >= 0)
return chan->stream;
return NULL;
}
| 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 |
| a | ast_filestream pointer if it opens the file. |
| NULL | on error. |
Definition at line 668 of file file.c.
References format, ast_filestream::buf, AST_FORMAT_FIRST_VIDEO_BIT, AST_FORMAT_VIDEO_MASK, ast_filestream::fmt, ast_channel::nativeformats, ast_getformatname(), fileexists_core(), ast_filehelper(), ACTION_OPEN, ast_channel::vstream, ast_log(), and LOG_WARNING.
Referenced by ast_streamfile(), handle_streamfile(), and handle_getoption().
{
/* As above, but for video. But here we don't have translators
* so we must enforce a format.
*/
format_t format;
char *buf;
int buflen;
if (preflang == NULL)
preflang = "";
buflen = strlen(preflang) + strlen(filename) + 4;
buf = alloca(buflen);
if (buf == NULL)
return NULL;
for (format = AST_FORMAT_FIRST_VIDEO_BIT; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) {
int fd;
const char *fmt;
if (!(chan->nativeformats & format))
continue;
fmt = ast_getformatname(format);
if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */
continue;
fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
if (fd >= 0)
return chan->vstream;
ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
}
return NULL;
}
| 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 856 of file file.c.
References ast_filestream::fmt, ast_format::format, AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), and FSREAD_FAILURE.
Referenced by speech_streamfile(), ast_streamfile(), handle_streamfile(), and handle_getoption().
{
enum fsread_res res;
if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
res = ast_readaudio_callback(s);
else
res = ast_readvideo_callback(s);
return (res == FSREAD_FAILURE) ? -1 : 0;
}
| static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 741 of file file.c.
References ast_filestream::orig_chan_name, ast_filestream::owner, ast_channel::name, read_frame(), ast_write(), ast_log(), LOG_WARNING, ast_frfree, ast_filestream::lasttimeout, ast_channel::timingfd, ast_format_rate(), ast_filestream::fmt, ast_format::format, ast_settimeout(), ast_fsread_audio(), ast_channel::streamid, ast_sched_add(), ast_channel::sched, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, and FSREAD_FAILURE.
Referenced by ast_fsread_audio(), and ast_playstream().
{
int whennext = 0;
while (!whennext) {
struct ast_frame *fr;
if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) {
goto return_failure;
}
fr = read_frame(s, &whennext);
if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
if (fr) {
ast_log(LOG_WARNING, "Failed to write frame\n");
ast_frfree(fr);
}
goto return_failure;
}
if (fr) {
ast_frfree(fr);
}
}
if (whennext != s->lasttimeout) {
if (s->owner->timingfd > -1) {
float samp_rate = (float) ast_format_rate(s->fmt->format);
unsigned int rate;
rate = (unsigned int) roundf(samp_rate / ((float) whennext));
ast_settimeout(s->owner, rate, ast_fsread_audio, s);
} else {
s->owner->streamid = ast_sched_add(s->owner->sched,
whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
}
s->lasttimeout = whennext;
return FSREAD_SUCCESS_NOSCHED;
}
return FSREAD_SUCCESS_SCHED;
return_failure:
s->owner->streamid = -1;
ast_settimeout(s->owner, 0, NULL, NULL);
return FSREAD_FAILURE;
}
| 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. |
| a | struct ast_filestream on success. |
| NULL | on failure. |
Definition at line 993 of file file.c.
References f, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, exts_compare(), ast_format::exts, build_filename(), errno, get_filestream(), open_wrapper(), ast_log(), LOG_WARNING, ast_closestream(), ast_free, ast_filestream::trans, ast_filestream::fmt, ast_filestream::flags, ast_filestream::mode, ast_filestream::filename, ast_strdup, ast_filestream::vfs, and AST_RWLIST_UNLOCK.
Referenced by __ast_play_and_record(), and handle_cli_file_convert().
{
FILE *bfile;
struct ast_format *f;
struct ast_filestream *fs = NULL;
char *fn;
int format_found = 0;
AST_RWLIST_RDLOCK(&formats);
AST_RWLIST_TRAVERSE(&formats, f, list) {
fs = NULL;
if (!exts_compare(f->exts, type))
continue;
else
format_found = 1;
fn = build_filename(filename, type);
errno = 0;
bfile = fopen(fn, "r");
if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
ast_log(LOG_WARNING, "Unable to open %s\n", fn);
if (fs) {
ast_closestream(fs);
}
fs = NULL;
bfile = NULL;
ast_free(fn);
break;
}
/* found it */
fs->trans = NULL;
fs->fmt = f;
fs->flags = flags;
fs->mode = mode;
fs->filename = ast_strdup(filename);
fs->vfs = NULL;
break;
}
AST_RWLIST_UNLOCK(&formats);
if (!format_found)
ast_log(LOG_WARNING, "No such format '%s'\n", type);
return fs;
}
| struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) | [read] |
Read a frame from a filestream.
| s | ast_filestream to act on |
| NULL | if read failed. |
Definition at line 726 of file file.c.
References read_frame().
Referenced by __ast_play_and_record(), dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().
{
int whennext = 0;
return read_frame(s, &whennext);
}
| static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 805 of file file.c.
References read_frame(), ast_write(), ast_filestream::owner, ast_log(), LOG_WARNING, ast_frfree, ast_channel::vstreamid, FSREAD_FAILURE, ast_filestream::lasttimeout, ast_sched_add(), ast_channel::sched, ast_format_rate(), ast_filestream::fmt, ast_format::format, ast_fsread_video(), FSREAD_SUCCESS_NOSCHED, and FSREAD_SUCCESS_SCHED.
Referenced by ast_fsread_video(), and ast_playstream().
{
int whennext = 0;
while (!whennext) {
struct ast_frame *fr = read_frame(s, &whennext);
if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
if (fr) {
ast_log(LOG_WARNING, "Failed to write frame\n");
ast_frfree(fr);
}
s->owner->vstreamid = -1;
return FSREAD_FAILURE;
}
if (fr) {
ast_frfree(fr);
}
}
if (whennext != s->lasttimeout) {
s->owner->vstreamid = ast_sched_add(s->owner->sched,
whennext / (ast_format_rate(s->fmt->format) / 1000),
ast_fsread_video, s);
s->lasttimeout = whennext;
return FSREAD_SUCCESS_NOSCHED;
}
return FSREAD_SUCCESS_SCHED;
}
| 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 868 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by ast_control_streamfile(), dictate_exec(), __ast_read(), ast_write(), ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), handle_streamfile(), handle_getoption(), handle_recordfile(), speech_streamfile(), and ast_moh_files_next().
| int ast_stopstream | ( | struct ast_channel * | c | ) |
Stops a stream.
| c | The channel you wish to stop playback on |
Stop playback of a stream
| 0 | always |
Definition at line 124 of file file.c.
References ast_channel_lock, ast_channel::stream, ast_closestream(), ast_channel::oldwriteformat, ast_set_write_format(), ast_log(), LOG_WARNING, ast_getformatname(), ast_channel::vstream, and ast_channel_unlock.
Referenced by ast_control_streamfile(), ast_play_and_wait(), ivr_dispatch(), menu_callback(), dial_exec_full(), play_mailbox_owner(), select_item_seq(), directory_exec(), send_waveform_to_channel(), wait_for_winner(), ices_exec(), conf_run(), conf_exec(), recordthread(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), s_streamwait3(), playback_exec(), play_file(), queue_exec(), read_exec(), readexten_exec(), record_exec(), send_morse(), send_tone_telemetry(), sayfile(), saycharstr(), saynum(), rpt_tele_thread(), speech_background(), background_detect_exec(), leave_voicemail(), vm_authenticate(), vm_execmain(), zapateller_exec(), grab_transfer(), ast_readstring_full(), ast_openstream_full(), waitstream_core(), pbx_builtin_background(), ast_adsi_transmit_message_full(), handle_streamfile(), handle_getoption(), handle_speechrecognize(), say_character_str_full(), say_phonetic_str_full(), say_digit_str_full(), ast_say_number_full_en(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), 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(), pl_odtworz_plik(), ast_say_number_full_pt(), ast_say_number_full_se(), ast_say_number_full_zh(), ast_say_number_full_ur(), ast_say_number_full_ru(), ast_say_number_full_th(), ast_say_number_full_vi(), ast_say_enumeration_full_en(), ast_say_enumeration_full_vi(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_he(), ast_say_number_full_gr(), and ast_say_number_full_ka().
{
ast_channel_lock(tmp);
/* Stop a running stream if there is one */
if (tmp->stream) {
ast_closestream(tmp->stream);
tmp->stream = NULL;
if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_getformatname(tmp->oldwriteformat));
}
/* Stop the video stream too */
if (tmp->vstream != NULL) {
ast_closestream(tmp->vstream);
tmp->vstream = NULL;
}
ast_channel_unlock(tmp);
return 0;
}
| 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 1355 of file file.c.
References ast_strlen_zero(), ast_test_suite_event_notify, ast_streamfile(), ast_channel::language, and ast_waitstream().
Referenced by __ast_play_and_record(), ast_record_review(), ivr_dispatch(), announce_user_count(), play_prompt_to_channel(), join_conference_bridge(), play_sound_file(), menu_callback(), confbridge_exec(), play_mailbox_owner(), select_item_seq(), directory_exec(), app_exec(), play_record_review(), invent_message(), leave_voicemail(), vm_forwardoptions(), forward_message(), wait_file2(), play_message_callerid(), sayname(), vmsayname_exec(), grab_transfer(), feature_blind_transfer(), feature_attended_transfer(), bridge_playfile(), masq_park_call(), xfer_park_call_helper(), play_message_on_chan(), builtin_automixmonitor(), builtin_blindtransfer(), builtin_atxfer(), park_call_exec(), parked_call_exec(), and ast_pickup_call().
{
int res = 0;
if (!ast_strlen_zero(file)) {
ast_test_suite_event_notify("PLAYBACK", "Message: %s", file);
res = ast_streamfile(chan, file, chan->language);
if (!res) {
res = ast_waitstream(chan, digits);
}
}
return res;
}
| 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 883 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
{
return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
}
| 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 888 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), record_exec(), waitstream_core(), and handle_recordfile().
{
return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
}
| 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 949 of file file.c.
References ast_filestream::vfs, ast_filestream::fmt, ast_openstream(), ast_log(), LOG_WARNING, ast_getformatname_multiple(), ast_channel::nativeformats, errno, ast_filestream::f, ast_seekstream(), ast_openvstream(), ast_debug, ast_getformatname(), ast_format::format, ast_test_flag, AST_FLAG_MASQ_NOSTREAM, ast_filestream::orig_chan_name, ast_strdup, ast_channel::name, ast_applystream(), ast_playstream(), ast_verb, and ast_channel::writeformat.
Referenced by ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), auth_exec(), common_exec(), menu_callback(), setup_privacy_args(), dial_exec_full(), retrydial_exec(), play_and_wait(), select_item_menu(), do_directory(), wait_for_winner(), app_exec(), announce_thread(), conf_run(), find_conf_realtime(), conf_exec(), invent_message(), play_record_review(), leave_voicemail(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), s_streamwait3(), playback_exec(), privacy_exec(), play_file(), readexten_exec(), record_exec(), sayfile(), rpt_tele_thread(), background_detect_exec(), forward_message(), vm_authenticate(), agent_call(), check_availability(), check_beep(), login_exec(), analog_ss_thread(), local_attended_transfer(), action_bridge(), bridge_exec(), ast_stream_and_wait(), pbx_builtin_background(), handle_recordfile(), say_character_str_full(), say_phonetic_str_full(), say_digit_str_full(), wait_file(), ast_say_number_full_en(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), 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(), pl_odtworz_plik(), ast_say_number_full_pt(), ast_say_number_full_se(), ast_say_number_full_zh(), ast_say_number_full_ur(), ast_say_number_full_ru(), ast_say_number_full_th(), ast_say_number_full_vi(), ast_say_enumeration_full_en(), ast_say_enumeration_full_vi(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_he(), ast_say_date_en(), ast_say_date_da(), ast_say_date_de(), ast_say_date_hu(), ast_say_date_fr(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_he(), ast_say_time_en(), ast_say_time_de(), ast_say_time_hu(), ast_say_time_fr(), ast_say_time_nl(), ast_say_time_zh(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_datetime_he(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), gr_say_number_female(), ast_say_number_full_gr(), ast_say_date_gr(), ast_say_time_gr(), ast_say_datetime_gr(), ast_say_date_with_format_gr(), ast_say_number_full_ka(), ast_say_date_ka(), ast_say_time_ka(), ast_say_datetime_from_now_ka(), and __analog_ss_thread().
{
struct ast_filestream *fs;
struct ast_filestream *vfs=NULL;
char fmt[256];
int seekattempt;
int res;
fs = ast_openstream(chan, filename, preflang);
if (!fs) {
ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
return -1;
}
/* check to see if there is any data present (not a zero length file),
* done this way because there is no where for ast_openstream_full to
* return the file had no data. */
seekattempt = fseek(fs->f, -1, SEEK_END);
if (seekattempt && errno == EINVAL) {
/* Zero-length file, as opposed to a pipe */
return 0;
} else {
ast_seekstream(fs, 0, SEEK_SET);
}
vfs = ast_openvstream(chan, filename, preflang);
if (vfs) {
ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
}
if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
fs->orig_chan_name = ast_strdup(chan->name);
if (ast_applystream(chan, fs))
return -1;
if (vfs && ast_applystream(chan, vfs))
return -1;
res = ast_playstream(fs);
if (!res && vfs)
res = ast_playstream(vfs);
ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
return res;
}
| off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream.
| fs | fs to act on |
Definition at line 878 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by ast_control_streamfile(), __ast_play_and_record(), handle_streamfile(), handle_getoption(), handle_recordfile(), handle_speechrecognize(), and ast_moh_files_next().
| 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 873 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by __ast_play_and_record(), record_exec(), 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 1328 of file file.c.
References waitstream_core().
Referenced by ast_play_and_wait(), auth_exec(), common_exec(), menu_callback(), setup_privacy_args(), retrydial_exec(), play_and_wait(), select_item_menu(), directory_exec(), app_exec(), announce_thread(), conf_run(), find_conf_realtime(), conf_exec(), invent_message(), play_record_review(), leave_voicemail(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), s_streamwait3(), playback_exec(), privacy_exec(), play_file(), record_exec(), send_morse(), send_tone_telemetry(), sayfile(), saycharstr(), saynum(), rpt_tele_thread(), vm_authenticate(), agent_call(), check_availability(), check_beep(), login_exec(), analog_ss_thread(), local_attended_transfer(), action_bridge(), bridge_exec(), ast_stream_and_wait(), pbx_builtin_background(), handle_recordfile(), say_character_str_full(), say_phonetic_str_full(), say_digit_str_full(), wait_file(), ast_say_number_full_en(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), 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(), pl_odtworz_plik(), ast_say_number_full_pt(), ast_say_number_full_se(), ast_say_number_full_zh(), ast_say_number_full_ur(), ast_say_number_full_ru(), ast_say_number_full_th(), ast_say_number_full_vi(), ast_say_enumeration_full_en(), ast_say_enumeration_full_vi(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_he(), ast_say_date_en(), ast_say_date_da(), ast_say_date_de(), ast_say_date_hu(), ast_say_date_fr(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_he(), ast_say_time_en(), ast_say_time_de(), ast_say_time_hu(), ast_say_time_nl(), ast_say_time_zh(), ast_say_time_he(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_datetime_he(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), gr_say_number_female(), ast_say_number_full_gr(), ast_say_date_gr(), ast_say_time_gr(), ast_say_datetime_gr(), ast_say_date_with_format_gr(), ast_say_number_full_ka(), ast_say_date_ka(), ast_say_time_ka(), ast_say_datetime_from_now_ka(), and __analog_ss_thread().
{
return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
}
| 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 1339 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
{
/* Waitstream, with return in the case of a valid 1 digit extension */
/* in the current or specified context being pressed */
if (!context)
context = c->context;
return waitstream_core(c, NULL, NULL, NULL, 0,
-1, -1, context);
}
| 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 1322 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
{
return waitstream_core(c, breakon, forward, reverse, ms,
-1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
}
| 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 1333 of file file.c.
References waitstream_core().
Referenced by s_streamwait3(), ast_readstring_full(), handle_streamfile(), handle_getoption(), say_character_str_full(), say_phonetic_str_full(), say_digit_str_full(), ast_say_number_full_en(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), 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(), pl_odtworz_plik(), ast_say_number_full_pt(), ast_say_number_full_se(), ast_say_number_full_zh(), ast_say_number_full_ur(), ast_say_number_full_ru(), ast_say_number_full_th(), ast_say_number_full_vi(), ast_say_enumeration_full_en(), ast_say_enumeration_full_vi(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_he(), ast_say_number_full_gr(), and ast_say_number_full_ka().
{
return waitstream_core(c, breakon, NULL, NULL, 0,
audiofd, cmdfd, NULL /* no context */);
}
| 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. |
| a | struct ast_filestream on success. |
| NULL | on failure. |
Definition at line 1041 of file file.c.
References f, ast_filestream::buf, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, exts_compare(), ast_format::exts, build_filename(), ast_log(), LOG_WARNING, errno, ast_opt_cache_record_files, ast_strdupa, record_cache_dir, ast_free, get_filestream(), ast_filestream::write_buffer, ast_malloc, ast_filestream::f, rewrite_wrapper(), ast_closestream(), ast_filestream::trans, ast_filestream::fmt, ast_filestream::flags, ast_filestream::mode, ast_filestream::realfilename, ast_strdup, ast_filestream::filename, ast_filestream::vfs, ast_format::seek, and AST_RWLIST_UNLOCK.
Referenced by __ast_play_and_record(), dictate_exec(), recordthread(), mixmonitor_thread(), record_exec(), rpt(), ast_writestream(), handle_recordfile(), handle_cli_file_convert(), and ast_monitor_start().
{
int fd, myflags = 0;
/* compiler claims this variable can be used before initialization... */
FILE *bfile = NULL;
struct ast_format *f;
struct ast_filestream *fs = NULL;
char *buf = NULL;
size_t size = 0;
int format_found = 0;
AST_RWLIST_RDLOCK(&formats);
/* set the O_TRUNC flag if and only if there is no O_APPEND specified */
/* We really can't use O_APPEND as it will break WAV header updates */
if (flags & O_APPEND) {
flags &= ~O_APPEND;
} else {
myflags = O_TRUNC;
}
myflags |= O_WRONLY | O_CREAT;
/* XXX need to fix this - we should just do the fopen,
* not open followed by fdopen()
*/
AST_RWLIST_TRAVERSE(&formats, f, list) {
char *fn, *orig_fn = NULL;
if (fs)
break;
if (!exts_compare(f->exts, type))
continue;
else
format_found = 1;
fn = build_filename(filename, type);
fd = open(fn, flags | myflags, mode);
if (fd > -1) {
/* fdopen() the resulting file stream */
bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
if (!bfile) {
ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
close(fd);
fd = -1;
}
}
if (ast_opt_cache_record_files && (fd > -1)) {
char *c;
fclose(bfile); /* this also closes fd */
/*
We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
*/
orig_fn = ast_strdupa(fn);
for (c = fn; *c; c++)
if (*c == '/')
*c = '_';
size = strlen(fn) + strlen(record_cache_dir) + 2;
buf = alloca(size);
strcpy(buf, record_cache_dir);
strcat(buf, "/");
strcat(buf, fn);
ast_free(fn);
fn = buf;
fd = open(fn, flags | myflags, mode);
if (fd > -1) {
/* fdopen() the resulting file stream */
bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
if (!bfile) {
ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
close(fd);
fd = -1;
}
}
}
if (fd > -1) {
errno = 0;
fs = get_filestream(f, bfile);
if (fs) {
if ((fs->write_buffer = ast_malloc(32768))) {
setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768);
}
}
if (!fs || rewrite_wrapper(fs, comment)) {
ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
close(fd);
if (orig_fn) {
unlink(fn);
unlink(orig_fn);
}
if (fs) {
ast_closestream(fs);
fs = NULL;
}
continue;
}
fs->trans = NULL;
fs->fmt = f;
fs->flags = flags;
fs->mode = mode;
if (orig_fn) {
fs->realfilename = ast_strdup(orig_fn);
fs->filename = ast_strdup(fn);
} else {
fs->realfilename = NULL;
fs->filename = ast_strdup(filename);
}
fs->vfs = NULL;
/* If truncated, we'll be at the beginning; if not truncated, then append */
f->seek(fs, 0, SEEK_END);
} else if (errno != EEXIST) {
ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
if (orig_fn)
unlink(orig_fn);
}
/* if buf != NULL then fn is already free and pointing to it */
if (!buf)
ast_free(fn);
}
AST_RWLIST_UNLOCK(&formats);
if (!format_found)
ast_log(LOG_WARNING, "No such format '%s'\n", type);
return fs;
}
| 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 146 of file file.c.
References ast_frame::frametype, AST_FRAME_VIDEO, ast_filestream::fmt, ast_format::format, AST_FORMAT_AUDIO_MASK, ast_filestream::vfs, ast_filestream::filename, type, ast_getformatname(), ast_frame::subclass, ast_frame_subclass::codec, ast_writefile(), ast_filestream::flags, ast_filestream::mode, ast_debug, ast_writestream(), AST_FRAME_VOICE, ast_log(), LOG_WARNING, ast_format::write, ast_filestream::trans, ast_filestream::lastwriteformat, ast_translator_free_path(), ast_translator_build_path(), ast_format::name, ast_translate(), AST_LIST_NEXT, and ast_frfree.
Referenced by __ast_play_and_record(), dictate_exec(), recordthread(), mixmonitor_thread(), record_exec(), rpt(), __ast_read(), ast_write(), ast_writestream(), handle_recordfile(), and handle_cli_file_convert().
{
int res = -1;
int alt = 0;
if (f->frametype == AST_FRAME_VIDEO) {
if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) {
/* This is the audio portion. Call the video one... */
if (!fs->vfs && fs->filename) {
const char *type = ast_getformatname(f->subclass.codec & ~0x1);
fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
ast_debug(1, "Opened video output file\n");
}
if (fs->vfs)
return ast_writestream(fs->vfs, f);
/* else ignore */
return 0;
} else {
/* Might / might not have mark set */
alt = 1;
}
} else if (f->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
return -1;
}
if (((fs->fmt->format | alt) & f->subclass.codec) == f->subclass.codec) {
res = fs->fmt->write(fs, f);
if (res < 0)
ast_log(LOG_WARNING, "Natural write failed\n");
else if (res > 0)
ast_log(LOG_WARNING, "Huh??\n");
} else {
/* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
the one we've setup a translator for, we do the "wrong thing" XXX */
if (fs->trans && f->subclass.codec != fs->lastwriteformat) {
ast_translator_free_path(fs->trans);
fs->trans = NULL;
}
if (!fs->trans)
fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass.codec);
if (!fs->trans)
ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
fs->fmt->name, ast_getformatname(f->subclass.codec));
else {
struct ast_frame *trf;
fs->lastwriteformat = f->subclass.codec;
/* Get the translated frame but don't consume the original in case they're using it on another stream */
if ((trf = ast_translate(fs->trans, f, 0))) {
struct ast_frame *cur;
/* the translator may have returned multiple frames, so process them */
for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
if ((res = fs->fmt->write(fs, trf))) {
ast_log(LOG_WARNING, "Translated frame write failed\n");
break;
}
}
ast_frfree(trf);
} else {
res = 0;
}
}
}
return res;
}
| 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 254 of file file.c.
References asprintf(), ast_log(), LOG_WARNING, errno, and ast_config_AST_DATA_DIR.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
{
char *fn = NULL;
if (!strcmp(ext, "wav49"))
ext = "WAV";
if (filename[0] == '/') {
if (asprintf(&fn, "%s.%s", filename, ext) < 0) {
ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
fn = NULL;
}
} else {
if (asprintf(&fn, "%s/sounds/%s.%s",
ast_config_AST_DATA_DIR, filename, ext) < 0) {
ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
fn = NULL;
}
}
return fn;
}
| static int copy | ( | const char * | infile, |
| const char * | outfile | ||
| ) | [static] |
Definition at line 211 of file file.c.
References len(), ast_log(), LOG_WARNING, AST_FILE_MODE, and errno.
Referenced by ast_filehelper().
{
int ifd, ofd, len;
char buf[4096]; /* XXX make it lerger. */
if ((ifd = open(infile, O_RDONLY)) < 0) {
ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
return -1;
}
if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
close(ifd);
return -1;
}
while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
int res;
if (len < 0) {
ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
break;
}
/* XXX handle partial writes */
res = write(ofd, buf, len);
if (res != len) {
ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
len = -1; /* error marker */
break;
}
}
close(ifd);
close(ofd);
if (len < 0) {
unlink(outfile);
return -1; /* error */
}
return 0; /* success */
}
| static int exts_compare | ( | const char * | exts, |
| const char * | type | ||
| ) | [static] |
Definition at line 278 of file file.c.
References ext, ast_copy_string(), and strsep().
Referenced by ast_filehelper(), ast_readfile(), ast_writefile(), and ast_format_str_reduce().
{
char tmp[256];
char *stringp = tmp, *ext;
ast_copy_string(tmp, exts, sizeof(tmp));
while ((ext = strsep(&stringp, "|"))) {
if (!strcmp(ext, type))
return 1;
}
return 0;
}
| static format_t 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 '_' suffices, or NULL.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Definition at line 571 of file file.c.
References ast_strdupa, ast_strlen_zero(), fileexists_test(), and DEFAULT_LANGUAGE.
Referenced by ast_openstream_full(), ast_openvstream(), and ast_fileexists().
{
format_t res = -1;
char *lang;
if (buf == NULL) {
return -1;
}
/* We try languages in the following order:
* preflang (may include dialect and style codes)
* lang (preflang without dialect - if any)
* <none>
* default (unless the same as preflang or lang without dialect)
*/
lang = ast_strdupa(preflang);
/* Try preferred language, including removing any style or dialect codes */
while (!ast_strlen_zero(lang)) {
char *end;
if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
return res;
}
if ((end = strrchr(lang, '_')) != NULL) {
*end = '\0';
continue;
}
break;
}
/* Try without any language */
if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
return res;
}
/* Finally try the default language unless it was already tried before */
if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
return res;
}
}
return 0;
}
| static format_t fileexists_test | ( | const char * | filename, |
| const char * | fmt, | ||
| const char * | lang, | ||
| char * | buf, | ||
| int | buflen | ||
| ) | [static] |
Definition at line 537 of file file.c.
References is_absolute_path(), ast_filehelper(), and ACTION_EXISTS.
Referenced by fileexists_core().
{
if (buf == NULL) {
return -1;
}
if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
if (lang) {
snprintf(buf, buflen, "%s/%s", lang, filename);
} else {
snprintf(buf, buflen, "%s", filename);
}
} else { /* old layout */
strcpy(buf, filename); /* first copy the full string */
if (lang) {
/* insert the language and suffix if needed */
const char *c = strrchr(filename, '/');
int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
}
}
return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
}
| static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 292 of file file.c.
References f, status, ast_filestream::owner, ast_filestream::fmt, ast_format::format, AST_FORMAT_AUDIO_MASK, ast_channel::stream, AST_SCHED_DEL, ast_channel::sched, ast_channel::streamid, ast_settimeout(), ast_channel::vstream, ast_channel::vstreamid, ast_filestream::trans, ast_translator_free_path(), ast_filestream::realfilename, ast_filestream::filename, ast_safe_fork(), SENTINEL, free, ast_format::close, ast_filestream::f, ast_filestream::vfs, ast_closestream(), ast_filestream::write_buffer, ast_free, ast_filestream::orig_chan_name, ast_module_unref(), and ast_format::module.
Referenced by get_filestream().
{
struct ast_filestream *f = arg;
int status;
int pid = -1;
/* Stop a running stream if there is one */
if (f->owner) {
if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
f->owner->stream = NULL;
AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
ast_settimeout(f->owner, 0, NULL, NULL);
} else {
f->owner->vstream = NULL;
AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
}
}
/* destroy the translator on exit */
if (f->trans)
ast_translator_free_path(f->trans);
if (f->realfilename && f->filename) {
pid = ast_safe_fork(0);
if (!pid) {
execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
_exit(1);
}
else if (pid > 0) {
/* Block the parent until the move is complete.*/
waitpid(pid, &status, 0);
}
}
if (f->filename)
free(f->filename);
if (f->realfilename)
free(f->realfilename);
if (f->fmt->close) {
void (*closefn)(struct ast_filestream *) = f->fmt->close;
closefn(f);
}
if (f->f)
fclose(f->f);
if (f->vfs)
ast_closestream(f->vfs);
if (f->write_buffer) {
ast_free(f->write_buffer);
}
if (f->orig_chan_name)
free((void *) f->orig_chan_name);
ast_module_unref(f->fmt->module);
}
| static int fn_wrapper | ( | struct ast_filestream * | s, |
| const char * | comment, | ||
| enum wrap_fn | mode | ||
| ) | [static] |
Definition at line 369 of file file.c.
References f, ast_filestream::fmt, WRAP_OPEN, ast_format::open, ast_log(), LOG_WARNING, ast_format::name, WRAP_REWRITE, ast_format::rewrite, ast_module_ref(), and ast_format::module.
Referenced by rewrite_wrapper(), and open_wrapper().
{
struct ast_format *f = s->fmt;
int ret = -1;
int (*openfn)(struct ast_filestream *s);
if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
else {
/* preliminary checks succeed. update usecount */
ast_module_ref(f->module);
ret = 0;
}
return ret;
}
| static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, |
| FILE * | bfile | ||
| ) | [static, read] |
Definition at line 345 of file file.c.
References ast_format::buf_size, ast_format::desc_size, ao2_alloc, filestream_destructor(), ast_filestream::fmt, ast_filestream::f, ast_filestream::_private, ast_filestream::buf, ast_filestream::fr, ast_frame::src, and ast_format::name.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
{
struct ast_filestream *s;
int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */
if ( (s = ao2_alloc(l, filestream_destructor)) == NULL)
return NULL;
s->fmt = fmt;
s->f = bfile;
if (fmt->desc_size)
s->_private = ((char *)(s + 1)) + fmt->buf_size;
if (fmt->buf_size)
s->buf = (char *)(s + 1);
s->fr.src = fmt->name;
return s;
}
| static char* handle_cli_core_show_file_formats | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1444 of file file.c.
References f, CLI_INIT, ast_cli_entry::command, ast_cli_entry::usage, CLI_GENERATE, ast_cli_args::argc, CLI_SHOWUSAGE, ast_cli(), ast_cli_args::fd, FORMAT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, ast_format::list, FORMAT2, ast_getformatname(), ast_format::format, ast_format::name, ast_format::exts, AST_RWLIST_UNLOCK, and CLI_SUCCESS.
{
#define FORMAT "%-10s %-10s %-20s\n"
#define FORMAT2 "%-10s %-10s %-20s\n"
struct ast_format *f;
int count_fmt = 0;
switch (cmd) {
case CLI_INIT:
e->command = "core show file formats";
e->usage =
"Usage: core show file formats\n"
" Displays currently registered file formats (if any).\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 4)
return CLI_SHOWUSAGE;
ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
ast_cli(a->fd, FORMAT, "------", "----", "----------");
AST_RWLIST_RDLOCK(&formats);
AST_RWLIST_TRAVERSE(&formats, f, list) {
ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
count_fmt++;
}
AST_RWLIST_UNLOCK(&formats);
ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
return CLI_SUCCESS;
#undef FORMAT
#undef FORMAT2
}
| static int is_absolute_path | ( | const char * | filename | ) | [static] |
Definition at line 532 of file file.c.
Referenced by fileexists_test().
{
return filename[0] == '/';
}
| static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 392 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
{
return fn_wrapper(s, NULL, WRAP_OPEN);
}
| static struct ast_frame* read_frame | ( | struct ast_filestream * | s, |
| int * | whennext | ||
| ) | [static, read] |
Definition at line 701 of file file.c.
References ast_filestream::fmt, ast_format::read, ast_frisolate(), and ast_frfree.
Referenced by ast_audiohook_read_frame(), ast_readframe(), ast_readaudio_callback(), and ast_readvideo_callback().
{
struct ast_frame *fr, *new_fr;
if (!s || !s->fmt) {
return NULL;
}
if (!(fr = s->fmt->read(s, whennext))) {
return NULL;
}
if (!(new_fr = ast_frisolate(fr))) {
ast_frfree(fr);
return NULL;
}
if (new_fr != fr) {
ast_frfree(fr);
fr = new_fr;
}
return fr;
}
| static int rewrite_wrapper | ( | struct ast_filestream * | s, |
| const char * | comment | ||
| ) | [static] |
Definition at line 387 of file file.c.
References fn_wrapper(), and WRAP_REWRITE.
Referenced by ast_writefile().
{
return fn_wrapper(s, comment, WRAP_REWRITE);
}
| 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 1176 of file file.c.
References ast_filestream::orig_chan_name, ast_set_flag, AST_FLAG_END_DTMF_ONLY, ast_test_flag, AST_FLAG_MASQ_NOSTREAM, ast_strdupa, ast_channel::name, ast_channel::stream, ast_stopstream(), ast_sched_wait(), ast_channel::sched, ast_waitfor(), ast_log(), LOG_WARNING, errno, ast_clear_flag, ast_waitfor_nandfds(), ast_read(), ast_frame::frametype, AST_FRAME_DTMF_END, exten, ast_frame::subclass, ast_frame_subclass::integer, ast_exists_extension(), S_COR, ast_channel::caller, ast_party_caller::id, ast_party_id::number, ast_party_number::valid, ast_party_number::str, ast_frfree, ast_stream_fastforward(), ast_filestream::f, ast_stream_rewind(), AST_FRAME_CONTROL, AST_CONTROL_HANGUP, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, AST_CONTROL_ANSWER, AST_CONTROL_VIDUPDATE, AST_CONTROL_SRCUPDATE, AST_CONTROL_SRCCHANGE, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_REDIRECTING, AST_CONTROL_AOC, AST_FRAME_VOICE, ast_frame::data, ast_frame::ptr, ast_frame::datalen, ast_sched_runq(), and ast_channel::_softhangup.
Referenced by ast_waitstream_fr(), ast_waitstream(), ast_waitstream_full(), and ast_waitstream_exten().
{
const char *orig_chan_name = NULL;
int err = 0;
if (!breakon)
breakon = "";
if (!forward)
forward = "";
if (!reverse)
reverse = "";
/* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM))
orig_chan_name = ast_strdupa(c->name);
while (c->stream) {
int res;
int ms;
if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) {
ast_stopstream(c);
err = 1;
break;
}
ms = ast_sched_wait(c->sched);
if (ms < 0 && !c->timingfunc) {
ast_stopstream(c);
break;
}
if (ms < 0)
ms = 1000;
if (cmdfd < 0) {
res = ast_waitfor(c, ms);
if (res < 0) {
ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res;
}
} else {
int outfd;
struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
if (!rchan && (outfd < 0) && (ms)) {
/* Continue */
if (errno == EINTR)
continue;
ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1;
} else if (outfd > -1) { /* this requires cmdfd set */
/* The FD we were watching has something waiting */
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return 1;
}
/* if rchan is set, it is 'c' */
res = rchan ? 1 : 0; /* map into 'res' values */
}
if (res > 0) {
struct ast_frame *fr = ast_read(c);
if (!fr) {
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1;
}
switch (fr->frametype) {
case AST_FRAME_DTMF_END:
if (context) {
const char exten[2] = { fr->subclass.integer, '\0' };
if (ast_exists_extension(c, context, exten, 1,
S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
res = fr->subclass.integer;
ast_frfree(fr);
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res;
}
} else {
res = fr->subclass.integer;
if (strchr(forward, res)) {
int eoftest;
ast_stream_fastforward(c->stream, skip_ms);
eoftest = fgetc(c->stream->f);
if (feof(c->stream->f)) {
ast_stream_rewind(c->stream, skip_ms);
} else {
ungetc(eoftest, c->stream->f);
}
} else if (strchr(reverse, res)) {
ast_stream_rewind(c->stream, skip_ms);
} else if (strchr(breakon, res)) {
ast_frfree(fr);
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res;
}
}
break;
case AST_FRAME_CONTROL:
switch (fr->subclass.integer) {
case AST_CONTROL_HANGUP:
case AST_CONTROL_BUSY:
case AST_CONTROL_CONGESTION:
ast_frfree(fr);
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1;
case AST_CONTROL_RINGING:
case AST_CONTROL_ANSWER:
case AST_CONTROL_VIDUPDATE:
case AST_CONTROL_SRCUPDATE:
case AST_CONTROL_SRCCHANGE:
case AST_CONTROL_HOLD:
case AST_CONTROL_UNHOLD:
case AST_CONTROL_CONNECTED_LINE:
case AST_CONTROL_REDIRECTING:
case AST_CONTROL_AOC:
case -1:
/* Unimportant */
break;
default:
ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
}
break;
case AST_FRAME_VOICE:
/* Write audio if appropriate */
if (audiofd > -1) {
if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
}
}
default:
/* Ignore all others */
break;
}
ast_frfree(fr);
}
ast_sched_runq(c->sched);
}
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return (err || c->_softhangup) ? -1 : 0;
}
| int ast_language_is_prefix = 1 |
Definition at line 59 of file file.c.
Referenced by handle_show_settings(), ast_readconfig(), and main().
struct ast_cli_entry cli_file[] [static] |
{
AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
}
Referenced by ast_rtp_instance_available_formats().