Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:50 2009

## Asterisk developer's documentation

# file.h File Reference

Generic File Format Support. More...

`#include "asterisk/channel.h"`
`#include "asterisk/frame.h"`
`#include <fcntl.h>`

Include dependency graph for file.h:

Go to the source code of this file.

## Defines

#define | AST_DIGIT_ANY "0123456789#*ABCD"
#define | AST_DIGIT_ANYNUM "0123456789"
#define | AST_RESERVED_POINTERS 20
#define | SEEK_FORCECUR 10

## Functions

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 *oldname, const char *newname, const char *fmt)
int | ast_filedelete (const char *filename, const char *fmt)
int | ast_fileexists (const char *filename, const char *fmt, const char *preflang)
int | ast_filerename (const char *oldname, const char *newname, const char *fmt)
int | ast_format_register (const char *name, const char *exts, int format, struct ast_filestream *(*open)(FILE *f), struct ast_filestream *(*rewrite)(FILE *f, const char *comment), int(*write)(struct ast_filestream *, struct ast_frame *), int(*seek)(struct ast_filestream *, long offset, int whence), int(*trunc)(struct ast_filestream *), long(*tell)(struct ast_filestream *), struct ast_frame *(*read)(struct ast_filestream *, int *timetonext), void(*close)(struct ast_filestream *), char *(*getcomment)(struct ast_filestream *))
int | ast_format_unregister (const char *name)
struct ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
struct ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
struct ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
int | ast_playstream (struct ast_filestream *s)
struct ast_filestream * | ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
struct ast_frame * | ast_readframe (struct ast_filestream *s)
int | ast_seekstream (struct ast_filestream *fs, long sample_offset, int whence)
int | ast_stopstream (struct ast_channel *c)
int | ast_stream_fastforward (struct ast_filestream *fs, long ms)
int | ast_stream_rewind (struct ast_filestream *fs, long ms)
int | ast_streamfile (struct ast_channel *c, const char *filename, const char *preflang)
long | 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 monfd)
struct ast_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f)

## Detailed Description

Generic File Format Support.

Definition in file file.h.

## Define Documentation

#define AST_DIGIT_ANY "0123456789#*ABCD"

Convenient for waiting

Definition at line 41 of file file.h.

