Mon Mar 31 07:40:37 2008

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#include "asterisk.h"
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"

Include dependency graph for file.c:

Go to the source code of this file.

Defines

#define FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-10s %-10s %-20s\n"

Enumerations

enum  file_action {
  ACTION_EXISTS = 1, ACTION_DELETE, ACTION_RENAME, ACTION_OPEN,
  ACTION_COPY
}
enum  fsread_res { FSREAD_FAILURE, FSREAD_SUCCESS_SCHED, FSREAD_SUCCESS_NOSCHED }
enum  wrap_fn { WRAP_OPEN, WRAP_REWRITE }

Functions

int __ast_format_register (const struct ast_format *f, struct ast_module *mod)
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
int ast_closestream (struct ast_filestream *f)
int ast_file_init (void)
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
int ast_filedelete (const char *filename, const char *fmt)
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
static int ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
int ast_format_unregister (const char *name)
static int ast_fsread_audio (const void *data)
static int ast_fsread_video (const void *data)
ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
ast_filestreamast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
int ast_playstream (struct ast_filestream *s)
static enum fsread_res ast_readaudio_callback (struct ast_filestream *s)
ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
ast_frameast_readframe (struct ast_filestream *s)
static enum fsread_res ast_readvideo_callback (struct ast_filestream *s)
static AST_RWLIST_HEAD_STATIC (formats, ast_format)
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream.
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *language, const char *digits)
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
off_t ast_tellstream (struct ast_filestream *fs)
int ast_truncstream (struct ast_filestream *fs)
int ast_waitstream (struct ast_channel *c, const char *breakon)
int ast_waitstream_exten (struct ast_channel *c, const char *context)
int ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
int ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
ast_filestreamast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
static char * build_filename (const char *filename, const char *ext)
 construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
static int copy (const char *infile, const char *outfile)
static int exts_compare (const char *exts, const char *type)
static int fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen)
 helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
static int fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen)
static int fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode)
static struct ast_filestreamget_filestream (struct ast_format *fmt, FILE *bfile)
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 show_file_formats (int fd, int argc, char *argv[])
static int show_file_formats_deprecated (int fd, int argc, char *argv[])
static int waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int skip_ms, int audiofd, int cmdfd, const char *context)
 the core of all waitstream() functions

Variables

int ast_language_is_prefix = 1
ast_cli_entry cli_file []
ast_cli_entry cli_show_file_formats_deprecated
char show_file_formats_usage []


Detailed Description

Generic File Format Support.

Author:
Mark Spencer <markster@digium.com>

Definition in file file.c.


Define Documentation

#define FORMAT   "%-10s %-10s %-20s\n"

#define FORMAT   "%-10s %-10s %-20s\n"

#define FORMAT2   "%-10s %-10s %-20s\n"

#define FORMAT2   "%-10s %-10s %-20s\n"

Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_inuse(), sip_show_registry(), zap_show_channels(), and zap_show_status().


Enumeration Type Documentation

enum file_action

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 337 of file file.c.

00337                  {
00338    ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
00339    ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
00340    ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
00341    ACTION_OPEN,
00342    ACTION_COPY /* copy file. return 0 on success, -1 on error */
00343 };

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 652 of file file.c.

00652                 {
00653    FSREAD_FAILURE,
00654    FSREAD_SUCCESS_SCHED,
00655    FSREAD_SUCCESS_NOSCHED,
00656 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 308 of file file.c.

00308 { WRAP_OPEN, WRAP_REWRITE };


Function Documentation

int __ast_format_register ( const struct ast_format f,
struct ast_module mod 
)

Register a new file format capability Adds a format to Asterisk's format abilities. returns 0 on success, -1 on failure

Definition at line 68 of file file.c.

References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), ast_format::buf_size, ast_format::exts, f, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

00069 {
00070    struct ast_format *tmp;
00071 
00072    AST_RWLIST_WRLOCK(&formats);
00073    AST_RWLIST_TRAVERSE(&formats, tmp, list) {
00074       if (!strcasecmp(f->name, tmp->name)) {
00075          AST_RWLIST_UNLOCK(&formats);
00076          ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
00077          return -1;
00078       }
00079    }
00080    if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
00081       AST_RWLIST_UNLOCK(&formats);
00082       return -1;
00083    }
00084    *tmp = *f;
00085    tmp->module = mod;
00086    if (tmp->buf_size) {
00087       /*
00088        * Align buf_size properly, rounding up to the machine-specific
00089        * alignment for pointers.
00090        */
00091       struct _test_align { void *a, *b; } p;
00092       int align = (char *)&p.b - (char *)&p.a;
00093       tmp->buf_size = ((f->buf_size + align - 1)/align)*align;
00094    }
00095    
00096    memset(&tmp->list, 0, sizeof(tmp->list));
00097 
00098    AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
00099    AST_RWLIST_UNLOCK(&formats);
00100    if (option_verbose > 1)
00101       ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts);
00102 
00103    return 0;
00104 }

int ast_applystream ( struct ast_channel chan,
struct ast_filestream s 
)

Parameters:
chan channel to work
s ast_filestream to apply Returns 0 for success, -1 on failure

Definition at line 749 of file file.c.

References s.

Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().

00750 {
00751    s->owner = chan;
00752    return 0;
00753 }

int ast_closestream ( struct ast_filestream f  ) 

Parameters:
f filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure

Definition at line 792 of file file.c.

