file.h File Reference

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

Include dependency graph for file.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define AST_DIGIT_ANY   "0123456789#*"
 Convenient for waiting.
#define SEEK_FORCECUR   10
#define AST_RESERVED_POINTERS   20

Functions

int ast_format_register (char *name, char *exts, int format, struct ast_filestream *(*open)(int fd), struct ast_filestream *(*rewrite)(int fd, 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 *))
 Registers a new file format.
int ast_format_unregister (char *name)
 Unregisters a file format.
int ast_streamfile (struct ast_channel *c, char *filename, char *preflang)
 Streams a file.
int ast_stopstream (struct ast_channel *c)
 Stops a stream.
int ast_fileexists (char *filename, char *fmt, char *preflang)
 Checks for the existence of a given file.
int ast_filerename (char *oldname, char *newname, char *fmt)
 Renames a file.
int ast_filedelete (char *filename, char *fmt)
 Deletes a file.
int ast_filecopy (char *oldname, char *newname, char *fmt)
 Copies a file.
int ast_waitstream (struct ast_channel *c, char *breakon)
 Waits for a stream to stop or digit to be pressed.
int ast_waitstream_fr (struct ast_channel *c, char *breakon, char *forward, char *rewind, int ms)
 Same as waitstream but allows stream to be forwarded or rewound.
int ast_waitstream_full (struct ast_channel *c, char *breakon, int audiofd, int monfd)
struct ast_filestreamast_readfile (char *filename, char *type, char *comment, int flags, int check, mode_t mode)
 Starts reading from a file.
struct ast_filestreamast_writefile (char *filename, char *type, char *comment, int flags, int check, mode_t mode)
 Starts writing a file.
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream.
int ast_closestream (struct ast_filestream *f)
 Closes a stream.
struct ast_filestreamast_openstream (struct ast_channel *chan, char *filename, char *preflang)
 Opens stream for use in seeking, playing.
struct ast_filestreamast_openvstream (struct ast_channel *chan, char *filename, char *preflang)
 Opens stream for use in seeking, playing.
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applys a open stream to a channel.
int ast_playstream (struct ast_filestream *s)
 play a open stream on a channel.
int ast_seekstream (struct ast_filestream *fs, long sample_offset, int whence)
 Seeks into stream.
int ast_truncstream (struct ast_filestream *fs)
 Trunc stream at current location.
int ast_stream_fastforward (struct ast_filestream *fs, long ms)
 Fast forward stream ms.
int ast_stream_rewind (struct ast_filestream *fs, long ms)
 Rewind stream ms.
long ast_tellstream (struct ast_filestream *fs)
 Tell where we are in a stream.
struct ast_frameast_readframe (struct ast_filestream *s)
 Read a frame from a filestream.
int ast_file_init (void)
 Initialize file stuff.


Define Documentation

#define AST_DIGIT_ANY   "0123456789#*"

Convenient for waiting.

Definition at line 28 of file file.h.

#define AST_RESERVED_POINTERS   20

Definition at line 295 of file file.h.

#define SEEK_FORCECUR   10

Definition at line 30 of file file.h.


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
ast_filestream s to apply Returns 0 for success, -1 on failure

Definition at line 607 of file file.c.

00608 {
00609    s->owner = chan;
00610    return 0;
00611 }

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

00653 {
00654    char *cmd = NULL;
00655    size_t size = 0;
00656    /* Stop a running stream if there is one */
00657    if (f->owner) {
00658       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
00659          f->owner->stream = NULL;
00660          if (f->owner->streamid > -1)
00661             ast_sched_del(f->owner->sched, f->owner->streamid);
00662          f->owner->streamid = -1;
00663 #ifdef ZAPTEL_OPTIMIZATIONS
00664          ast_settimeout(f->owner, 0, NULL, NULL);
00665 #endif         
00666       } else {
00667          f->owner->vstream = NULL;
00668          if (f->owner->vstreamid > -1)
00669             ast_sched_del(f->owner->sched, f->owner->vstreamid);
00670          f->owner->vstreamid = -1;
00671       }
00672    }
00673    /* destroy the translator on exit */
00674    if (f->trans) {
00675       ast_translator_free_path(f->trans);
00676       f->trans = NULL;
00677    }
00678 
00679    if (f->realfilename && f->filename) {
00680          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00681          cmd = alloca(size);
00682          memset(cmd,0,size);
00683          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00684          ast_safe_system(cmd);
00685    }
00686 
00687    if (f->filename) {
00688       free(f->filename);
00689       f->filename = NULL;
00690    }
00691    if (f->realfilename) {
00692       free(f->realfilename);
00693       f->realfilename = NULL;
00694    }
00695    f->fmt->close(f);
00696    return 0;
00697 }

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