Referenced by __login_exec(), ast_ivr_menu_run_internal(), ast_play_and_wait(), ast_readstring(), ast_readstring_full(), ast_record_review(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_blindtransfer(), conf_exec(), conf_run(), dial_exec_full(), dictate_exec(), directory_exec(), festival_exec(), get_folder(), ivr_dispatch(), pbx_builtin_background(), play_file(), play_mailbox_owner(), play_message(), play_message_callerid(), play_message_datetime(), play_message_duration(), play_record_review(), retrydial_exec(), say_and_wait(), say_position(), sayunixtime_exec(), try_calling(), vm_intro_gr(), vm_intro_pt(), and wait_file2().

#define AST_DIGIT_ANYNUM "0123456789"

Definition at line 42 of file file.h.

Referenced by initreqprep().

#define AST_RESERVED_POINTERS 20

Definition at line 312 of file file.h.

#define SEEK_FORCECUR 10

Definition at line 44 of file file.h.

Referenced by ast_read(), ast_write(), au_seek(), g729_seek(), gsm_seek(), ilbc_seek(), pcm_seek(), slinear_seek(), vox_seek(), and wav_seek().

## Function Documentation

int ast_applystream | ( | struct ast_channel * | chan,
|  | struct ast_filestream * | s |
| ) |  |  |

Applys a open stream to a channel.

Parameters:

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

Definition at line 649 of file file.c.

References ast_filestream::owner.

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

    00650 {
    00651    s->owner = chan;
    00652    return 0;
    00653 }

int ast_closestream | ( | struct ast_filestream * | f | ) |

Closes a stream

Parameters:

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

Definition at line 694 of file file.c.

References AST_FORMAT_MAX_AUDIO, ast_safe_system(), ast_sched_del(), ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_channel::vstream, and ast_channel::vstreamid.

Referenced by ast_app_getvoice(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_play_and_prepend(), ast_play_and_record_full(), ast_stopstream(), dictate_exec(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), record_exec(), and recordthread().

    00695 {
    00696    char *cmd = NULL;
    00697    size_t size = 0;
    00698    /* Stop a running stream if there is one */
    00699    if (f->owner) {
    00700       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
    00701          f->owner->stream = NULL;
    00702          if (f->owner->streamid > -1)
    00703             ast_sched_del(f->owner->sched, f->owner->streamid);
    00704          f->owner->streamid = -1;
    00705 #ifdef ZAPTEL_OPTIMIZATIONS
    00706          ast_settimeout(f->owner, 0, NULL, NULL);
    00707 #endif
    00708       } else {
    00709          f->owner->vstream = NULL;
    00710          if (f->owner->vstreamid > -1)
    00711             ast_sched_del(f->owner->sched, f->owner->vstreamid);
    00712          f->owner->vstreamid = -1;
    00713       }
    00714    }
    00715    /* destroy the translator on exit */
    00716    if (f->trans) {
    00717       ast_translator_free_path(f->trans);
    00718       f->trans = NULL;
    00719    }
    00720
    00721    if (f->realfilename && f->filename) {
    00722          size = strlen(f->filename) + strlen(f->realfilename) + 15;
    00723          cmd = alloca(size);
    00724          memset(cmd,0,size);
    00725          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
    00726          ast_safe_system(cmd);
    00727    }
    00728
    00729    if (f->filename) {
    00730       free(f->filename);
    00731       f->filename = NULL;
    00732    }
    00733    if (f->realfilename) {
    00734       free(f->realfilename);
    00735       f->realfilename = NULL;
    00736    }
    00737    f->fmt->close(f);
    00738    return 0;
    00739 }

int ast_file_init | ( | void |  | ) |

Initialize file stuff

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

Definition at line 1302 of file file.c.

References ast_cli_register().

Referenced by main().

    01303 {
    01304    ast_cli_register(&show_file);
    01305    return 0;
    01306 }

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

Copies a file

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

References ACTION_COPY, and ast_filehelper().

Referenced by copy_file().

    00801 {
    00802    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
    00803 }

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

Deletes a file

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

References ACTION_DELETE, and ast_filehelper().

Referenced by ast_monitor_start(), ast_monitor_stop(), ast_play_and_prepend(), conf_run(), dial_exec_full(), leave_voicemail(), play_mailbox_owner(), play_record_review(), and vm_delete().

    00791 {
    00792    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
    00793 }

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

Checks for the existence of a given file

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

References ACTION_EXISTS, ast_filehelper(), ast_strlen_zero(), MAX_LANGUAGE, and strsep().

Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_openstream_full(), ast_openvstream(), chanspy_exec(), conf_run(), dial_exec_full(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), vm_newuser(), and vm_tempgreeting().

    00743 {
    00744    char filename2[256];
    00745    char tmp[256];
    00746    char *postfix;
    00747    char *prefix;
    00748    char *c;
    00749    char lang2[MAX_LANGUAGE];
    00750    int res = -1;
    00751    if (!ast_strlen_zero(preflang)) {
    00752       /* Insert the language between the last two parts of the path */
    00753       ast_copy_string(tmp, filename, sizeof(tmp));
    00754       c = strrchr(tmp, '/');
    00755       if (c) {
    00756          *c = '\0';
    00757          postfix = c+1;
    00758          prefix = tmp;
    00759          snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix);
    00760       } else {
    00761          postfix = tmp;
    00762          prefix="";
    00763          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, postfix);
    00764       }
    00765       res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
    00766       if (res < 1) {
    00767          char *stringp=NULL;
    00768          ast_copy_string(lang2, preflang, sizeof(lang2));
    00769          stringp=lang2;
    00770          strsep(&stringp, "_");
    00771          /* If language is a specific locality of a language (like es_MX), strip the locality and try again */
    00772          if (strcmp(lang2, preflang)) {
    00773             if (ast_strlen_zero(prefix)) {
    00774                snprintf(filename2, sizeof(filename2), "%s/%s", lang2, postfix);
    00775             } else {
    00776                snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix);
    00777             }
    00778             res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
    00779          }
    00780       }
    00781    }
    00782
    00783    /* Fallback to no language (usually winds up being American English) */
    00784    if (res < 1) {
    00785       res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS);
    00786    }
    00787    return res;
    00788 }

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

Renames a file

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

References ACTION_RENAME, and ast_filehelper().

Referenced by ast_monitor_stop(), ast_play_and_prepend(), leave_voicemail(), play_record_review(), and rename_file().

    00796 {
    00797    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
    00798 }

int ast_format_register | ( | const char * | name,
|  | const char * | exts,
|  | int | format,
|  | struct ast_filestream *(*)(FILE *f) | open,
|  | struct ast_filestream *(*)(FILE *f, const char *comment) | rewrite,
|  | int(*)(struct ast_filestream *, struct ast_frame *) | write,
|  | int(*)(struct ast_filestream *, long offset, int whence) | seek,
|  | int(*)(struct ast_filestream *) | trunc,
|  | long(*)(struct ast_filestream *) | tell,
|  | struct ast_frame *(*)(struct ast_filestream *, int *timetonext) | read,
|  | void(*)(struct ast_filestream *) | close,
|  | char *(*)(struct ast_filestream *) | getcomment |
| ) |  |  |

Registers a new file format