References ast_closestream(), AST_FORMAT_MAX_AUDIO, ast_module_unref(), ast_safe_system(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, f, ast_format::format, free, and ast_format::module.

Referenced by __ast_play_and_record(), ast_closestream(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_stopstream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), and rpt().

00793 {
00794    char *cmd = NULL;
00795    size_t size = 0;
00796    /* Stop a running stream if there is one */
00797    if (f->owner) {
00798       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
00799          f->owner->stream = NULL;
00800          AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
00801 #ifdef HAVE_ZAPTEL
00802          ast_settimeout(f->owner, 0, NULL, NULL);
00803 #endif         
00804       } else {
00805          f->owner->vstream = NULL;
00806          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00807       }
00808    }
00809    /* destroy the translator on exit */
00810    if (f->trans)
00811       ast_translator_free_path(f->trans);
00812 
00813    if (f->realfilename && f->filename) {
00814          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00815          cmd = alloca(size);
00816          memset(cmd,0,size);
00817          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00818          ast_safe_system(cmd);
00819    }
00820 
00821    if (f->filename)
00822       free(f->filename);
00823    if (f->realfilename)
00824       free(f->realfilename);
00825    if (f->fmt->close)
00826       f->fmt->close(f);
00827    fclose(f->f);
00828    if (f->vfs)
00829       ast_closestream(f->vfs);
00830    if (f->orig_chan_name)
00831       free((void *) f->orig_chan_name);
00832    ast_module_unref(f->fmt->module);
00833    free(f);
00834    return 0;
00835 }

int ast_file_init ( void   ) 

Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time

Definition at line 1314 of file file.c.

References ast_cli_register_multiple(), and cli_file.

Referenced by main().

01315 {
01316    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01317    return 0;
01318 }

int ast_filecopy ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

Parameters:
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 865 of file file.c.

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00866 {
00867    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00868 }

int ast_filedelete ( const char *  filename,
const char *  fmt 
)

Parameters:
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 855 of file file.c.

References ACTION_DELETE, and ast_filehelper().

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), leave_voicemail(), play_mailbox_owner(), play_record_review(), vm_delete(), and vm_forwardoptions().

00856 {
00857    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00858 }

int ast_fileexists ( const char *  filename,
const char *  fmt,
const char *  preflang 
)

Parameters:
filename name of the file you wish to check, minus the extension
fmt the format you wish to check (the extension)
preflang (the preferred language you wisht to find the file in) See if a given file exists in a given format. If fmt is NULL, any format is accepted. Returns -1 if file does not exist, non-zero positive otherwise.

Definition at line 841 of file file.c.

References ast_filestream::buf, and fileexists_core().

Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), last_message_index(), leave_voicemail(), play_greeting(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), rxfax_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

00842 {
00843    char *buf;
00844    int buflen;
00845 
00846    if (preflang == NULL)
00847       preflang = "";
00848    buflen = strlen(preflang) + strlen(filename) + 4;  /* room for everything */
00849    buf = alloca(buflen);
00850    if (buf == NULL)
00851       return 0;
00852    return fileexists_core(filename, fmt, preflang, buf, buflen);
00853 }

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 354 of file file.c.

References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_MAX_AUDIO, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_format::format, free, get_filestream(), 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(), fileexists_core(), and fileexists_test().

00355 {
00356    struct ast_format *f;
00357    int res = (action == ACTION_EXISTS) ? 0 : -1;
00358 
00359    AST_RWLIST_RDLOCK(&formats);
00360    /* Check for a specific format */
00361    AST_RWLIST_TRAVERSE(&formats, f, list) {
00362       char *stringp, *ext = NULL;
00363 
00364       if (fmt && !exts_compare(f->exts, fmt))
00365          continue;
00366 
00367       /* Look for a file matching the supported extensions.
00368        * The file must exist, and for OPEN, must match
00369        * one of the formats supported by the channel.
00370        */
00371       stringp = ast_strdupa(f->exts);  /* this is in the stack so does not need to be freed */
00372       while ( (ext = strsep(&stringp, "|")) ) {
00373          struct stat st;
00374          char *fn = build_filename(filename, ext);
00375 
00376          if (fn == NULL)
00377             continue;
00378 
00379          if ( stat(fn, &st) ) { /* file not existent */
00380             free(fn);
00381             continue;
00382          }
00383          /* for 'OPEN' we need to be sure that the format matches
00384           * what the channel can process
00385           */
00386          if (action == ACTION_OPEN) {
00387             struct ast_channel *chan = (struct ast_channel *)arg2;
00388             FILE *bfile;
00389             struct ast_filestream *s;
00390 
00391             if ( !(chan->writeformat & f->format) &&
00392                  !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) {
00393                free(fn);
00394                continue;   /* not a supported format */
00395             }
00396             if ( (bfile = fopen(fn, "r")) == NULL) {
00397                free(fn);
00398                continue;   /* cannot open file */
00399             }
00400             s = get_filestream(f, bfile);
00401             if (!s) {
00402                fclose(bfile);
00403                free(fn);   /* cannot allocate descriptor */
00404                continue;
00405             }
00406             if (open_wrapper(s)) {
00407                fclose(bfile);
00408                free(fn);
00409                free(s);
00410                continue;   /* cannot run open on file */
00411             }
00412             /* ok this is good for OPEN */
00413             res = 1; /* found */
00414             s->lasttimeout = -1;
00415             s->fmt = f;
00416             s->trans = NULL;
00417             s->filename = NULL;
00418             if (s->fmt->format < AST_FORMAT_MAX_AUDIO) {
00419                if (chan->stream)
00420                   ast_closestream(chan->stream);
00421                chan->stream = s;
00422             } else {
00423                if (chan->vstream)
00424                   ast_closestream(chan->vstream);
00425                chan->vstream = s;
00426             }
00427             free(fn);
00428             break;
00429          }
00430          switch (action) {
00431          case ACTION_OPEN:
00432             break;   /* will never get here */
00433 
00434          case ACTION_EXISTS:  /* return the matching format */
00435             res |= f->format;
00436             break;
00437 
00438          case ACTION_DELETE:
00439             if ( (res = unlink(fn)) )
00440                ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
00441             break;
00442 
00443          case ACTION_RENAME:
00444          case ACTION_COPY: {
00445             char *nfn = build_filename((const char *)arg2, ext);
00446             if (!nfn)
00447                ast_log(LOG_WARNING, "Out of memory\n");
00448             else {
00449                res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
00450                if (res)
00451                   ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
00452                      action == ACTION_COPY ? "copy" : "rename",
00453                       fn, nfn, strerror(errno));
00454                free(nfn);
00455             }
00456              }
00457             break;
00458 
00459          default:
00460             ast_log(LOG_WARNING, "Unknown helper %d\n", action);
00461          }
00462          free(fn);
00463       }
00464    }
00465    AST_RWLIST_UNLOCK(&formats);
00466    return res;
00467 }