01166 {
01167    ast_cli_register(&show_file);
01168    return 0;
01169 }

int ast_filecopy ( char *  oldname,
char *  newname,
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 758 of file file.c.

00759 {
00760    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00761 }

int ast_filedelete ( char *  filename,
char *  fmt 
)

Deletes a file.

Parameters:
filename name of the file you wish to delete (minus the extension)
format of the file Delete a given file in a given format, or if fmt is NULL, then do so for all

Definition at line 748 of file file.c.

00749 {
00750    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00751 }

int ast_fileexists ( char *  filename,
char *  fmt,
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 700 of file file.c.

00701 {
00702    char filename2[256];
00703    char tmp[256];
00704    char *postfix;
00705    char *prefix;
00706    char *c;
00707    char lang2[MAX_LANGUAGE];
00708    int res = -1;
00709    if (preflang && !ast_strlen_zero(preflang)) {
00710       /* Insert the language between the last two parts of the path */
00711       strncpy(tmp, filename, sizeof(tmp) - 1);
00712       c = strrchr(tmp, '/');
00713       if (c) {
00714          *c = '\0';
00715          postfix = c+1;
00716          prefix = tmp;
00717          snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix);
00718       } else {
00719          postfix = tmp;
00720          prefix="";
00721          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, postfix);
00722       }
00723       res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
00724       if (res < 1) {
00725          char *stringp=NULL;
00726          strncpy(lang2, preflang, sizeof(lang2)-1);
00727          stringp=lang2;
00728          strsep(&stringp, "_");
00729          /* If language is a specific locality of a language (like es_MX), strip the locality and try again */
00730          if (strcmp(lang2, preflang)) {
00731             if (ast_strlen_zero(prefix)) {
00732                snprintf(filename2, sizeof(filename2), "%s/%s", lang2, postfix);
00733             } else {
00734                snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix);
00735             }
00736             res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
00737          }
00738       }
00739    }
00740 
00741    /* Fallback to no language (usually winds up being American English) */
00742    if (res < 1) {
00743       res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS);
00744    }
00745    return res;
00746 }