Register a new file format capability Adds a format to asterisk's format abilities. Fill in the fields, and it will work. For examples, look at some of the various format code. returns 0 on success, -1 on failure

int ast_format_unregister | ( | const char * | name | ) |

Unregisters a file format

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, LOG_WARNING, ast_format::name, ast_format::next, option_verbose, and VERBOSE_PREFIX_2.

Referenced by unload_module().

    00157 {
    00158    struct ast_format *tmp, *tmpl = NULL;
    00159    if (ast_mutex_lock(&formatlock)) {
    00160       ast_log(LOG_WARNING, "Unable to lock format list\n");
    00161       return -1;
    00162    }
    00163    tmp = formats;
    00164    while(tmp) {
    00165       if (!strcasecmp(name, tmp->name)) {
    00166          if (tmpl)
    00167             tmpl->next = tmp->next;
    00168          else
    00169             formats = tmp->next;
    00170          free(tmp);
    00171          ast_mutex_unlock(&formatlock);
    00172          if (option_verbose > 1)
    00173             ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
    00174          return 0;
    00175       }
    00176       tmpl = tmp;
    00177       tmp = tmp->next;
    00178    }
    00179    ast_mutex_unlock(&formatlock);
    00180    ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
    00181    return -1;
    00182 }

struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan,
|  | const char * | filename,
|  | const char * | preflang |
| ) |  |  | `[read]`

Opens stream for use in seeking, playing

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

References ast_openstream_full().

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

    00471 {
    00472    return ast_openstream_full(chan, filename, preflang, 0);
    00473 }

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

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

References ACTION_OPEN, ast_deactivate_generator(), ast_fileexists(), ast_filehelper(), ast_log(), ast_set_write_format(), ast_stopstream(), ast_strlen_zero(), ast_channel::generator, LOG_WARNING, ast_channel::oldwriteformat, and ast_channel::writeformat.

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

    00476 {
    00477    /* This is a fairly complex routine.  Essentially we should do
    00478       the following:
    00479
    00480       1) Find which file handlers produce our type of format.
    00481       2) Look for a filename which it can handle.
    00482       3) If we find one, then great.
    00483       4) If not, see what files are there
    00484       5) See what we can actually support
    00485       6) Choose the one with the least costly translator path and
    00486           set it up.
    00487
    00488    */
    00489    int fmts = -1;
    00490    char filename2[256]="";
    00491    char filename3[256];
    00492    char *endpart;
    00493    int res;
    00494
    00495    if (!asis) {
    00496       /* do this first, otherwise we detect the wrong writeformat */
    00497       ast_stopstream(chan);
    00498       if (chan->generator)
    00499          ast_deactivate_generator(chan);
    00500    }
    00501    if (!ast_strlen_zero(preflang)) {
    00502       ast_copy_string(filename3, filename, sizeof(filename3));
    00503       endpart = strrchr(filename3, '/');
    00504       if (endpart) {
    00505          *endpart = '\0';
    00506          endpart++;
    00507          snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart);
    00508       } else
    00509          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
    00510       fmts = ast_fileexists(filename2, NULL, NULL);
    00511    }
    00512    if (fmts < 1) {
    00513       ast_copy_string(filename2, filename, sizeof(filename2));
    00514       fmts = ast_fileexists(filename2, NULL, NULL);
    00515    }
    00516    if (fmts < 1) {
    00517       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
    00518       return NULL;
    00519    }
    00520    chan->oldwriteformat = chan->writeformat;
    00521    /* Set the channel to a format we can work with */
    00522    res = ast_set_write_format(chan, fmts);
    00523
    00524    res = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN);
    00525    if (res >= 0)
    00526       return chan->stream;
    00527    return NULL;
    00528 }

struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan,
|  | const char * | filename,
|  | const char * | preflang |
| ) |  |  | `[read]`

Opens stream for use in seeking, playing

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

References ACTION_OPEN, ast_fileexists(), ast_filehelper(), ast_log(), ast_strlen_zero(), fmt, LOG_WARNING, and MAX_LANGUAGE.

