#include <asterisk/channel.h>
#include <asterisk/frame.h>
#include <fcntl.h>
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. | |
char | ast_waitstream (struct ast_channel *c, char *breakon) |
Waits for a stream to stop or digit to be pressed. | |
char | 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. | |
char | ast_waitstream_full (struct ast_channel *c, char *breakon, int audiofd, int monfd) |
ast_filestream * | ast_readfile (char *filename, char *type, char *comment, int flags, int check, mode_t mode) |
Starts reading from a file. | |
ast_filestream * | ast_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. | |
ast_filestream * | ast_openstream (struct ast_channel *chan, char *filename, char *preflang) |
Opens stream for use in seeking, playing. | |
ast_filestream * | ast_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. | |
ast_frame * | ast_readframe (struct ast_filestream *s) |
Read a frame from a filestream. | |
int | ast_file_init (void) |
Initialize file stuff. |
|
Convenient for waiting.
Definition at line 28 of file file.h. Referenced by ast_play_and_wait(), ast_readstring(), and ast_readstring_full(). |
|
|
|
Definition at line 30 of file file.h. Referenced by ast_read(), and ast_write(). |
|
Applys a open stream to a channel.
Definition at line 607 of file file.c. References ast_filestream::owner, and s. Referenced by ast_streamfile().
|
|
Closes a stream.
Definition at line 652 of file file.c. References AST_FORMAT_MAX_AUDIO, ast_safe_system(), ast_sched_del(), ast_settimeout(), ast_translator_free_path(), free, ast_filestream::owner, ast_channel::stream, ast_channel::streamid, ast_channel::vstream, and ast_channel::vstreamid. Referenced by ast_app_getvoice(), ast_hangup(), ast_play_and_prepend(), ast_play_and_record(), and ast_stopstream(). 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 }
|
|
Initialize file stuff. Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time Definition at line 1154 of file file.c. References ast_cli_register(), and show_file. Referenced by main(). 01155 { 01156 ast_cli_register(&show_file); 01157 return 0; 01158 }
|
|
Copies a file.
Definition at line 750 of file file.c. References ACTION_COPY. 00751 {
00752 return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00753 }
|
|
Deletes a file.
Definition at line 740 of file file.c. References ACTION_DELETE. Referenced by ast_play_and_prepend(). 00741 {
00742 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00743 }
|
|
Checks for the existence of a given file.
Definition at line 700 of file file.c. References ACTION_EXISTS, and MAX_LANGUAGE. Referenced by ast_openstream(), and ast_openvstream(). 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 } else { 00718 postfix = tmp; 00719 prefix=""; 00720 } 00721 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix); 00722 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00723 if (res < 1) { 00724 char *stringp=NULL; 00725 strncpy(lang2, preflang, sizeof(lang2)-1); 00726 stringp=lang2; 00727 strsep(&stringp, "_"); 00728 if (strcmp(lang2, preflang)) { 00729 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix); 00730 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00731 } 00732 } 00733 } 00734 if (res < 1) { 00735 res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); 00736 } 00737 return res; 00738 }
|
|
Renames a file.
Definition at line 745 of file file.c. References ACTION_RENAME. Referenced by ast_play_and_prepend(). 00746 {
00747 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00748 }
|
|
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 |
|
Unregisters a file format.
Definition at line 141 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. 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 }
|
|
Opens stream for use in seeking, playing.
Definition at line 435 of file file.c. References ACTION_OPEN, ast_deactivate_generator(), ast_fileexists(), ast_log(), ast_set_write_format(), ast_stopstream(), and LOG_WARNING. Referenced by ast_streamfile(). 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 }
|
|
Opens stream for use in seeking, playing.
Definition at line 488 of file file.c. References ACTION_OPEN, ast_fileexists(), ast_log(), LOG_WARNING, and MAX_LANGUAGE. Referenced by ast_streamfile(). 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 }
|
|
play a open stream on a channel.
Definition at line 613 of file file.c. References AST_FORMAT_MAX_AUDIO, ast_filestream::fmt, ast_format::format, and s. Referenced by ast_streamfile(). 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 }
|
|
Starts reading from a file.
Definition at line 783 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_format::exts, 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, type, and ast_filestream::vfs. Referenced by ast_play_and_prepend(). 00784 { 00785 int fd,myflags = 0; 00786 struct ast_format *f; 00787 struct ast_filestream *fs=NULL; 00788 char *fn; 00789 char *ext; 00790 if (ast_mutex_lock(&formatlock)) { 00791 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00792 return NULL; 00793 } 00794 f = formats; 00795 while(f) { 00796 if (exts_compare(f->exts, type)) { 00797 char *stringp=NULL; 00798 /* XXX Implement check XXX */ 00799 ext = strdup(f->exts); 00800 stringp=ext; 00801 ext = strsep(&stringp, "|"); 00802 fn = build_filename(filename, ext); 00803 fd = open(fn, flags | myflags); 00804 if (fd >= 0) { 00805 errno = 0; 00806 if ((fs = f->open(fd))) { 00807 fs->trans = NULL; 00808 fs->fmt = f; 00809 fs->flags = flags; 00810 fs->mode = mode; 00811 fs->filename = strdup(filename); 00812 fs->vfs = NULL; 00813 } else { 00814 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00815 close(fd); 00816 unlink(fn); 00817 } 00818 } else if (errno != EEXIST) 00819 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00820 free(fn); 00821 free(ext); 00822 break; 00823 } 00824 f = f->next; 00825 } 00826 ast_mutex_unlock(&formatlock); 00827 if (!f) 00828 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00829 return fs; 00830 }
|
|
Read a frame from a filestream.
Definition at line 531 of file file.c. References s. Referenced by ast_play_and_prepend(). 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 }
|
|
Seeks into stream.
Definition at line 622 of file file.c. Referenced by ast_control_streamfile(), ast_read(), ast_stream_fastforward(), ast_stream_rewind(), and ast_write().
|
|
Stops a stream.
Definition at line 168 of file file.c. References ast_closestream(), ast_log(), ast_set_write_format(), and LOG_WARNING. Referenced by ast_control_streamfile(), ast_openstream(), ast_play_and_wait(), ast_readstring(), ast_readstring_full(), ast_say_character_str(), ast_say_character_str_full(), ast_say_digit_str(), ast_say_digit_str_full(), ast_say_phonetic_str(), ast_say_phonetic_str_full(), ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full(). 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 }
|
|
Fast forward stream ms.
Definition at line 637 of file file.c. References ast_seekstream(). Referenced by ast_control_streamfile(), and ast_waitstream_fr(). 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 }
|
|
Rewind stream ms.
Definition at line 645 of file file.c. References ast_seekstream(). Referenced by ast_play_and_prepend(), ast_play_and_record(), and ast_waitstream_fr(). 00646 { 00647 long samples = ms * 8; 00648 samples = samples * -1; 00649 return ast_seekstream(fs, samples, SEEK_CUR); 00650 }
|
|
Streams a file.
Definition at line 755 of file file.c. References ast_applystream(), ast_getformatname(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_verbose(), LOG_DEBUG, LOG_WARNING, option_verbose, and VERBOSE_PREFIX_3. Referenced by ast_app_getdata(), ast_app_getdata_full(), ast_app_getvoice(), ast_control_streamfile(), ast_play_and_prepend(), ast_play_and_record(), ast_play_and_wait(), ast_say_character_str(), ast_say_character_str_full(), ast_say_digit_str(), ast_say_digit_str_full(), ast_say_phonetic_str(), and ast_say_phonetic_str_full(). 00756 { 00757 struct ast_filestream *fs; 00758 struct ast_filestream *vfs; 00759 00760 fs = ast_openstream(chan, filename, preflang); 00761 vfs = ast_openvstream(chan, filename, preflang); 00762 if (vfs) 00763 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00764 if (fs){ 00765 if (ast_applystream(chan, fs)) 00766 return -1; 00767 if (vfs && ast_applystream(chan, vfs)) 00768 return -1; 00769 if (ast_playstream(fs)) 00770 return -1; 00771 if (vfs && ast_playstream(vfs)) 00772 return -1; 00773 #if 1 00774 if (option_verbose > 2) 00775 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default"); 00776 #endif 00777 return 0; 00778 } 00779 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno)); 00780 return -1; 00781 }
|
|
Tell where we are in a stream.
Definition at line 632 of file file.c.
|
|
Trunc stream at current location.
Definition at line 627 of file file.c. Referenced by ast_play_and_prepend(), and ast_play_and_record().
|
|
Waits for a stream to stop or digit to be pressed.
Definition at line 927 of file file.c. References ast_frfree(), ast_log(), ast_read(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, and ast_frame::subclass. Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record(), ast_play_and_wait(), ast_readstring(), ast_say_character_str(), ast_say_digit_str(), and ast_say_phonetic_str(). 00928 { 00929 /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */ 00930 int res; 00931 struct ast_frame *fr; 00932 if (!breakon) breakon = ""; 00933 while(c->stream) { 00934 res = ast_sched_wait(c->sched); 00935 if ((res < 0) && !c->timingfunc) { 00936 ast_stopstream(c); 00937 break; 00938 } 00939 if (res < 0) 00940 res = 1000; 00941 res = ast_waitfor(c, res); 00942 if (res < 0) { 00943 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 00944 return res; 00945 } else if (res > 0) { 00946 fr = ast_read(c); 00947 if (!fr) { 00948 #if 0 00949 ast_log(LOG_DEBUG, "Got hung up\n"); 00950 #endif 00951 return -1; 00952 } 00953 00954 switch(fr->frametype) { 00955 case AST_FRAME_DTMF: 00956 res = fr->subclass; 00957 if (strchr(breakon, res)) { 00958 ast_frfree(fr); 00959 return res; 00960 } 00961 break; 00962 case AST_FRAME_CONTROL: 00963 switch(fr->subclass) { 00964 case AST_CONTROL_HANGUP: 00965 ast_frfree(fr); 00966 return -1; 00967 case AST_CONTROL_RINGING: 00968 case AST_CONTROL_ANSWER: 00969 /* Unimportant */ 00970 break; 00971 default: 00972 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 00973 } 00974 } 00975 /* Ignore */ 00976 ast_frfree(fr); 00977 } 00978 ast_sched_runq(c->sched); 00979 } 00980 return (c->_softhangup ? -1 : 0); 00981 }
|
|
Same as waitstream but allows stream to be forwarded or rewound.
Definition at line 983 of file file.c. References ast_log(), ast_read(), ast_sched_wait(), ast_stopstream(), ast_stream_fastforward(), ast_stream_rewind(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, and ast_frame::subclass. Referenced by ast_control_streamfile(). 00984 { 00985 int res; 00986 struct ast_frame *fr; 00987 00988 if (!breakon) 00989 breakon = ""; 00990 if (!forward) 00991 forward = ""; 00992 if (!rewind) 00993 rewind = ""; 00994 00995 while(c->stream) { 00996 res = ast_sched_wait(c->sched); 00997 if ((res < 0) && !c->timingfunc) { 00998 ast_stopstream(c); 00999 break; 01000 } 01001 if (res < 0) 01002 res = 1000; 01003 res = ast_waitfor(c, res); 01004 if (res < 0) { 01005 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01006 return res; 01007 } else 01008 if (res > 0) { 01009 fr = ast_read(c); 01010 if (!fr) { 01011 #if 0 01012 ast_log(LOG_DEBUG, "Got hung up\n"); 01013 #endif 01014 return -1; 01015 } 01016 01017 switch(fr->frametype) { 01018 case AST_FRAME_DTMF: 01019 res = fr->subclass; 01020 if (strchr(forward,res)) { 01021 ast_stream_fastforward(c->stream, ms); 01022 } else if (strchr(rewind,res)) { 01023 ast_stream_rewind(c->stream, ms); 01024 } else if (strchr(breakon, res)) { 01025 ast_frfree(fr); 01026 return res; 01027 } 01028 break; 01029 case AST_FRAME_CONTROL: 01030 switch(fr->subclass) { 01031 case AST_CONTROL_HANGUP: 01032 ast_frfree(fr); 01033 return -1; 01034 case AST_CONTROL_RINGING: 01035 case AST_CONTROL_ANSWER: 01036 /* Unimportant */ 01037 break; 01038 default: 01039 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01040 } 01041 } 01042 /* Ignore */ 01043 ast_frfree(fr); 01044 } else 01045 ast_sched_runq(c->sched); 01046 01047 01048 } 01049 return (c->_softhangup ? -1 : 0); 01050 }
|
|
Definition at line 1052 of file file.c. References AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_sched_wait(), ast_stopstream(), ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, and ast_frame::subclass. Referenced by ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_full(), and ast_say_phonetic_str_full(). 01053 { 01054 int res; 01055 int ms; 01056 int outfd; 01057 struct ast_frame *fr; 01058 struct ast_channel *rchan; 01059 01060 if (!breakon) 01061 breakon = ""; 01062 01063 while(c->stream) { 01064 ms = ast_sched_wait(c->sched); 01065 if ((ms < 0) && !c->timingfunc) { 01066 ast_stopstream(c); 01067 break; 01068 } 01069 if (ms < 0) 01070 ms = 1000; 01071 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01072 if (!rchan && (outfd < 0) && (ms)) { 01073 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01074 return -1; 01075 } else if (outfd > -1) { 01076 /* The FD we were watching has something waiting */ 01077 return 1; 01078 } else if (rchan) { 01079 fr = ast_read(c); 01080 if (!fr) { 01081 #if 0 01082 ast_log(LOG_DEBUG, "Got hung up\n"); 01083 #endif 01084 return -1; 01085 } 01086 01087 switch(fr->frametype) { 01088 case AST_FRAME_DTMF: 01089 res = fr->subclass; 01090 if (strchr(breakon, res)) { 01091 ast_frfree(fr); 01092 return res; 01093 } 01094 break; 01095 case AST_FRAME_CONTROL: 01096 switch(fr->subclass) { 01097 case AST_CONTROL_HANGUP: 01098 ast_frfree(fr); 01099 return -1; 01100 case AST_CONTROL_RINGING: 01101 case AST_CONTROL_ANSWER: 01102 /* Unimportant */ 01103 break; 01104 default: 01105 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01106 } 01107 case AST_FRAME_VOICE: 01108 /* Write audio if appropriate */ 01109 if (audiofd > -1) 01110 write(audiofd, fr->data, fr->datalen); 01111 } 01112 /* Ignore */ 01113 ast_frfree(fr); 01114 } 01115 ast_sched_runq(c->sched); 01116 01117 01118 } 01119 return (c->_softhangup ? -1 : 0); 01120 }
|
|
Starts writing a file.
Definition at line 832 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_format::exts, 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, strdup, ast_filestream::trans, type, and ast_filestream::vfs. Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record(), and ast_writestream(). 00833 { 00834 int fd,myflags = 0; 00835 struct ast_format *f; 00836 struct ast_filestream *fs=NULL; 00837 char *fn,*orig_fn=NULL; 00838 char *ext; 00839 char *buf=NULL; 00840 size_t size = 0; 00841 00842 if (ast_mutex_lock(&formatlock)) { 00843 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00844 return NULL; 00845 } 00846 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00847 if (flags & O_APPEND){ 00848 /* We really can't use O_APPEND as it will break WAV header updates */ 00849 flags &= ~O_APPEND; 00850 }else{ 00851 myflags = O_TRUNC; 00852 } 00853 00854 myflags |= O_WRONLY | O_CREAT; 00855 00856 f = formats; 00857 while(f) { 00858 if (exts_compare(f->exts, type)) { 00859 char *stringp=NULL; 00860 /* XXX Implement check XXX */ 00861 ext = ast_strdupa(f->exts); 00862 stringp=ext; 00863 ext = strsep(&stringp, "|"); 00864 fn = build_filename(filename, ext); 00865 fd = open(fn, flags | myflags, mode); 00866 00867 if (option_cache_record_files && fd >= 0) { 00868 close(fd); 00869 /* 00870 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 00871 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 00872 */ 00873 orig_fn = ast_strdupa(fn); 00874 for (size=0;size<strlen(fn);size++) { 00875 if (fn[size] == '/') 00876 fn[size] = '_'; 00877 } 00878 00879 size += (strlen(record_cache_dir) + 10); 00880 buf = alloca(size); 00881 memset(buf, 0, size); 00882 snprintf(buf, size, "%s/%s", record_cache_dir, fn); 00883 free(fn); 00884 fn=buf; 00885 fd = open(fn, flags | myflags, mode); 00886 } 00887 if (fd >= 0) { 00888 errno = 0; 00889 if ((fs = f->rewrite(fd, comment))) { 00890 fs->trans = NULL; 00891 fs->fmt = f; 00892 fs->flags = flags; 00893 fs->mode = mode; 00894 if (option_cache_record_files) { 00895 fs->realfilename = build_filename(filename, ext); 00896 fs->filename = strdup(fn); 00897 } else { 00898 fs->realfilename = NULL; 00899 fs->filename = strdup(filename); 00900 } 00901 fs->vfs = NULL; 00902 } else { 00903 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 00904 close(fd); 00905 unlink(fn); 00906 if (orig_fn) 00907 unlink(orig_fn); 00908 } 00909 } else if (errno != EEXIST) { 00910 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00911 if (orig_fn) 00912 unlink(orig_fn); 00913 } 00914 if (!buf) /* if buf != NULL then fn is already free and pointing to it */ 00915 free(fn); 00916 00917 break; 00918 } 00919 f = f->next; 00920 } 00921 ast_mutex_unlock(&formatlock); 00922 if (!f) 00923 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00924 return fs; 00925 }
|
|
Writes a frame to a stream.
Definition at line 181 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::fmt, LOG_DEBUG, LOG_WARNING, type, and ast_format::write. Referenced by ast_play_and_prepend(), ast_play_and_record(), ast_read(), ast_write(), and ast_writestream(). 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 }
|