int ast_filerename ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

Parameters:
oldname the name of the file you wish to act upon (minus the extension)
newname the name you wish to rename the file to (minus the extension)
fmt the format of the file Rename a given file in a given format, or if fmt is NULL, then do so for all Returns -1 on failure

Definition at line 860 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().

00861 {
00862    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00863 }

int ast_format_unregister ( const char *  name  ) 

Parameters:
name the name of the format you wish to unregister Unregisters a format based on the name of the format. Returns 0 on success, -1 on failure to unregister

Definition at line 106 of file file.c.

References ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), free, LOG_WARNING, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by unload_module().

00107 {
00108    struct ast_format *tmp;
00109    int res = -1;
00110 
00111    AST_RWLIST_WRLOCK(&formats);
00112    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
00113       if (!strcasecmp(name, tmp->name)) {
00114          AST_RWLIST_REMOVE_CURRENT(&formats, list);
00115          free(tmp);
00116          res = 0;
00117       }
00118    }
00119    AST_RWLIST_TRAVERSE_SAFE_END
00120    AST_RWLIST_UNLOCK(&formats);
00121 
00122    if (!res) {
00123       if (option_verbose > 1)
00124          ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
00125    } else
00126       ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00127 
00128    return res;
00129 }

static int ast_fsread_audio ( const void *  data  )  [static]

Definition at line 697 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00698 {
00699    struct ast_filestream *fs = (struct ast_filestream *)data;
00700    enum fsread_res res;
00701 
00702    res = ast_readaudio_callback(fs);
00703 
00704    if (res == FSREAD_SUCCESS_SCHED)
00705       return 1;
00706    
00707    return 0;
00708 }

static int ast_fsread_video ( const void *  data  )  [static]

Definition at line 736 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00737 {
00738    struct ast_filestream *fs = (struct ast_filestream *)data;
00739    enum fsread_res res;
00740 
00741    res = ast_readvideo_callback(fs);
00742 
00743    if (res == FSREAD_SUCCESS_SCHED)
00744       return 1;
00745    
00746    return 0;
00747 }

struct ast_filestream* ast_openstream ( struct ast_channel chan,
const char *  filename,
const char *  preflang 
)

Parameters:
chan channel to work with
filename to use
preflang prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error

Definition at line 567 of file file.c.

References ast_openstream_full().

Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().

00568 {
00569    return ast_openstream_full(chan, filename, preflang, 0);
00570 }

struct ast_filestream* ast_openstream_full ( struct ast_channel chan,
const char *  filename,
const char *  preflang,
int  asis 
)

Parameters:
chan channel to work with
filename to use
preflang prefered language to use
asis if set, don't clear generators Returns a ast_filestream pointer if it opens the file, NULL on error

Definition at line 572 of file file.c.

References ACTION_OPEN, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), ast_filestream::buf, fileexists_core(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.

Referenced by ast_moh_files_next(), ast_openstream(), and gen_nextfile().

00573 {
00574    /* 
00575     * Use fileexists_core() to find a file in a compatible
00576     * language and format, set up a suitable translator,
00577     * and open the stream.
00578     */
00579    int fmts, res, buflen;
00580    char *buf;
00581 
00582    if (!asis) {
00583       /* do this first, otherwise we detect the wrong writeformat */
00584       ast_stopstream(chan);
00585       if (chan->generator)
00586          ast_deactivate_generator(chan);
00587    }
00588    if (preflang == NULL)
00589       preflang = "";
00590    buflen = strlen(preflang) + strlen(filename) + 4;
00591    buf = alloca(buflen);
00592    if (buf == NULL)
00593       return NULL;
00594    fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
00595    if (fmts > 0)
00596       fmts &= AST_FORMAT_AUDIO_MASK;
00597    if (fmts < 1) {
00598       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00599       return NULL;
00600    }
00601    chan->oldwriteformat = chan->writeformat;
00602    /* Set the channel to a format we can work with */
00603    res = ast_set_write_format(chan, fmts);
00604    res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
00605    if (res >= 0)
00606       return chan->stream;
00607    return NULL;
00608 }

struct ast_filestream* ast_openvstream ( struct ast_channel chan,
const char *  filename,
const char *  preflang 
)

Parameters:
chan channel to work with
filename to use
preflang prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error

Definition at line 610 of file file.c.

References ACTION_OPEN, ast_filehelper(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_getformatname(), ast_log(), ast_filestream::buf, fileexists_core(), fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.

Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().

00611 {
00612    /* As above, but for video. But here we don't have translators
00613     * so we must enforce a format.
00614     */
00615    unsigned int format;
00616    char *buf;
00617    int buflen;
00618 
00619    if (preflang == NULL)
00620       preflang = "";
00621    buflen = strlen(preflang) + strlen(filename) + 4;
00622    buf = alloca(buflen);
00623    if (buf == NULL)
00624       return NULL;
00625 
00626    for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) {
00627       int fd;
00628       const char *fmt;
00629 
00630       if (!(chan->nativeformats & format))
00631          continue;
00632       fmt = ast_getformatname(format);
00633       if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1)   /* no valid format */
00634          continue;
00635       fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
00636       if (fd >= 0)
00637          return chan->vstream;
00638       ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00639    }
00640    return NULL;
00641 }

int ast_playstream ( struct ast_filestream s  ) 

Parameters:
s filestream to play Returns 0 for success, -1 on failure

Definition at line 755 of file file.c.

References AST_FORMAT_MAX_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), FSREAD_FAILURE, and s.

Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().

00756 {
00757    enum fsread_res res;
00758 
00759    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00760       res = ast_readaudio_callback(s);
00761    else
00762       res = ast_readvideo_callback(s);
00763 
00764    return (res == FSREAD_FAILURE) ? -1 : 0;
00765 }

static enum fsread_res ast_readaudio_callback ( struct ast_filestream s  )  [static]