int ast_filerename ( char *  oldname,
char *  newname,
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 753 of file file.c.

00754 {
00755    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00756 }

int ast_format_register ( char *  name,
char *  exts,
int  format,
struct ast_filestream *(*)(int fd)  open,
struct ast_filestream *(*)(int fd, 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 ( 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 141 of file file.c.

00142 {
00143    struct ast_format *tmp, *tmpl = NULL;
00144    if (ast_mutex_lock(&formatlock)) {
00145       ast_log(LOG_WARNING, "Unable to lock format list\n");
00146       return -1;
00147    }
00148    tmp = formats;
00149    while(tmp) {
00150       if (!strcasecmp(name, tmp->name)) {
00151          if (tmpl) 
00152             tmpl->next = tmp->next;
00153          else
00154             formats = tmp->next;
00155          free(tmp);
00156          ast_mutex_unlock(&formatlock);
00157          if (option_verbose > 1)
00158             ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
00159          return 0;
00160       }
00161       tmpl = tmp;
00162       tmp = tmp->next;
00163    }
00164    ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00165    return -1;
00166 }

struct ast_filestream* ast_openstream ( struct ast_channel chan,
char *  filename,
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 435 of file file.c.

00436 {
00437    /* This is a fairly complex routine.  Essentially we should do 
00438       the following:
00439       
00440       1) Find which file handlers produce our type of format.
00441       2) Look for a filename which it can handle.
00442       3) If we find one, then great.  
00443       4) If not, see what files are there
00444       5) See what we can actually support
00445       6) Choose the one with the least costly translator path and
00446           set it up.
00447          
00448    */
00449    int fd = -1;
00450    int fmts = -1;
00451    char filename2[256]="";
00452    char filename3[256]="";
00453    char *endpart;
00454    int res;
00455    ast_stopstream(chan);
00456    /* do this first, otherwise we detect the wrong writeformat */
00457    if (chan->generator)
00458       ast_deactivate_generator(chan);
00459    if (preflang && !ast_strlen_zero(preflang)) {
00460       strncpy(filename3, filename, sizeof(filename3) - 1);
00461       endpart = strrchr(filename3, '/');
00462       if (endpart) {
00463          *endpart = '\0';
00464          endpart++;
00465          snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart);
00466       } else
00467          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
00468       fmts = ast_fileexists(filename2, NULL, NULL);
00469    }
00470    if (fmts < 1) {
00471       strncpy(filename2, filename, sizeof(filename2)-1);
00472       fmts = ast_fileexists(filename2, NULL, NULL);
00473    }
00474    if (fmts < 1) {
00475       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00476       return NULL;
00477    }
00478    chan->oldwriteformat = chan->writeformat;
00479    /* Set the channel to a format we can work with */
00480    res = ast_set_write_format(chan, fmts);
00481    
00482    fd = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN);
00483    if (fd >= 0)
00484       return chan->stream;
00485    return NULL;
00486 }

struct ast_filestream* ast_openvstream ( struct ast_channel chan,
char *  filename,
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 488 of file file.c.

00489 {
00490    /* This is a fairly complex routine.  Essentially we should do 
00491       the following:
00492       
00493       1) Find which file handlers produce our type of format.
00494       2) Look for a filename which it can handle.
00495       3) If we find one, then great.  
00496       4) If not, see what files are there
00497       5) See what we can actually support
00498       6) Choose the one with the least costly translator path and
00499           set it up.
00500          
00501    */
00502    int fd = -1;
00503    int fmts = -1;
00504    char filename2[256];
00505    char lang2[MAX_LANGUAGE];
00506    /* XXX H.263 only XXX */
00507    char *fmt = "h263";
00508    if (preflang && !ast_strlen_zero(preflang)) {
00509       snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
00510       fmts = ast_fileexists(filename2, fmt, NULL);
00511       if (fmts < 1) {
00512          strncpy(lang2, preflang, sizeof(lang2)-1);
00513          snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename);
00514          fmts = ast_fileexists(filename2, fmt, NULL);
00515       }
00516    }
00517    if (fmts < 1) {
00518       strncpy(filename2, filename, sizeof(filename2)-1);
00519       fmts = ast_fileexists(filename2, fmt, NULL);
00520    }
00521    if (fmts < 1) {
00522       return NULL;
00523    }
00524    fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN);
00525    if (fd >= 0)
00526       return chan->vstream;
00527    ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00528    return NULL;
00529 }

int ast_playstream ( struct ast_filestream s  ) 

play a open stream on a channel.

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

Definition at line 613 of file file.c.

00614 {
00615    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00616       ast_readaudio_callback(s);
00617    else
00618       ast_readvideo_callback(s);
00619    return 0;
00620 }

struct ast_filestream* ast_readfile ( char *  filename,
char *  type,
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 791 of file file.c.

00792 {
00793    int fd,myflags = 0;
00794    struct ast_format *f;
00795    struct ast_filestream *fs=NULL;
00796    char *fn;
00797    char *ext;
00798    if (ast_mutex_lock(&formatlock)) {
00799       ast_log(LOG_WARNING, "Unable to lock format list\n");
00800       return NULL;
00801    }
00802    f = formats;
00803    while(f) {
00804       if (exts_compare(f->exts, type)) {
00805          char *stringp=NULL;
00806          /* XXX Implement check XXX */
00807          ext = strdup(f->exts);
00808          stringp=ext;
00809          ext = strsep(&stringp, "|");
00810          fn = build_filename(filename, ext);
00811          fd = open(fn, flags | myflags);
00812          if (fd >= 0) {
00813             errno = 0;
00814             if ((fs = f->open(fd))) {
00815                fs->trans = NULL;
00816                fs->fmt = f;
00817                fs->flags = flags;
00818                fs->mode = mode;
00819                fs->filename = strdup(filename);
00820                fs->vfs = NULL;
00821             } else {
00822                ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00823                close(fd);
00824                unlink(fn);
00825             }
00826          } else if (errno != EEXIST)
00827             ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
00828          free(fn);
00829          free(ext);
00830          break;
00831       }
00832       f = f->next;
00833    }
00834    ast_mutex_unlock(&formatlock);
00835    if (!f) 
00836       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00837    return fs;
00838 }

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

Read a frame from a filestream.

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

Definition at line 531 of file file.c.

00532 {
00533    struct ast_frame *f = NULL;
00534    int whennext = 0; 
00535    if (s && s->fmt)
00536       f = s->fmt->read(s, &whennext);
00537    return f;
00538 }

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

Seeks into stream.

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

00623 {
00624    return fs->fmt->seek(fs, sample_offset, whence);
00625 }

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

00169 {
00170    /* Stop a running stream if there is one */
00171    if (tmp->vstream)
00172       ast_closestream(tmp->vstream);
00173    if (tmp->stream) {
00174       ast_closestream(tmp->stream);
00175       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00176          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00177    }
00178    return 0;
00179 }

int ast_stream_fastforward ( struct ast_filestream fs,
long  ms 
)

Fast forward stream ms.

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

Definition at line 637 of file file.c.

00638 {
00639    /* I think this is right, 8000 samples per second, 1000 ms a second so 8
00640     * samples per ms  */
00641    long samples = ms * 8;
00642    return ast_seekstream(fs, samples, SEEK_CUR);
00643 }

int ast_stream_rewind ( struct ast_filestream fs,
long  ms 
)

Rewind stream ms.

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

Definition at line 645 of file file.c.

00646 {
00647    long samples = ms * 8;
00648    samples = samples * -1;
00649    return ast_seekstream(fs, samples, SEEK_CUR);
00650 }

int ast_streamfile ( struct ast_channel c,
char *  filename,
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 763 of file file.c.

00764 {
00765    struct ast_filestream *fs;
00766    struct ast_filestream *vfs;
00767 
00768    fs = ast_openstream(chan, filename, preflang);
00769    vfs = ast_openvstream(chan, filename, preflang);
00770    if (vfs)
00771       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00772    if (fs){
00773       if (ast_applystream(chan, fs))
00774          return -1;
00775       if (vfs && ast_applystream(chan, vfs))
00776          return -1;
00777       if (ast_playstream(fs))
00778          return -1;
00779       if (vfs && ast_playstream(vfs))
00780          return -1;
00781 #if 1
00782       if (option_verbose > 2)
00783          ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default");
00784 #endif
00785       return 0;
00786    }
00787    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno));
00788    return -1;
00789 }

long ast_tellstream ( struct ast_filestream fs  ) 

Tell where we are in a stream.

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

Definition at line 632 of file file.c.

00633 {
00634    return fs->fmt->tell(fs);
00635 }

int ast_truncstream ( struct ast_filestream fs  ) 

Trunc stream at current location.

Parameters:
ast_filestream fs Returns 0 for success, or -1 for error

Definition at line 627 of file file.c.

00628 {
00629    return fs->fmt->trunc(fs);
00630 }

int ast_waitstream ( struct ast_channel c,
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 935 of file file.c.

00936 {
00937    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
00938    int res;
00939    struct ast_frame *fr;
00940    if (!breakon) breakon = "";
00941    while(c->stream) {
00942       res = ast_sched_wait(c->sched);
00943       if ((res < 0) && !c->timingfunc) {
00944          ast_stopstream(c);
00945          break;
00946       }
00947       if (res < 0)
00948          res = 1000;
00949       res = ast_waitfor(c, res);
00950       if (res < 0) {
00951          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
00952          return res;
00953       } else if (res > 0) {
00954          fr = ast_read(c);
00955          if (!fr) {
00956 #if 0
00957             ast_log(LOG_DEBUG, "Got hung up\n");
00958 #endif
00959             return -1;
00960          }
00961          
00962          switch(fr->frametype) {
00963          case AST_FRAME_DTMF:
00964             res = fr->subclass;
00965             if (strchr(breakon, res)) {
00966                ast_frfree(fr);
00967                return res;
00968             }
00969             break;
00970          case AST_FRAME_CONTROL:
00971             switch(fr->subclass) {
00972             case AST_CONTROL_HANGUP:
00973                ast_frfree(fr);
00974                return -1;
00975             case AST_CONTROL_RINGING:
00976             case AST_CONTROL_ANSWER:
00977                /* Unimportant */
00978                break;
00979             default:
00980                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
00981             }
00982          }
00983          /* Ignore */
00984          ast_frfree(fr);
00985       }
00986       ast_sched_runq(c->sched);
00987    }
00988    return (c->_softhangup ? -1 : 0);
00989 }

int ast_waitstream_fr ( struct ast_channel c,
char *  breakon,
char *  forward,
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 991 of file file.c.

00992 {
00993    int res;
00994    struct ast_frame *fr;
00995 
00996    if (!breakon)
00997          breakon = "";
00998    if (!forward)
00999          forward = "";
01000    if (!rewind)
01001          rewind = "";
01002    
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
01016       if (res > 0) {
01017          fr = ast_read(c);
01018          if (!fr) {
01019 #if 0
01020             ast_log(LOG_DEBUG, "Got hung up\n");
01021 #endif
01022             return -1;
01023          }
01024          
01025          switch(fr->frametype) {
01026          case AST_FRAME_DTMF:
01027             res = fr->subclass;
01028             if (strchr(forward,res)) {
01029                ast_stream_fastforward(c->stream, ms);
01030             } else if (strchr(rewind,res)) {
01031                ast_stream_rewind(c->stream, ms);
01032             } else if (strchr(breakon, res)) {
01033                ast_frfree(fr);
01034                return res;
01035             }              
01036             break;
01037          case AST_FRAME_CONTROL:
01038             switch(fr->subclass) {
01039             case AST_CONTROL_HANGUP:
01040                ast_frfree(fr);
01041                return -1;
01042             case AST_CONTROL_RINGING:
01043             case AST_CONTROL_ANSWER:
01044                /* Unimportant */
01045                break;
01046             default:
01047                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01048             }
01049          }
01050          /* Ignore */
01051          ast_frfree(fr);
01052       } else
01053          ast_sched_runq(c->sched);
01054    
01055       
01056    }
01057    return (c->_softhangup ? -1 : 0);
01058 }

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

Definition at line 1060 of file file.c.

01061 {
01062    int res;
01063    int ms;
01064    int outfd;
01065    struct ast_frame *fr;
01066    struct ast_channel *rchan;
01067 
01068    if (!breakon)
01069       breakon = "";
01070    
01071    while(c->stream) {
01072       ms = ast_sched_wait(c->sched);
01073       if ((ms < 0) && !c->timingfunc) {
01074          ast_stopstream(c);
01075          break;
01076       }
01077       if (ms < 0)
01078          ms = 1000;
01079       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01080       if (!rchan && (outfd < 0) && (ms)) {
01081          /* Continue */
01082          if (errno == EINTR)
01083             continue;
01084          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01085          return -1;
01086       } else if (outfd > -1) {
01087          /* The FD we were watching has something waiting */
01088          return 1;
01089       } else if (rchan) {
01090          fr = ast_read(c);
01091          if (!fr) {
01092 #if 0
01093             ast_log(LOG_DEBUG, "Got hung up\n");
01094 #endif
01095             return -1;
01096          }
01097          
01098          switch(fr->frametype) {
01099          case AST_FRAME_DTMF:
01100             res = fr->subclass;
01101             if (strchr(breakon, res)) {
01102                ast_frfree(fr);
01103                return res;
01104             }
01105             break;
01106          case AST_FRAME_CONTROL:
01107             switch(fr->subclass) {
01108             case AST_CONTROL_HANGUP:
01109                ast_frfree(fr);
01110                return -1;
01111             case AST_CONTROL_RINGING:
01112             case AST_CONTROL_ANSWER:
01113                /* Unimportant */
01114                break;
01115             default:
01116                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01117             }
01118          case AST_FRAME_VOICE:
01119             /* Write audio if appropriate */
01120             if (audiofd > -1)
01121                write(audiofd, fr->data, fr->datalen);
01122          }
01123          /* Ignore */
01124          ast_frfree(fr);
01125       }
01126       ast_sched_runq(c->sched);
01127    
01128       
01129    }
01130    return (c->_softhangup ? -1 : 0);
01131 }

struct ast_filestream* ast_writefile ( char *  filename,
char *  type,
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
oflags 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 840 of file file.c.

00841 {
00842    int fd,myflags = 0;
00843    struct ast_format *f;
00844    struct ast_filestream *fs=NULL;
00845    char *fn,*orig_fn=NULL;
00846    char *ext;
00847    char *buf=NULL;
00848    size_t size = 0;
00849 
00850    if (ast_mutex_lock(&formatlock)) {
00851       ast_log(LOG_WARNING, "Unable to lock format list\n");
00852       return NULL;
00853    }
00854    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
00855    if (flags & O_APPEND){ 
00856       /* We really can't use O_APPEND as it will break WAV header updates */
00857       flags &= ~O_APPEND;
00858    }else{
00859       myflags = O_TRUNC;
00860    }
00861    
00862    myflags |= O_WRONLY | O_CREAT;
00863 
00864    f = formats;
00865    while(f) {
00866       if (exts_compare(f->exts, type)) {
00867          char *stringp=NULL;
00868          /* XXX Implement check XXX */
00869          ext = ast_strdupa(f->exts);
00870          stringp=ext;
00871          ext = strsep(&stringp, "|");
00872          fn = build_filename(filename, ext);
00873          fd = open(fn, flags | myflags, mode);
00874 
00875          if (option_cache_record_files && fd >= 0) {
00876             close(fd);
00877             /*
00878                We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
00879                What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
00880             */
00881             orig_fn = ast_strdupa(fn); 
00882             for (size=0;size<strlen(fn);size++) {
00883                if (fn[size] == '/')
00884                   fn[size] = '_';
00885             }
00886 
00887             size += (strlen(record_cache_dir) + 10);
00888             buf = alloca(size);
00889             memset(buf, 0, size);
00890             snprintf(buf, size, "%s/%s", record_cache_dir, fn);
00891             free(fn);
00892             fn=buf;
00893             fd = open(fn, flags | myflags, mode);
00894          }
00895          if (fd >= 0) {
00896             errno = 0;
00897             if ((fs = f->rewrite(fd, comment))) {
00898                fs->trans = NULL;
00899                fs->fmt = f;
00900                fs->flags = flags;
00901                fs->mode = mode;
00902                if (option_cache_record_files) {
00903                   fs->realfilename = build_filename(filename, ext);
00904                   fs->filename = strdup(fn);
00905                } else {
00906                   fs->realfilename = NULL;
00907                   fs->filename = strdup(filename);
00908                }
00909                fs->vfs = NULL;
00910             } else {
00911                ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
00912                close(fd);
00913                unlink(fn);
00914                if (orig_fn)
00915                   unlink(orig_fn);
00916             }
00917          } else if (errno != EEXIST) {
00918             ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
00919             if (orig_fn)
00920                unlink(orig_fn);
00921          }
00922          if (!buf) /* if buf != NULL then fn is already free and pointing to it */
00923             free(fn);
00924 
00925          break;
00926       }
00927       f = f->next;
00928    }
00929    ast_mutex_unlock(&formatlock);
00930    if (!f) 
00931       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00932    return fs;
00933 }

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

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


Generated on Wed Oct 28 17:00:54 2009 for Asterisk by  doxygen 1.5.6