Referenced by ast_streamfile().

    00531 {
    00532    /* This is a fairly complex routine.  Essentially we should do
    00533       the following:
    00534
    00535       1) Find which file handlers produce our type of format.
    00536       2) Look for a filename which it can handle.
    00537       3) If we find one, then great.
    00538       4) If not, see what files are there
    00539       5) See what we can actually support
    00540       6) Choose the one with the least costly translator path and
    00541           set it up.
    00542
    00543    */
    00544    int fd = -1;
    00545    int fmts = -1;
    00546    char filename2[256];
    00547    char lang2[MAX_LANGUAGE];
    00548    /* XXX H.263 only XXX */
    00549    char *fmt = "h263";
    00550    if (!ast_strlen_zero(preflang)) {
    00551       snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
    00552       fmts = ast_fileexists(filename2, fmt, NULL);
    00553       if (fmts < 1) {
    00554          ast_copy_string(lang2, preflang, sizeof(lang2));
    00555          snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename);
    00556          fmts = ast_fileexists(filename2, fmt, NULL);
    00557       }
    00558    }
    00559    if (fmts < 1) {
    00560       ast_copy_string(filename2, filename, sizeof(filename2));
    00561       fmts = ast_fileexists(filename2, fmt, NULL);
    00562    }
    00563    if (fmts < 1) {
    00564       return NULL;
    00565    }
    00566    fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN);
    00567    if (fd >= 0)
    00568       return chan->vstream;
    00569    ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
    00570    return NULL;
    00571 }

int ast_playstream | ( | struct ast_filestream * | s | ) |

play a open stream on a channel.

Parameters:

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

Definition at line 655 of file file.c.

References AST_FORMAT_MAX_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, and ast_format::format.

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

    00656 {
    00657    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
    00658       ast_readaudio_callback(s);
    00659    else
    00660       ast_readvideo_callback(s);
    00661    return 0;
    00662 }

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

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), build_filename(), ast_format::exts, exts_compare(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, LOG_WARNING, ast_filestream::mode, ast_format::next, ast_format::open, strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by ast_play_and_prepend().

    00833 {
    00834    FILE *bfile;
    00835    struct ast_format *f;
    00836    struct ast_filestream *fs = NULL;
    00837    char *fn;
    00838
    00839    if (ast_mutex_lock(&formatlock)) {
    00840       ast_log(LOG_WARNING, "Unable to lock format list\n");
    00841       return NULL;
    00842    }
    00843
    00844    for (f = formats; f && !fs; f = f->next) {
    00845       if (!exts_compare(f->exts, type))
    00846          continue;
    00847
    00848       fn = build_filename(filename, type);
    00849       bfile = fopen(fn, "r");
    00850       if (bfile) {
    00851          errno = 0;
    00852
    00853          if (!(fs = f->open(bfile))) {
    00854             ast_log(LOG_WARNING, "Unable to open %s\n", fn);
    00855             fclose(bfile);
    00856             free(fn);
    00857             continue;
    00858          }
    00859
    00860          fs->trans = NULL;
    00861          fs->fmt = f;
    00862          fs->flags = flags;
    00863          fs->mode = mode;
    00864          fs->filename = strdup(filename);
    00865          fs->vfs = NULL;
    00866       } else if (errno != EEXIST)
    00867          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
    00868       free(fn);
    00869    }
    00870
    00871    ast_mutex_unlock(&formatlock);
    00872    if (!fs)
    00873       ast_log(LOG_WARNING, "No such format '%s'\n", type);
    00874
    00875    return fs;
    00876 }

struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) | `[read]`

Read a frame from a filestream

Parameters:

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

Definition at line 573 of file file.c.

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

Referenced by ast_play_and_prepend(), dictate_exec(), gen_readframe(), and moh_files_readframe().

    00574 {
    00575    struct ast_frame *f = NULL;
    00576    int whennext = 0;
    00577    if (s && s->fmt)
    00578       f = s->fmt->read(s, &whennext);
    00579    return f;
    00580 }

int ast_seekstream | ( | struct ast_filestream * | fs,
|  | long | sample_offset,
|  | int | whence |
| ) |  |  |

Seeks into stream

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

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