Definition at line 660 of file file.c.

References ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.

Referenced by ast_fsread_audio(), and ast_playstream().

00661 {
00662    int whennext = 0;
00663 
00664    while (!whennext) {
00665       struct ast_frame *fr;
00666       
00667       if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name))
00668          goto return_failure;
00669       
00670       fr = s->fmt->read(s, &whennext);
00671       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00672          if (fr)
00673             ast_log(LOG_WARNING, "Failed to write frame\n");
00674          goto return_failure;
00675       }
00676    }
00677    if (whennext != s->lasttimeout) {
00678 #ifdef HAVE_ZAPTEL
00679       if (s->owner->timingfd > -1)
00680          ast_settimeout(s->owner, whennext, ast_fsread_audio, s);
00681       else
00682 #endif      
00683          s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_fsread_audio, s);
00684       s->lasttimeout = whennext;
00685       return FSREAD_SUCCESS_NOSCHED;
00686    }
00687    return FSREAD_SUCCESS_SCHED;
00688 
00689 return_failure:
00690    s->owner->streamid = -1;
00691 #ifdef HAVE_ZAPTEL
00692    ast_settimeout(s->owner, 0, NULL, NULL);
00693 #endif         
00694    return FSREAD_FAILURE;
00695 }

struct ast_filestream* ast_readfile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
)

Parameters:
filename the name of the file to read from
type format of file you wish to read from
comment comment to go with
flags file flags
check (unimplemented, hence negligible)
mode Open mode Open an incoming file stream. flags are flags for the open() command, and if check is non-zero, then it will not read a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. Returns a struct ast_filestream on success, NULL on failure

Definition at line 901 of file file.c.

References ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), cli_audio_convert(), and cli_audio_convert_deprecated().

00902 {
00903    FILE *bfile;
00904    struct ast_format *f;
00905    struct ast_filestream *fs = NULL;
00906    char *fn;
00907 
00908    AST_RWLIST_RDLOCK(&formats);
00909 
00910    AST_RWLIST_TRAVERSE(&formats, f, list) {
00911       fs = NULL;
00912       if (!exts_compare(f->exts, type))
00913          continue;
00914 
00915       fn = build_filename(filename, type);
00916       errno = 0;
00917       bfile = fopen(fn, "r");
00918       if (!bfile || (fs = get_filestream(f, bfile)) == NULL ||
00919           open_wrapper(fs) ) {
00920          ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00921          if (fs)
00922             ast_free(fs);
00923          if (bfile)
00924             fclose(bfile);
00925          free(fn);
00926          continue;
00927       }
00928       /* found it */
00929       fs->trans = NULL;
00930       fs->fmt = f;
00931       fs->flags = flags;
00932       fs->mode = mode;
00933       fs->filename = strdup(filename);
00934       fs->vfs = NULL;
00935       break;
00936    }
00937 
00938    AST_RWLIST_UNLOCK(&formats);
00939    if (!fs) 
00940       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00941 
00942    return fs;
00943 }

struct ast_frame* ast_readframe ( struct ast_filestream s  ) 

Parameters:
s ast_filestream to act on Returns a frame or NULL if read failed

Definition at line 643 of file file.c.

References f, and s.

Referenced by __ast_play_and_record(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().

00644 {
00645    struct ast_frame *f = NULL;
00646    int whennext = 0; 
00647    if (s && s->fmt)
00648       f = s->fmt->read(s, &whennext);
00649    return f;
00650 }

static enum fsread_res ast_readvideo_callback ( struct ast_filestream s  )  [static]

Definition at line 712 of file file.c.

References ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.

Referenced by ast_fsread_video(), and ast_playstream().

00713 {
00714    int whennext = 0;
00715 
00716    while (!whennext) {
00717       struct ast_frame *fr = s->fmt->read(s, &whennext);
00718       if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */
00719          if (fr)
00720             ast_log(LOG_WARNING, "Failed to write frame\n");
00721          s->owner->vstreamid = -1;
00722          return FSREAD_FAILURE;
00723       }
00724    }
00725 
00726    if (whennext != s->lasttimeout) {
00727       s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext / 8, 
00728          ast_fsread_video, s);
00729       s->lasttimeout = whennext;
00730       return FSREAD_SUCCESS_NOSCHED;
00731    }
00732 
00733    return FSREAD_SUCCESS_SCHED;
00734 }

static AST_RWLIST_HEAD_STATIC ( formats  ,
ast_format   
) [static]

int ast_seekstream ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)

Parameters:
fs ast_filestream to perform seek on
sample_offset numbers of samples to seek
whence SEEK_SET, SEEK_CUR, SEEK_END Returns 0 for success, or -1 for error

Definition at line 767 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_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_streamfile().

00768 {
00769    return fs->fmt->seek(fs, sample_offset, whence);
00770 }

int ast_stopstream ( struct ast_channel c  ) 

Stops a stream.

Parameters:
c The channel you wish to stop playback on
Stop playback of a stream

Return values:
0 always
Note:
The channel does not need to be locked before calling this function.

Definition at line 131 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_app_getdata(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), nv_background_detect_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

00132 {
00133    ast_channel_lock(tmp);
00134 
00135    /* Stop a running stream if there is one */
00136    if (tmp->stream) {
00137       ast_closestream(tmp->stream);
00138       tmp->stream = NULL;
00139       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00140          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00141    }
00142    /* Stop the video stream too */
00143    if (tmp->vstream != NULL) {
00144       ast_closestream(tmp->vstream);
00145       tmp->vstream = NULL;
00146    }
00147 
00148    ast_channel_unlock(tmp);
00149 
00150    return 0;
00151 }

int ast_stream_and_wait ( struct ast_channel chan,
const char *  file,
const char *  language,
const char *  digits 
)

Definition at line 1237 of file file.c.

