#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. | |
| 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) |
| 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. Referenced by ast_streamfile(). 00608 { 00609 s->owner = chan; 00610 return 0; 00611 }
|
|
|
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(), 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_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 1165 of file file.c. References ast_cli_register(). Referenced by main(). 01166 { 01167 ast_cli_register(&show_file); 01168 return 0; 01169 }
|
|
||||||||||||||||
|
Copies a file.
Definition at line 758 of file file.c. References ACTION_COPY. 00759 { 00760 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00761 }
|
|
||||||||||||
|
Deletes a file.
Definition at line 748 of file file.c. References ACTION_DELETE. Referenced by ast_play_and_prepend(). 00749 { 00750 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00751 }
|
|
||||||||||||||||
|
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 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 }
|
|
||||||||||||||||
|
Renames a file.
Definition at line 753 of file file.c. References ACTION_RENAME. Referenced by ast_play_and_prepend(). 00754 { 00755 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00756 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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(), ast_channel::generator, LOG_WARNING, ast_channel::oldwriteformat, and ast_channel::writeformat. 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(), ast_filestream::fmt, 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, and ast_format::format. 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 791 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, and ast_filestream::vfs. Referenced by ast_play_and_prepend(). 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 }
|
|
|
Read a frame from a filestream.
Definition at line 531 of file file.c. References ast_filestream::fmt, and ast_format::read. 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. References ast_filestream::fmt, and ast_format::seek. 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(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::vstream. 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(), and ast_frame::samples. 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(), and ast_frame::samples. 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 763 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 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(). 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 }
|
|
|
Tell where we are in a stream.
Definition at line 632 of file file.c. References ast_filestream::fmt, and ast_format::tell.
|
|
|
Trunc stream at current location.
Definition at line 627 of file file.c. References ast_filestream::fmt, and ast_format::trunc. 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 935 of file file.c. References ast_channel::_softhangup, AST_CONTROL_ANSWER, 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_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc. 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(). 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 }
|
|
||||||||||||||||||||||||
|
Same as waitstream but allows stream to be forwarded or rewound.
Definition at line 991 of file file.c. References ast_channel::_softhangup, AST_CONTROL_ANSWER, 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(). 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 }
|
|
||||||||||||||||||||
|
Definition at line 1060 of file file.c. References ast_channel::_softhangup, AST_CONTROL_ANSWER, 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(), and ast_say_phonetic_str_full(). 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 }
|
|
||||||||||||||||||||||||||||
|
Starts writing a file.
Definition at line 840 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, and ast_filestream::vfs. Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record(), and ast_writestream(). 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 }
|
|
||||||||||||
|
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::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_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 }
|
1.4.4