Referenced by ast_control_streamfile(), ast_moh_files_next(), ast_read(), ast_stream_fastforward(), ast_stream_rewind(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_streamfile().

    00665 {
    00666    return fs->fmt->seek(fs, sample_offset, whence);
    00667 }

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 Returns 0 regardless

Definition at line 184 of file file.c.

References ast_closestream(), ast_log(), ast_set_write_format(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::vstream.

Referenced by adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring(), ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_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_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_phonetic_str_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), background_detect_exec(), background_file(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), record_exec(), recordthread(), rpt_tele_thread(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), vm_authenticate(), vm_execmain(), and zapateller_exec().

    00185 {
    00186    /* Stop a running stream if there is one */
    00187    if (tmp->vstream) {
    00188       ast_closestream(tmp->vstream);
    00189       tmp->vstream = NULL;
    00190    }
    00191    if (tmp->stream) {
    00192       ast_closestream(tmp->stream);
    00193       tmp->stream = NULL;
    00194       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
    00195          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
    00196    }
    00197    return 0;
    00198 }

int ast_stream_fastforward | ( | struct ast_filestream * | fs,
|  | long | ms |
| ) |  |  |

Fast forward stream ms

Parameters:

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

Definition at line 679 of file file.c.

References ast_seekstream(), and ast_frame::samples.

Referenced by ast_waitstream_fr().

    00680 {
    00681    /* I think this is right, 8000 samples per second, 1000 ms a second so 8
    00682     * samples per ms  */
    00683    long samples = ms * 8;
    00684    return ast_seekstream(fs, samples, SEEK_CUR);
    00685 }

int ast_stream_rewind | ( | struct ast_filestream * | fs,
|  | long | ms |
| ) |  |  |

Rewind stream ms

Parameters:

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

Definition at line 687 of file file.c.

References ast_seekstream(), and ast_frame::samples.

Referenced by ast_play_and_prepend(), ast_play_and_record_full(), ast_waitstream_fr(), handle_recordfile(), and record_exec().

    00688 {
    00689    long samples = ms * 8;
    00690    samples = samples * -1;
    00691    return ast_seekstream(fs, samples, SEEK_CUR);
    00692 }

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

Streams a file

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

References ast_applystream(), ast_getformatname(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_verbose(), LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_verbose, VERBOSE_PREFIX_3, and ast_filestream::vfs.

Referenced by __login_exec(), agent_call(), ast_app_getdata(), ast_app_getdata_full(), ast_app_getvoice(), ast_control_streamfile(), ast_play_and_prepend(), ast_play_and_record_full(), ast_play_and_wait(), ast_record_review(), ast_say_character_str_full(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), 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_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_digit_str_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_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_phonetic_str_full(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), auth_exec(), background_detect_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_mailbox_owner(), play_message_callerid(), play_record_review(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().

    00806 {
    00807    struct ast_filestream *fs;
    00808    struct ast_filestream *vfs;
    00809
    00810    fs = ast_openstream(chan, filename, preflang);
    00811    vfs = ast_openvstream(chan, filename, preflang);
    00812    if (vfs)
    00813       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
    00814    if (fs){
    00815       if (ast_applystream(chan, fs))
    00816          return -1;
    00817       if (vfs && ast_applystream(chan, vfs))
    00818          return -1;
    00819       ast_playstream(fs);
    00820       if (vfs)
    00821          ast_playstream(vfs);
    00822 #if 1
    00823       if (option_verbose > 2)
    00824          ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default");
    00825 #endif
    00826       return 0;
    00827    }
    00828    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno));
    00829    return -1;
    00830 }

long ast_tellstream | ( | struct ast_filestream * | fs | ) |

Tell where we are in a stream

Parameters:

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

Definition at line 674 of file file.c.

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

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

    00675 {
    00676    return fs->fmt->tell(fs);
    00677 }

int ast_truncstream | ( | struct ast_filestream * | fs | ) |

Trunc stream at current location

Parameters:

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

Definition at line 669 of file file.c.

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

Referenced by ast_play_and_prepend(), ast_play_and_record_full(), handle_recordfile(), and record_exec().

    00670 {
    00671    return fs->fmt->trunc(fs);
    00672 }

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

Waits for a stream to stop or digit to be pressed

Parameters:

  | c | channel to waitstram 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 997 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by __login_exec(), agent_call(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), ast_play_and_wait(), ast_readstring(), ast_record_review(), ast_say_character_str_full(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), 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_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_digit_str_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_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_phonetic_str_full(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), auth_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_mailbox_owner(), play_message_callerid(), play_record_review(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().

    00998 {
    00999    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
    01000    int res;
    01001    struct ast_frame *fr;
    01002    if (!breakon) breakon = "";
    01003    while(c->stream) {
    01004       res = ast_sched_wait(c->sched);
    01005       if ((res < 0) && !c->timingfunc) {
    01006          ast_stopstream(c);
    01007          break;
    01008       }
    01009       if (res < 0)
    01010          res = 1000;
    01011       res = ast_waitfor(c, res);
    01012       if (res < 0) {
    01013          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
    01014          return res;
    01015       } else if (res > 0) {
    01016          fr = ast_read(c);
    01017          if (!fr) {
    01018 #if 0
    01019             ast_log(LOG_DEBUG, "Got hung up\n");
    01020 #endif
    01021             return -1;
    01022          }
    01023
    01024          switch(fr->frametype) {
    01025          case AST_FRAME_DTMF:
    01026             res = fr->subclass;
    01027             if (strchr(breakon, res)) {
    01028                ast_frfree(fr);
    01029                return res;
    01030             }
    01031             break;
    01032          case AST_FRAME_CONTROL:
    01033             switch(fr->subclass) {
    01034             case AST_CONTROL_HANGUP:
    01035             case AST_CONTROL_BUSY:
    01036             case AST_CONTROL_CONGESTION:
    01037                ast_frfree(fr);
    01038                return -1;
    01039             case AST_CONTROL_RINGING:
    01040             case AST_CONTROL_ANSWER:
    01041             case AST_CONTROL_VIDUPDATE:
    01042                /* Unimportant */
    01043                break;
    01044             default:
    01045                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
    01046             }
    01047          }
    01048          /* Ignore */
    01049          ast_frfree(fr);
    01050       }
    01051       ast_sched_runq(c->sched);
    01052    }
    01053    return (c->_softhangup ? -1 : 0);
    01054 }

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

Parameters:

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

Definition at line 1200 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), AST_MAX_EXTENSION, ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, exten, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by pbx_builtin_background().

    01201 {
    01202    /* Waitstream, with return in the case of a valid 1 digit extension */
    01203    /* in the current or specified context being pressed */
    01204    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
    01205    int res;
    01206    struct ast_frame *fr;
    01207    char exten[AST_MAX_EXTENSION];
    01208
    01209    if (!context) context = c->context;
    01210    while(c->stream) {
    01211       res = ast_sched_wait(c->sched);
    01212       if ((res < 0) && !c->timingfunc) {
    01213          ast_stopstream(c);
    01214          break;
    01215       }
    01216       if (res < 0)
    01217          res = 1000;
    01218       res = ast_waitfor(c, res);
    01219       if (res < 0) {
    01220          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
    01221          return res;
    01222       } else if (res > 0) {
    01223          fr = ast_read(c);
    01224          if (!fr) {
    01225 #if 0
    01226             ast_log(LOG_DEBUG, "Got hung up\n");
    01227 #endif
    01228             return -1;
    01229          }
    01230
    01231          switch(fr->frametype) {
    01232          case AST_FRAME_DTMF:
    01233             res = fr->subclass;
    01234             snprintf(exten, sizeof(exten), "%c", res);
    01235             if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
    01236                ast_frfree(fr);
    01237                return res;
    01238             }
    01239             break;
    01240          case AST_FRAME_CONTROL:
    01241             switch(fr->subclass) {
    01242             case AST_CONTROL_HANGUP:
    01243             case AST_CONTROL_BUSY:
    01244             case AST_CONTROL_CONGESTION:
    01245                ast_frfree(fr);
    01246                return -1;
    01247             case AST_CONTROL_RINGING:
    01248             case AST_CONTROL_ANSWER:
    01249                /* Unimportant */
    01250                break;
    01251             default:
    01252                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
    01253             }
    01254          }
    01255          /* Ignore */
    01256          ast_frfree(fr);
    01257       }
    01258       ast_sched_runq(c->sched);
    01259    }
    01260    return (c->_softhangup ? -1 : 0);
    01261 }

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