References ast_streamfile(), ast_strlen_zero(), and ast_waitstream().

Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), directory_exec(), invent_message(), ivr_dispatch(), leave_voicemail(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().

01239 {
01240         int res = 0;
01241         if (!ast_strlen_zero(file)) {
01242                 res =  ast_streamfile(chan, file, language);
01243                 if (!res)
01244                         res = ast_waitstream(chan, digits);
01245         }
01246         return res;
01247 } 

int ast_stream_fastforward ( struct ast_filestream fs,
off_t  ms 
)

Parameters:
fs filestream to act on
ms milliseconds to move Returns 0 for success, or -1 for error

Definition at line 782 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00783 {
00784    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00785 }

int ast_stream_rewind ( struct ast_filestream fs,
off_t  ms 
)

Parameters:
fs filestream to act on
ms milliseconds to move Returns 0 for success, or -1 for error

Definition at line 787 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by __ast_play_and_record(), handle_recordfile(), and waitstream_core().

00788 {
00789    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00790 }

int ast_streamfile ( struct ast_channel c,
const char *  filename,
const char *  preflang 
)

Parameters:
c channel to stream the file to
filename the name of the file you wish to stream, minus the extension
preflang the preferred language you wish to have the file streamed to you in Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel Also, it will stop any existing streams on the channel. Returns 0 on success, or -1 on failure.

Definition at line 870 of file file.c.

References ast_applystream(), AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_strdup, ast_test_flag, ast_verbose(), errno, fmt, ast_filestream::fmt, ast_format::format, LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_verbose, ast_filestream::orig_chan_name, VERBOSE_PREFIX_3, and ast_filestream::vfs.

Referenced by __login_exec(), action_bridge(), agent_call(), 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_nl(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), nv_background_detect_exec(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().

00871 {
00872    struct ast_filestream *fs;
00873    struct ast_filestream *vfs=NULL;
00874    char fmt[256];
00875 
00876    fs = ast_openstream(chan, filename, preflang);
00877    if (fs)
00878       vfs = ast_openvstream(chan, filename, preflang);
00879    if (vfs)
00880       ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00881    if (fs){
00882       int res;
00883       if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
00884          fs->orig_chan_name = ast_strdup(chan->name);
00885       if (ast_applystream(chan, fs))
00886          return -1;
00887       if (vfs && ast_applystream(chan, vfs))
00888          return -1;
00889       res = ast_playstream(fs);
00890       if (!res && vfs)
00891          res = ast_playstream(vfs);
00892       if (option_verbose > 2)
00893          ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default");
00894 
00895       return res;
00896    }
00897    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00898    return -1;
00899 }

off_t ast_tellstream ( struct ast_filestream fs  ) 

Parameters:
fs fs to act on Returns a long as a sample offset into stream

Definition at line 777 of file file.c.

References ast_filestream::fmt, and ast_format::tell.

Referenced by __ast_play_and_record(), ast_control_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().

00778 {
00779    return fs->fmt->tell(fs);
00780 }

int ast_truncstream ( struct ast_filestream fs  ) 

Parameters:
fs filestream to act on Returns 0 for success, or -1 for error

Definition at line 772 of file file.c.

References ast_filestream::fmt, and ast_format::trunc.

Referenced by __ast_play_and_record(), and handle_recordfile().

00773 {
00774    return fs->fmt->trunc(fs);
00775 }

int ast_waitstream ( struct ast_channel c,
const char *  breakon 
)

Parameters:
c channel to waitstream on
breakon string of DTMF digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1210 of file file.c.

References waitstream_core().

Referenced by __login_exec(), action_bridge(), agent_call(), app_exec(), ast_app_getdata(), 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_nl(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), 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(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), and wait_file().

01211 {
01212    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01213 }

int ast_waitstream_exten ( struct ast_channel c,
const char *  context 
)

Parameters:
c channel to waitstream on
context string of context to match digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a valid extension digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1221 of file file.c.

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01222 {
01223    /* Waitstream, with return in the case of a valid 1 digit extension */
01224    /* in the current or specified context being pressed */
01225 
01226    if (!context)
01227       context = c->context;
01228    return waitstream_core(c, NULL, NULL, NULL, 0,
01229       -1, -1, context);
01230 }

int ast_waitstream_fr ( struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  ms 
)

Parameters:
c channel to waitstream on
breakon string of DTMF digits to break upon
forward DTMF digit to fast forward upon
rewind DTMF digit to rewind upon
ms How many miliseconds to skip forward/back Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1204 of file file.c.

References waitstream_core().

Referenced by ast_control_streamfile().

01205 {
01206    return waitstream_core(c, breakon, forward, rewind, ms,
01207       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01208 }

int ast_waitstream_full ( struct ast_channel c,
const char *  breakon,
int  audiofd,
int  cmdfd 
)

Definition at line 1215 of file file.c.

References waitstream_core().

Referenced by ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().

01216 {
01217    return waitstream_core(c, breakon, NULL, NULL, 0,
01218       audiofd, cmdfd, NULL /* no context */);
01219 }

struct ast_filestream* ast_writefile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
)

Parameters:
filename the name of the file to write to
type format of file you wish to write out to
comment comment to go with
flags output file flags
check (unimplemented, hence negligible)
mode Open mode Create an outgoing file stream. oflags are flags for the open() command, and if check is non-zero, then it will not write a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. Returns a struct ast_filestream on success, NULL on failure

Definition at line 945 of file file.c.

References ast_free, ast_log(), ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().

00946 {
00947    int fd, myflags = 0;
00948    /* compiler claims this variable can be used before initialization... */
00949    FILE *bfile = NULL;
00950    struct ast_format *f;
00951    struct ast_filestream *fs = NULL;
00952    char *buf = NULL;
00953    size_t size = 0;
00954    int format_found = 0;
00955 
00956    AST_RWLIST_RDLOCK(&formats);
00957 
00958    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
00959    /* We really can't use O_APPEND as it will break WAV header updates */
00960    if (flags & O_APPEND) { 
00961       flags &= ~O_APPEND;
00962    } else {
00963       myflags = O_TRUNC;
00964    }
00965    
00966    myflags |= O_WRONLY | O_CREAT;
00967 
00968    /* XXX need to fix this - we should just do the fopen,
00969     * not open followed by fdopen()
00970     */
00971    AST_RWLIST_TRAVERSE(&formats, f, list) {
00972       char *fn, *orig_fn = NULL;
00973       if (fs)
00974          break;
00975 
00976       if (!exts_compare(f->exts, type))
00977          continue;
00978       else
00979          format_found = 1;
00980 
00981       fn = build_filename(filename, type);
00982       fd = open(fn, flags | myflags, mode);
00983       if (fd > -1) {
00984          /* fdopen() the resulting file stream */
00985          bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
00986          if (!bfile) {
00987             ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
00988             close(fd);
00989             fd = -1;
00990          }
00991       }
00992       
00993       if (ast_opt_cache_record_files && (fd > -1)) {
00994          char *c;
00995 
00996          fclose(bfile); /* this also closes fd */
00997          /*
00998            We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
00999            What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
01000          */
01001          orig_fn = ast_strdupa(fn);
01002          for (c = fn; *c; c++)
01003             if (*c == '/')
01004                *c = '_';
01005 
01006          size = strlen(fn) + strlen(record_cache_dir) + 2;
01007          buf = alloca(size);
01008          strcpy(buf, record_cache_dir);
01009          strcat(buf, "/");
01010          strcat(buf, fn);
01011          free(fn);
01012          fn = buf;
01013          fd = open(fn, flags | myflags, mode);
01014          if (fd > -1) {
01015             /* fdopen() the resulting file stream */
01016             bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
01017             if (!bfile) {
01018                ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
01019                close(fd);
01020                fd = -1;
01021             }
01022          }
01023       }
01024       if (fd > -1) {
01025          errno = 0;
01026          fs = get_filestream(f, bfile);
01027          if (!fs || rewrite_wrapper(fs, comment)) {
01028             ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
01029             close(fd);
01030             if (orig_fn) {
01031                unlink(fn);
01032                unlink(orig_fn);
01033             }
01034             if (fs)
01035                ast_free(fs);
01036             fs = NULL;
01037             continue;
01038          }
01039          fs->trans = NULL;
01040          fs->fmt = f;
01041          fs->flags = flags;
01042          fs->mode = mode;
01043          if (orig_fn) {
01044             fs->realfilename = strdup(orig_fn);
01045             fs->filename = strdup(fn);
01046          } else {
01047             fs->realfilename = NULL;
01048             fs->filename = strdup(filename);
01049          }
01050          fs->vfs = NULL;
01051          /* If truncated, we'll be at the beginning; if not truncated, then append */
01052          f->seek(fs, 0, SEEK_END);
01053       } else if (errno != EEXIST) {
01054          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
01055          if (orig_fn)
01056             unlink(orig_fn);
01057       }
01058       /* if buf != NULL then fn is already free and pointing to it */
01059       if (!buf)
01060          free(fn);
01061    }
01062 
01063    AST_RWLIST_UNLOCK(&formats);
01064 
01065    if (!format_found)
01066       ast_log(LOG_WARNING, "No such format '%s'\n", type);
01067 
01068    return fs;
01069 }

int ast_writestream ( struct ast_filestream fs,
struct ast_frame f 
)

Parameters:
fs filestream to write to
f frame to write to the filestream Send a frame to a filestream -- note: does NOT free the frame, call ast_frfree manually Returns 0 on success, -1 on failure.

Definition at line 153 of file file.c.

References AST_FORMAT_MAX_AUDIO, 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_DEBUG, 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(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().

00154 {
00155    int res = -1;
00156    int alt = 0;
00157    if (f->frametype == AST_FRAME_VIDEO) {
00158       if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) {
00159          /* This is the audio portion.  Call the video one... */
00160          if (!fs->vfs && fs->filename) {
00161             const char *type = ast_getformatname(f->subclass & ~0x1);
00162             fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
00163             ast_log(LOG_DEBUG, "Opened video output file\n");
00164          }
00165          if (fs->vfs)
00166             return ast_writestream(fs->vfs, f);
00167          /* else ignore */
00168          return 0;            
00169       } else {
00170          /* Might / might not have mark set */
00171          alt = 1;
00172       }
00173    } else if (f->frametype != AST_FRAME_VOICE) {
00174       ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
00175       return -1;
00176    }
00177    if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
00178       res =  fs->fmt->write(fs, f);
00179       if (res < 0) 
00180          ast_log(LOG_WARNING, "Natural write failed\n");
00181       else if (res > 0)
00182          ast_log(LOG_WARNING, "Huh??\n");
00183    } else {
00184       /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
00185              the one we've setup a translator for, we do the "wrong thing" XXX */
00186       if (fs->trans && f->subclass != fs->lastwriteformat) {
00187          ast_translator_free_path(fs->trans);
00188          fs->trans = NULL;
00189       }
00190       if (!fs->trans) 
00191          fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
00192       if (!fs->trans)
00193          ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
00194             fs->fmt->name, ast_getformatname(f->subclass));
00195       else {
00196          struct ast_frame *trf;
00197          fs->lastwriteformat = f->subclass;
00198          /* Get the translated frame but don't consume the original in case they're using it on another stream */
00199          trf = ast_translate(fs->trans, f, 0);
00200          if (trf) {
00201             res = fs->fmt->write(fs, trf);
00202             ast_frfree(trf);
00203             if (res) 
00204                ast_log(LOG_WARNING, "Translated frame write failed\n");
00205          } else
00206             res = 0;
00207       }
00208    }
00209    return res;
00210 }

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 255 of file file.c.

References asprintf, and ast_config_AST_DATA_DIR.

Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().

00256 {
00257    char *fn = NULL;
00258 
00259    if (!strcmp(ext, "wav49"))
00260       ext = "WAV";
00261 
00262    if (filename[0] == '/')
00263       asprintf(&fn, "%s.%s", filename, ext);
00264    else
00265       asprintf(&fn, "%s/sounds/%s.%s",
00266          ast_config_AST_DATA_DIR, filename, ext);
00267    return fn;
00268 }

static int copy ( const char *  infile,
const char *  outfile 
) [static]

Definition at line 212 of file file.c.

References ast_log(), errno, len, and LOG_WARNING.

Referenced by action_getvar(), ast_filehelper(), copy_plain_file(), iax2_register(), and transcoder_show().

00213 {
00214    int ifd, ofd, len;
00215    char buf[4096];   /* XXX make it lerger. */
00216 
00217    if ((ifd = open(infile, O_RDONLY)) < 0) {
00218       ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
00219       return -1;
00220    }
00221    if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
00222       ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
00223       close(ifd);
00224       return -1;
00225    }
00226    while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
00227       int res;
00228       if (len < 0) {
00229          ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
00230          break;
00231       }
00232       /* XXX handle partial writes */
00233       res = write(ofd, buf, len);
00234       if (res != len) {
00235          ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
00236          len = -1; /* error marker */
00237          break;
00238       }
00239    }
00240    close(ifd);
00241    close(ofd);
00242    if (len < 0) {
00243       unlink(outfile);
00244       return -1; /* error */
00245    }
00246    return 0;   /* success */
00247 }