Parameters:

  | c | channel to waitstram 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 1056 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_stream_fastforward(), ast_stream_rewind(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by ast_control_streamfile().

    01057 {
    01058    int res;
    01059    struct ast_frame *fr;
    01060
    01061    if (!breakon)
    01062          breakon = "";
    01063    if (!forward)
    01064          forward = "";
    01065    if (!rewind)
    01066          rewind = "";
    01067
    01068    while(c->stream) {
    01069       res = ast_sched_wait(c->sched);
    01070       if ((res < 0) && !c->timingfunc) {
    01071          ast_stopstream(c);
    01072          break;
    01073       }
    01074       if (res < 0)
    01075          res = 1000;
    01076       res = ast_waitfor(c, res);
    01077       if (res < 0) {
    01078          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
    01079          return res;
    01080       } else
    01081       if (res > 0) {
    01082          fr = ast_read(c);
    01083          if (!fr) {
    01084 #if 0
    01085             ast_log(LOG_DEBUG, "Got hung up\n");
    01086 #endif
    01087             return -1;
    01088          }
    01089
    01090          switch(fr->frametype) {
    01091          case AST_FRAME_DTMF:
    01092             res = fr->subclass;
    01093             if (strchr(forward,res)) {
    01094                ast_stream_fastforward(c->stream, ms);
    01095             } else if (strchr(rewind,res)) {
    01096                ast_stream_rewind(c->stream, ms);
    01097             } else if (strchr(breakon, res)) {
    01098                ast_frfree(fr);
    01099                return res;
    01100             }
    01101             break;
    01102          case AST_FRAME_CONTROL:
    01103             switch(fr->subclass) {
    01104             case AST_CONTROL_HANGUP:
    01105             case AST_CONTROL_BUSY:
    01106             case AST_CONTROL_CONGESTION:
    01107                ast_frfree(fr);
    01108                return -1;
    01109             case AST_CONTROL_RINGING:
    01110             case AST_CONTROL_ANSWER:
    01111                /* Unimportant */
    01112                break;
    01113             default:
    01114                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
    01115             }
    01116          }
    01117          /* Ignore */
    01118          ast_frfree(fr);
    01119       } else
    01120          ast_sched_runq(c->sched);
    01121
    01122
    01123    }
    01124    return (c->_softhangup ? -1 : 0);
    01125 }

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

Definition at line 1127 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_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_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_phonetic_str_full(), handle_getoption(), handle_streamfile(), and pl_odtworz_plik().

    01128 {
    01129    int res;
    01130    int ms;
    01131    int outfd;
    01132    struct ast_frame *fr;
    01133    struct ast_channel *rchan;
    01134
    01135    if (!breakon)
    01136       breakon = "";
    01137
    01138    while(c->stream) {
    01139       ms = ast_sched_wait(c->sched);
    01140       if ((ms < 0) && !c->timingfunc) {
    01141          ast_stopstream(c);
    01142          break;
    01143       }
    01144       if (ms < 0)
    01145          ms = 1000;
    01146       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
    01147       if (!rchan && (outfd < 0) && (ms)) {
    01148          /* Continue */
    01149          if (errno == EINTR)
    01150             continue;
    01151          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
    01152          return -1;
    01153       } else if (outfd > -1) {
    01154          /* The FD we were watching has something waiting */
    01155          return 1;
    01156       } else if (rchan) {
    01157          fr = ast_read(c);
    01158          if (!fr) {
    01159 #if 0
    01160             ast_log(LOG_DEBUG, "Got hung up\n");
    01161 #endif
    01162             return -1;
    01163          }
    01164
    01165          switch(fr->frametype) {
    01166          case AST_FRAME_DTMF:
    01167             res = fr->subclass;
    01168             if (strchr(breakon, res)) {
    01169                ast_frfree(fr);
    01170                return res;
    01171             }
    01172             break;
    01173          case AST_FRAME_CONTROL:
    01174             switch(fr->subclass) {
    01175             case AST_CONTROL_HANGUP:
    01176             case AST_CONTROL_BUSY:
    01177             case AST_CONTROL_CONGESTION:
    01178                ast_frfree(fr);
    01179                return -1;
    01180             case AST_CONTROL_RINGING:
    01181             case AST_CONTROL_ANSWER:
    01182                /* Unimportant */
    01183                break;
    01184             default:
    01185                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
    01186             }
    01187          case AST_FRAME_VOICE:
    01188             /* Write audio if appropriate */
    01189             if (audiofd > -1)
    01190                write(audiofd, fr->data, fr->datalen);
    01191          }
    01192          /* Ignore */
    01193          ast_frfree(fr);
    01194       }
    01195       ast_sched_runq(c->sched);
    01196    }
    01197    return (c->_softhangup ? -1 : 0);
    01198 }

struct ast_filestream* ast_writefile | ( | const char * | filename,
|  | const char * | type,
|  | const char * | comment,
|  | int | flags,
|  | int | check,
|  | mode_t | mode |
| ) |  |  | `[read]`

Starts writing a file

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_filestream::buf, build_filename(), ast_format::exts, exts_compare(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, LOG_WARNING, ast_filestream::mode, ast_format::next, option_cache_record_files, ast_filestream::realfilename, record_cache_dir, ast_format::rewrite, ast_format::seek, strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by ast_app_getvoice(), ast_monitor_start(), ast_play_and_prepend(), ast_play_and_record_full(), ast_writestream(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

    00879 {
    00880    int fd, myflags = 0;
    00881    /* compiler claims this variable can be used before initialization... */
    00882    FILE *bfile = NULL;
    00883    struct ast_format *f;
    00884    struct ast_filestream *fs = NULL;
    00885    char *fn, *orig_fn = NULL;
    00886    char *buf = NULL;
    00887    size_t size = 0;
    00888    int format_found = 0;
    00889
    00890    if (ast_mutex_lock(&formatlock)) {
    00891       ast_log(LOG_WARNING, "Unable to lock format list\n");
    00892       return NULL;
    00893    }
    00894
    00895    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
    00896    if (flags & O_APPEND) {
    00897       /* We really can't use O_APPEND as it will break WAV header updates */
    00898       flags &= ~O_APPEND;
    00899    } else {
    00900       myflags = O_TRUNC;
    00901    }
    00902
    00903    myflags |= O_WRONLY | O_CREAT;
    00904
    00905    for (f = formats; f && !fs; f = f->next) {
    00906       if (!exts_compare(f->exts, type))
    00907          continue;
    00908       else
    00909          format_found = 1;
    00910
    00911       fn = build_filename(filename, type);
    00912       fd = open(fn, flags | myflags, mode);
    00913       if (fd > -1) {
    00914          /* fdopen() the resulting file stream */
    00915          bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
    00916          if (!bfile) {
    00917             ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
    00918             close(fd);
    00919             fd = -1;
    00920          }
    00921       }
    00922
    00923       if (option_cache_record_files && (fd > -1)) {
    00924          char *c;
    00925
    00926          fclose(bfile);
    00927          /*
    00928            We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
    00929            What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
    00930          */
    00931          orig_fn = ast_strdupa(fn);
    00932          for (c = fn; *c; c++)
    00933             if (*c == '/')
    00934                *c = '_';
    00935
    00936          size = strlen(fn) + strlen(record_cache_dir) + 2;
    00937          buf = alloca(size);
    00938          strcpy(buf, record_cache_dir);
    00939          strcat(buf, "/");
    00940          strcat(buf, fn);
    00941          free(fn);
    00942          fn = buf;
    00943          fd = open(fn, flags | myflags, mode);
    00944          if (fd > -1) {
    00945             /* fdopen() the resulting file stream */
    00946             bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
    00947             if (!bfile) {
    00948                ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
    00949                close(fd);
    00950                fd = -1;
    00951             }
    00952          }
    00953       }
    00954       if (fd > -1) {
    00955          errno = 0;
    00956          if ((fs = f->rewrite(bfile, comment))) {
    00957             fs->trans = NULL;
    00958             fs->fmt = f;
    00959             fs->flags = flags;
    00960             fs->mode = mode;
    00961             if (orig_fn) {
    00962                fs->realfilename = strdup(orig_fn);
    00963                fs->filename = strdup(fn);
    00964             } else {
    00965                fs->realfilename = NULL;
    00966                fs->filename = strdup(filename);
    00967             }
    00968             fs->vfs = NULL;
    00969             /* If truncated, we'll be at the beginning; if not truncated, then append */
    00970             f->seek(fs, 0, SEEK_END);
    00971          } else {
    00972             ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
    00973             close(fd);
    00974             if (orig_fn) {
    00975                unlink(fn);
    00976                unlink(orig_fn);
    00977             }
    00978          }
    00979       } else if (errno != EEXIST) {
    00980          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
    00981          if (orig_fn)
    00982             unlink(orig_fn);
    00983       }
    00984       /* if buf != NULL then fn is already free and pointing to it */
    00985       if (!buf)
    00986          free(fn);
    00987    }
    00988
    00989    ast_mutex_unlock(&formatlock);
    00990
    00991    if (!format_found)
    00992       ast_log(LOG_WARNING, "No such format '%s'\n", type);
    00993
    00994    return fs;
    00995 }

int ast_writestream | ( | struct ast_filestream * | fs,
|  | struct ast_frame * | f |
| ) |  |  |

Writes a frame to a stream

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

References AST_FORMAT_MAX_AUDIO, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_DEBUG, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.

Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

    00201 {
    00202    struct ast_frame *trf;
    00203    int res = -1;
    00204    int alt=0;
    00205    if (f->frametype == AST_FRAME_VIDEO) {
    00206       if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) {
    00207          /* This is the audio portion.  Call the video one... */
    00208          if (!fs->vfs && fs->filename) {
    00209             /* XXX Support other video formats XXX */
    00210             const char *type = "h263";
    00211             fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
    00212             ast_log(LOG_DEBUG, "Opened video output file\n");
    00213          }
    00214          if (fs->vfs)
    00215             return ast_writestream(fs->vfs, f);
    00216          /* Ignore */
    00217          return 0;
    00218       } else {
    00219          /* Might / might not have mark set */
    00220          alt = 1;
    00221       }
    00222    } else if (f->frametype != AST_FRAME_VOICE) {
    00223       ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
    00224       return -1;
    00225    }
    00226    if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
    00227       res =  fs->fmt->write(fs, f);
    00228       if (res < 0)
    00229          ast_log(LOG_WARNING, "Natural write failed\n");
    00230       if (res > 0)
    00231          ast_log(LOG_WARNING, "Huh??\n");
    00232       return res;
    00233    } else {
    00234       /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
    00235              the one we've setup a translator for, we do the "wrong thing" XXX */
    00236       if (fs->trans && (f->subclass != fs->lastwriteformat)) {
    00237          ast_translator_free_path(fs->trans);
    00238          fs->trans = NULL;
    00239       }
    00240       if (!fs->trans)
    00241          fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
    00242       if (!fs->trans)
    00243          ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", fs->fmt->name, ast_getformatname(f->subclass));
    00244       else {
    00245          fs->lastwriteformat = f->subclass;
    00246          res = 0;
    00247          /* Get the translated frame but don't consume the original in case they're using it on another stream */
    00248          trf = ast_translate(fs->trans, f, 0);
    00249          if (trf) {
    00250             res = fs->fmt->write(fs, trf);
    00251             if (res)
    00252                ast_log(LOG_WARNING, "Translated frame write failed\n");
    00253          } else
    00254             res = 0;
    00255       }
    00256       return res;
    00257    }
    00258 }