static int exts_compare ( const char *  exts,
const char *  type 
) [static]

Definition at line 272 of file file.c.

References ext, and strsep().

Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().

00273 {
00274    char tmp[256];
00275    char *stringp = tmp, *ext;
00276 
00277    ast_copy_string(tmp, exts, sizeof(tmp));
00278    while ((ext = strsep(&stringp, "|"))) {
00279       if (!strcmp(ext, type))
00280          return 1;
00281    }
00282 
00283    return 0;
00284 }

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 511 of file file.c.

References ACTION_EXISTS, ast_filehelper(), ast_strdupa, ast_strlen_zero(), DEFAULT_LANGUAGE, fileexists_test(), is_absolute_path(), and strsep().

Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().

00513 {
00514    int res = -1;
00515    char *lang = NULL;
00516 
00517    if (buf == NULL) {
00518       return -1;
00519    }
00520 
00521    if (is_absolute_path(filename)) {
00522       ast_copy_string(buf, filename, buflen);
00523       return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
00524    }
00525 
00526    /* We try languages in the following order:
00527     *    preflang (may include dialect)
00528     *    lang (preflang without dialect - if any)
00529     *    <none>
00530     *    default (unless the same as preflang or lang without dialect)
00531     */
00532 
00533    /* Try preferred language */
00534    if (!ast_strlen_zero(preflang)) {
00535       /* try the preflang exactly as it was requested */
00536       if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) {
00537          return res;
00538       } else {
00539          /* try without a dialect */
00540          char *postfix = NULL;
00541          postfix = lang = ast_strdupa(preflang);
00542 
00543          strsep(&postfix, "_");
00544          if (postfix) {
00545             if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
00546                return res;
00547             }
00548          }
00549       }
00550    }
00551 
00552    /* Try without any language */
00553    if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
00554       return res;
00555    }
00556 
00557    /* Finally try the default language unless it was already tried before */
00558    if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
00559       if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
00560          return res;
00561       }
00562    }
00563 
00564    return 0;
00565 }

static int fileexists_test ( const char *  filename,
const char *  fmt,
const char *  lang,
char *  buf,
int  buflen 
) [static]

Definition at line 474 of file file.c.

References ACTION_EXISTS, ast_filehelper(), and offset.

Referenced by fileexists_core().

00476 {
00477    if (buf == NULL) {
00478       return -1;
00479    }
00480 
00481    if (ast_language_is_prefix) { /* new layout */
00482       if (lang) {
00483          snprintf(buf, buflen, "%s/%s", lang, filename);
00484       } else {
00485          snprintf(buf, buflen, "%s", filename);
00486       }
00487    } else { /* old layout */
00488       strcpy(buf, filename);  /* first copy the full string */
00489       if (lang) {
00490          /* insert the language and suffix if needed */
00491          const char *c = strrchr(filename, '/');
00492          int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
00493          snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
00494       }
00495    }
00496 
00497    return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
00498 }

static int fn_wrapper ( struct ast_filestream s,
const char *  comment,
enum wrap_fn  mode 
) [static]

Definition at line 310 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().

00311 {
00312    struct ast_format *f = s->fmt;
00313    int ret = -1;
00314 
00315    if (mode == WRAP_OPEN && f->open && f->open(s))
00316                 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
00317    else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
00318                 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
00319    else {
00320       /* preliminary checks succeed. update usecount */
00321       ast_module_ref(f->module);
00322       ret = 0;
00323    }
00324         return ret;
00325 }

static struct ast_filestream* get_filestream ( struct ast_format fmt,
FILE *  bfile 
) [static]

Definition at line 286 of file file.c.

References ast_calloc, fmt, and s.

Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().

00287 {
00288    struct ast_filestream *s;
00289 
00290    int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;  /* total allocation size */
00291    if ( (s = ast_calloc(1, l)) == NULL)
00292       return NULL;
00293    s->fmt = fmt;
00294    s->f = bfile;
00295 
00296    if (fmt->desc_size)
00297       s->_private = ((char *)(s+1)) + fmt->buf_size;
00298    if (fmt->buf_size)
00299       s->buf = (char *)(s+1);
00300    s->fr.src = fmt->name;
00301    return s;
00302 }

static int is_absolute_path ( const char *  filename  )  [static]

Definition at line 469 of file file.c.

Referenced by fileexists_core().

00470 {
00471    return filename[0] == '/';
00472 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 332 of file file.c.

References fn_wrapper(), s, and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00333 {
00334    return fn_wrapper(s, NULL, WRAP_OPEN);
00335 }

static int rewrite_wrapper ( struct ast_filestream s,
const char *  comment 
) [static]

Definition at line 327 of file file.c.

References fn_wrapper(), and s.

Referenced by ast_writefile().

00328 {
00329    return fn_wrapper(s, comment, WRAP_REWRITE);
00330 }

static int show_file_formats ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1249 of file file.c.

References ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01250 {
01251 #define FORMAT "%-10s %-10s %-20s\n"
01252 #define FORMAT2 "%-10s %-10s %-20s\n"
01253    struct ast_format *f;
01254    int count_fmt = 0;
01255 
01256    if (argc != 4)
01257       return RESULT_SHOWUSAGE;
01258    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01259 
01260    AST_RWLIST_RDLOCK(&formats);
01261    AST_RWLIST_TRAVERSE(&formats, f, list) {
01262       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01263       count_fmt++;
01264    }
01265    AST_RWLIST_UNLOCK(&formats);
01266    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01267    return RESULT_SUCCESS;
01268 #undef FORMAT
01269 #undef FORMAT2
01270 }

static int show_file_formats_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1272 of file file.c.

References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01273 {
01274 #define FORMAT "%-10s %-10s %-20s\n"
01275 #define FORMAT2 "%-10s %-10s %-20s\n"
01276    struct ast_format *f;
01277    int count_fmt = 0;
01278    
01279    if (argc != 3)
01280       return RESULT_SHOWUSAGE;
01281    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01282    
01283    if (AST_LIST_LOCK(&formats)) {
01284       ast_log(LOG_WARNING, "Unable to lock format list\n");
01285       return -1;
01286    }
01287    
01288    AST_LIST_TRAVERSE(&formats, f, list) {
01289       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01290       count_fmt++;
01291    }
01292    AST_LIST_UNLOCK(&formats);
01293    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01294    return RESULT_SUCCESS;
01295 #undef FORMAT
01296 #undef FORMAT2
01297 }

static int waitstream_core ( struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  skip_ms,
int  audiofd,
int  cmdfd,
const char *  context 
) [static]

the core of all waitstream() functions

Definition at line 1074 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_filestream::orig_chan_name, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.

Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().

01077 {
01078    const char *orig_chan_name = NULL;
01079    int err = 0;
01080 
01081    if (!breakon)
01082       breakon = "";
01083    if (!forward)
01084       forward = "";
01085    if (!rewind)
01086       rewind = "";
01087 
01088    /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
01089    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
01090 
01091    if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM))
01092       orig_chan_name = ast_strdupa(c->name);
01093 
01094    while (c->stream) {
01095       int res;
01096       int ms;
01097 
01098       if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) {
01099          ast_stopstream(c);
01100          err = 1;
01101          break;
01102       }
01103 
01104       ms = ast_sched_wait(c->sched);
01105 
01106       if (ms < 0 && !c->timingfunc) {
01107          ast_stopstream(c);
01108          break;
01109       }
01110       if (ms < 0)
01111          ms = 1000;
01112       if (cmdfd < 0) {
01113          res = ast_waitfor(c, ms);
01114          if (res < 0) {
01115             ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01116             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01117             return res;
01118          }
01119       } else {
01120          int outfd;
01121          struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01122          if (!rchan && (outfd < 0) && (ms)) {
01123             /* Continue */
01124             if (errno == EINTR)
01125                continue;
01126             ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01127             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01128             return -1;
01129          } else if (outfd > -1) { /* this requires cmdfd set */
01130             /* The FD we were watching has something waiting */
01131             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01132             return 1;
01133          }
01134          /* if rchan is set, it is 'c' */
01135          res = rchan ? 1 : 0; /* map into 'res' values */
01136       }
01137       if (res > 0) {
01138          struct ast_frame *fr = ast_read(c);
01139          if (!fr) {
01140             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01141             return -1;
01142          }
01143          switch(fr->frametype) {
01144          case AST_FRAME_DTMF_END:
01145             if (context) {
01146                const char exten[2] = { fr->subclass, '\0' };
01147                if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
01148                   res = fr->subclass;
01149                   ast_frfree(fr);
01150                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01151                   return res;
01152                }
01153             } else {
01154                res = fr->subclass;
01155                if (strchr(forward,res)) {
01156                   ast_stream_fastforward(c->stream, skip_ms);
01157                } else if (strchr(rewind,res)) {
01158                   ast_stream_rewind(c->stream, skip_ms);
01159                } else if (strchr(breakon, res)) {
01160                   ast_frfree(fr);
01161                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01162                   return res;
01163                }              
01164             }
01165             break;
01166          case AST_FRAME_CONTROL:
01167             switch(fr->subclass) {
01168             case AST_CONTROL_HANGUP:
01169             case AST_CONTROL_BUSY:
01170             case AST_CONTROL_CONGESTION:
01171                ast_frfree(fr);
01172                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01173                return -1;
01174             case AST_CONTROL_RINGING:
01175             case AST_CONTROL_ANSWER:
01176             case AST_CONTROL_VIDUPDATE:
01177             case AST_CONTROL_SRCUPDATE:
01178             case AST_CONTROL_HOLD:
01179             case AST_CONTROL_UNHOLD:
01180                /* Unimportant */
01181                break;
01182             default:
01183                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01184             }
01185             break;
01186          case AST_FRAME_VOICE:
01187             /* Write audio if appropriate */
01188             if (audiofd > -1)
01189                write(audiofd, fr->data, fr->datalen);
01190          default:
01191             /* Ignore all others */
01192             break;
01193          }
01194          ast_frfree(fr);
01195       }
01196       ast_sched_runq(c->sched);
01197    }
01198 
01199    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01200 
01201    return (err || c->_softhangup) ? -1 : 0;
01202 }


Variable Documentation

int ast_language_is_prefix = 1

Definition at line 64 of file file.c.

struct ast_cli_entry cli_file[]

Initial value:

 {
   { { "core", "show", "file", "formats" },
   show_file_formats, "Displays file formats",
   show_file_formats_usage, NULL, &cli_show_file_formats_deprecated },
}

Definition at line 1308 of file file.c.

Referenced by ast_file_init().

struct ast_cli_entry cli_show_file_formats_deprecated

Initial value:

 {
   { "show", "file", "formats" },
   show_file_formats_deprecated, NULL,
   NULL }

Definition at line 1303 of file file.c.

char show_file_formats_usage[]

Initial value:

 
"Usage: core show file formats\n"
"       Displays currently registered file formats (if any)\n"

Definition at line 1299 of file file.c.


Generated on Mon Mar 31 07:40:38 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1